2

freeRTOS を搭載した CC3200 wifi (TI) lauchpad ボードで複数のタスクを実行するシステムを構築しようとしています。メインに 3 つのタスクを作成しました。

    // Create task1
    osi_TaskCreate( task1, ( signed portCHAR * ) "task1",
            OSI_STACK_SIZE, NULL, 1, NULL );

    //Two more tasks

3 つのタスクはすべて同じ優先度 (1) を持っているため、3 つのタスクすべてが同じ量のプロセッサー時間を取得すると予想されます。

各タスクは、その名前を uart ポートに出力することのみを担当します。

void task1( void *pvParameters )
{
    while(1)
    {
        Report("task1");
    }
}

残念ながら、タスク 1 だけが常にその名前を表示しています。これを修正するにはどうすればよいですか?

4

2 に答える 2

4

私の FreeRTOS の記憶によると、すべてのスレッドを同じ優先度で作成した場合、USE_TIME_SLICING を定義しないか、それを定義して「1」に設定した場合にのみ、希望する均等な共有が得られます。

複数のスレッドがハードウェア リソース (または共有メモリ リソース) へのアクセスをめぐって競合する場合、何らかの方法でアクセスを制御する必要があります。この場合、最も簡単な (ただし最速ではありませんが) オプションは、mutex を使用することです。一般に、mutex とバイナリ セマフォは交換可能です。2 つの詳細については、FreeRTOS のドキュメントを参照してください。問題が解決するはずです。

疑似コードを許すなら、各スレッドが次の行に沿って何かを実行することを望みます

createMutex(UART_Lock)

void task1
{
    while(1)
    {
       if(GetLockOnMutex(UART_Lock))
       {
          PrintToUART();
          ReleaseMutex();
       }
    }
}

void task2
{
    while(1)
    {
       if(GetLockOnMutex(UART_Lock))
       {
          PrintToUART();
          ReleaseMutex();
       }
    }
}

void task3
{
    while(1)
    {
       if(GetLockOnMutex(UART_Lock))
       {
          PrintToUART();
          ReleaseMutex();
       }
    }
}

そのため、各スレッドがコンテキストに持ち込まれると、UART へのアクセスを制限するために使用されているミューテックスをロックしようとします。成功した場合は何かを送信し、印刷機能が返されたとき (複数のタイム スライスにまたがる可能性があります) にのみ、別のスレッドが試行して取得できるように UART のロックを解放します。スレッドがロックを取得できない場合は、タイム スライスがアップするまで再試行します。ロックを取得できなかったスレッドを、次にコンテキストに持ち込まれるまでスリープ状態に戻すことができますが、これは、CPU が非常にビジーで、タスクが実際にスケジュール可能かどうかを考える必要がある場合にのみ重要です。

基本的に、UART へのアクセスを制御せず、スレッドの特定のタイム スライス中にそのスレッドが UART へのアクセスを完了するという保証がない場合、スケジューラは未完了のスレッドをプリエンプトし、他のスレッドがそのスレッドを使用しようとする可能性があります。 UART。

あなたの場合、UARTs送信バッファがそれを整理するかもしれないと仮定するのは論理的ですが、それは非常に大きく、1つのスレッドが完全にいっぱいになるのを止めるものは何もないので、実際にはそれに依存したくありません.

于 2014-11-27T14:47:31.723 に答える
1

サンクス!

これを次のように実装しました。

void vTestTask1( void *pvParameters )
{
    while(1) {
        if(xSemaphoreTake(uart_lock, 1000)) {
            // Use Guarded Resource
            Report("1");
            // Give Semaphore back:
            xSemaphoreGive(uart_lock);
        }
        vTaskDelay(1000);
    }
}
void vTestTask2( void *pvParameters )
{
    while(1) {
        if(xSemaphoreTake(uart_lock, 1000)) {
            // Use Guarded Resource
            Report("2");
            // Give Semaphore back:
            xSemaphoreGive(uart_lock);
        }
        vTaskDelay(1000);
    }
}

uart経由で121212などを印刷しているため、完全に機能しました。

于 2014-11-28T12:54:52.863 に答える