【タスクの状態遷移】
FreeRTOS管理下でのタスクの状態は下図のように変化します。
まずタスクが生成されるといったんレディー状態となります。レディー状態のタスクの中で
最も優先順位が高いものひとつだけが実行中となり実行が開始されます。
タイマ1の割り込みの都度、レディー状態のタスクの中で最も優先順位が高く、
同じ優先順位の中の次の順番のタスクを実行中状態として実行を開始します。
特にタスクの中で待ち合わせなどをしなければ、次のタイマ1の割り込みで、タスクの
切替が行われ、実行中タスクはレディー状態となり、同じ優先順位の中の次の順番の
タスクが実行中となります。
つまり同じ優先順位のタスクは、タイマ1の割り込みの都度順番に実行されることに
なります。これをラウンドロビンと呼びます。
実行中タスクが何らかの待ち合わせ(ブロック)を行うAPI関数を実行すると、
そのタスクはブロック状態となります。そして同じ優先順位で次の順番のタスクか同じ
優先順位が無ければ、下位の優先順位のタスクが実行中となり実行されます。
待ち合わせを解除するAPI関数が実行されるか、待ち合わせているイベントが発生
すると、そのタスクは再度レディー状態となり、次の実行待ちとなります。
実行中タスクでサスペンドするAPI関数が実行されると、そのタスクか指定された
タスクがサスペンド状態(休止状態)となり、再度タスクの優先順位が決定されて
新たなタスクが実行中となります。
サスペンドしたタスクは、レジューム関数が実行されると再びレディー状態に戻り
実行待ちとなります。
【タスクのスケジューリングの方法】
FreeRTOSをPIC24またはdsPICに移植した場合のタスクのスケジューリングは下図のように
行われます。
タスクAが実行中だとし、この間にタイマ1の割り込みが発生したとします。
タイマ1はFreeRTOS専用のインターバルタイマとなっており、この割り込みにより、全体の
時間管理をするTickという単位をカウントアップします。
FreeRTOS内のタイマ1の割り込みハンドラの処理では、Delayなどの時間待ち合わせを
しているタスクのTickもカウントアップし、タイムアップにより、そのタスクをブロック状態から
レディー状態に移行します。最後に「taskYIELD()」という関数を実行します。
taskYIELD()関数の処理は、「portasm_PIC24.S」ファイル内の「_vPortYield」ルーチン内で
行われ、現在実行中のタスクの現在状態をスタックに退避し、そのタスクを実行中から
レディー状態とします。
その後にレディー状態のタスクの優先順位をチェックし、最も優先順位が高いか、同じ優先
レベルで複数のタスクがあれば次の順のタスクを実行中とします。
そしてそのタスクのスタックに保存されている実行継続位置にジャンプし、割り込みレベルも
SRレジスタに復帰させて新たなタスクの実行が開始されます。
タスクの実行中にそのタスクから他のタスクの待ち合わせを行うAPI関数を実行したり、
周辺モジュールの割り込みイベントなどによりAPI関数が実行されると、そのAPI関数の
最後で同じ「taskYIELD()」関数が実行されます。
そのtaskYIELD()関数の処理で再度スケジューリングが行われ、タスクの切替が行われ
ます。
目次に戻る