Previous: 3.6.1. 単純な待ちルーチンの問題点 |
Up: 3.6. タスクの実行頻度 |
Next: 3.6.3. すべてのタスクを周期実行させる |
サンプルプログラム |
freertos_vTaskDelay |
一定時間タスクの実行を中断させるために使用するのがvTaskDelay関数です。Running状態のタスク中でvTaskDelay関数が実行されると、そのタスクは、指定された待ち時間の間、Blocked状態になります。Blocked状態になっている間は、そのタスクは実行されません。結果、より優先度が低いタスクが実行されることになります。Blocked状態のタスクと同じ優先度のタスクがある場合には、実行の順番が回ってきた場合でも、Blocked状態のタスクは飛ばされ、同じ優先度の他のタスクが実行されます。
図 3?2 Ready状態とRunning状態の遷移
サンプルプログラムの実行結果は以下のようになります。
abcABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABC ABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB CABabcCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCAB CABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCA BCABCabcABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCABCA .... |
“abc”を出力するためのTaskaは”ABC”を出力するためのTaskAより優先度が低いのですが、”abc”は所々でしか表示されていません。これはvTaskDelay関数を使用してTaskaをBlocked状態にしているからです。
関数名 |
vTaskDelay関数 |
|
関数プロトタイプ |
void vTaskDelay( portTickType xTicksToDelay ) |
|
動作 |
指定時間分タスクをBlocked状態にして待ちます。 |
|
引数 |
xTicksToDelay |
待ち時間を指定します。指定する数値はTick単位です。 |
戻り値 |
無し。 |
待ち時間で指定するTickとは、FreeRTOSConfig.h内のconfigTICK_RATE_HZで指定した周波数で発生するコンテキストスイッチのタイミング・期間のことです。configTICK_RATE_HZが1000のときは、コンテキストスイッチは1ms毎に発生するのでTickは1msということになります。このとき、xTicksToDelayに500を指定すると、500msの間タスクはBlocked状態になります。configTICK_RATE_HZが2500のときは、Tickは0.4msになり、xTicksToDelayに500を指定すると、200msの間タスクはBlocked状態になります。
サンプルプログラムでは以下のようにしてxTicksToDelayに10を指定しています。configTICK_RATE_HZが1000なので、Taskaは毎回10ms待ちます。Taskaより優先度の高いタスクは登録されていませんから、Taskaはおよそ10ms毎に実行されることになります。
void prvTaska(void *pvParameters) { ? int8_t* pcTaskName; ? pcTaskName = (int8_t *)pvParameters; ? while(1) ??? { ????? cprintf(pcTaskName); ????? vTaskDelay(10); ??? } } |
サンプルプログラムの実行結果では、”abc”の間では”ABC”が113文字表示されており、USARTの送信速度からすると、だいたい計算が合います(115200bps/10bit×(10ms/1000ms)=115.2文字)。
先ほど「Taskaはおよそ10ms毎に実行される」と書きました。xTicksToDelay関数を使って10ms待った場合、待ち時間は10msになりますが、実行周期は10msになるとは限りません。Taskaの場合、xTicksToDelay関数を実行する前にcprintf関数を実行しているので、Taskaの1サイクル分の合計実行時間は10ms+cprintf関数の実行時間となります。つまりTaskaの実行周期は、10msよりも若干長くなるということになります。
実行周期を正確に10msやその他の指定した時間にしたいというときには、後述のvTaskDelayUntil関数を使用します。
Previous: 3.6.1. 単純な待ちルーチンの問題点 |
Up: 3.6. タスクの実行頻度 |
Next: 3.6.3. すべてのタスクを周期実行させる |