Previous: 5.1.3.1. 割込み優先度の設定 |
Up: 5.1.3. バイナリセマフォを与える |
Next: 5.1.4. バイナリセマフォを取る |
次に割込みハンドラの作成です。まず先にサンプルプログラムのコードを見てみましょう。
void TIM4_IRQHandler(void) { ? static portBASE_TYPE xHigherPriorityTaskWoken; ? xHigherPriorityTaskWoken = pdFALSE;
? if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) ??? { ????? // give semaphore to unblock handler task ????? xSemaphoreGiveFromISR( xBinarySemaphore, &xHigherPriorityTaskWoken );
????? // Clear TIM4 update interrupt pending bit ????? TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
????? // context switch : Set PendSV bit ????? portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); ??? } } |
冒頭部分の変数の宣言、代入はとりあえず飛ばして見てみると、割込みフラグをチェックし、そのif構文の中で割込みフラグをクリアしているのがわかると思います。ここはこれまでの割込みハンドラの記述方法と同じです。if構文の中で出てくるxSemaphoreGiveFromISR関数が、セマフォを与えるための関数です。
関数名 |
xSemaphoreGiveFromISR関数 |
|
関数プロトタイプ |
xSemaphoreGiveFromISR ? ( ??? xSemaphoreHandle xSemaphore, ??? portBASE_TYPE *pxHigherPriorityTaskWoken ? ) |
|
動作 |
セマフォを与えます。割込みハンドラから使用できます。 |
|
引数 |
xSemaphore |
与える対象のセマフォのハンドラを指定します。 |
*pxHigherPriorityTaskWoken |
セマフォを与えることにより、割込みハンドラ起動前に実行中であったタスクよりもより優先度が高いタスクが起動することになるのかどうかをこの変数に入れて返します(起動した場合:pdTRUE/起動しなかった場合:pdFALSE)。 |
|
戻り値 |
無し |
サンプルプログラムでは、main関数でセマフォのハンドラとして作成しておいたxBinarySemaphoreを指定しています。割込みハンドラの冒頭で宣言していた変数は、xSemaphoreGiveFromISR関数の引数とするためのものです。 portBASE_TYPE型の変数を宣言しておき、 pdFALSEを代入しておきます。xSemaphoreGiveFromISR関数で引数として指定すると、セマフォを与えることにより優先度の高いタスクが起動すれば、pdTRUEに変化しますから、優先度の高いタスクが起動したことを確認できます。割込みハンドラが起動させるタスクは、割込み処理のためのものですので、通常は優先度を高くしているでしょう。
割込みハンドラの最後では、portEND_SWITCHING_ISRマクロを呼び出します。
マクロ名 |
portEND_SWITCHING_ISRマクロ |
|
マクロプロトタイプ |
portEND_SWITCHING_ISR(xSwitchRequired ) |
|
動作 |
優先度の高いタスクが起動している場合にはコンテキストスイッチを行います。 |
|
引数 |
xSemaphore |
与える対象のセマフォのハンドラを指定します。 |
戻り値 |
無し |
このマクロを実行する理由はOSの実装上の都合のようなものなのですが、割込みハンドラ内でセマフォを与えて優先順位の高いタスクを起動させたとしても、割込みハンドラの処理中はFreeRTOSは停止したまま、つまりコンテキストスイッチの機能が働いていないので、割込みハンドラが終了すると、割込みハンドラ起動前の(優先度の低い)タスクに処理が戻ってしまいます。そこで割込みハンドラを終了させる前に強制的にコンテキストスイッチを発生させ、実行するタスクを、優先度の低いタスクから、優先度の高いタスクに変更させます。こうしておくことにより、割込みハンドラが終了した時点で直ちに優先度が高いタスクの処理が開始されます。
Previous: 5.1.3.1. 割込み優先度の設定 |
Up: 5.1.3. バイナリセマフォを与える |
Next: 5.1.4. バイナリセマフォを取る |