1

この問題について誰か助けてください。VxWorks で同じ重要なリソースを保護するために、2 つの異なるタスクが 2 つの異なるセマフォを作成することは可能ですか?

4

2 に答える 2

1

ここで何かが欠けていると思います。

vxWorks では、すべてのタスクが同じメモリ空間を共有するため、タスク間のグローバル データを Mutex で保護する必要があります。

アイデアは、1 つの Mutex のみを使用することです (その sem_id は、それを使用するすべてのタスクでよく知られています)。

1 つの Mutex を使用してデータを保護できます (同じ Mutex を使用するタスクの数に制限はありません)。


vxWorks の 2 つのタスク間で同じメモリ空間にアクセスしたい場合は、アクセス関数を作成するのが最善の方法です。

int access_func(void)

{

    static SEM_ID sem_id=0;

    if(sem_id == 0)

    {

        /* create mutex semaphore \u2013 semMCreate(\u2026) */

    }

    return_code=semTake(sem_id, time_out);

    if(return_code != 0) return errno;

    /* read or write to or from global memory */

    semGive(sem_id); 

}

ノート:

semMCreate にはいくつかのオプションがあり、semTake にはいくつかのオプションがあります。

システムの init でミューテックスを作成できます (推奨)。

ミューテックスが読み取られず、sem_id がまだゼロの場合、semTake は ERROR を返します (リターン コードとシステム errno を確認できます)。

于 2013-05-22T16:10:24.800 に答える
1

これについては、vxWorks のドキュメントで説明する必要があります。

一般に、セマフォの使用からセマフォの作成を分離する必要があります。

/**Initialization Code**/
SEM_ID semM;
semM = semMCreate (...);
...
taskSpawn(task1...);
taskSpawn(task2...);
...

/* Task 1 code */
void task1() {
    ...
    semTake (semM, WAIT_FOREVER);
    ...<Task 1 critical section>
    semGive (semM);
    ...
}

/* Task 2 code */
void task2() {
    ...
    semTake (semM, WAIT_FOREVER);
    ...< Task 2 critical section>
    semGive (semM);
    ...
}

この場合、 semM は両方のタスクで使用できるグローバル変数です。それが気になる場合は、VxWorks 6.x では、セマフォに名前を付ける semOpen() API を使用することもできます。各タスクで semOpen を実行して、セマフォとその ID を作成/取得します。

ミューテックスが作成されると、semTake を実行する最初のタスク (タスク 1 またはタスク 2) で使用できます。

特定の順序で物事を行う必要がある場合は、ミューテックス (相互排除用) と同期 (たとえば、バイナリ セマフォ経由) の組み合わせが必要です。

上記の例を少し変更して、task1 が何かを行った後にのみ task2 が実行されるようにします。

/**Initialization Code**/
SEM_ID semM;
SEM_ID semSync;
semM = semMCreate (...);
semSync = semBCreate (...);
...

void task1() {
    ...
    /* Access Shared Structure */
    semTake (semM, WAIT_FOREVER);
    ...<Task 1 critical section>
    semGive (semM);
    /* Notify Task 2 that something is available */
    semGive (semSync);
    ...
}
void task2() {
    ...
    /* Wait for Task 1 to let me know there is something to do */
    semTake (semSync, WAIT_FOREVER);

    /* Access Shared Structure */
    semTake (semM, WAIT_FOREVER);
    ...< Task 2 critical section>
    semGive (semM);
    ...
}
于 2013-05-10T15:41:19.793 に答える