Previous: 6.1. クリティカルセクションとは |
Up: 6. クリティカルセクション |
Next: 6.3. スケジューラ停止 |
サンプルプログラム |
freertos_critical_section_disable_interrupt |
割込みは割込みを無効化してしまうと発生しません。またFreeRTOSのコンテキストスイッチはSVC割込みやSystick割込みを利用して発生していますので、割込みを無効化するとやはりコンテキストスイッチは発生しません。そのため割込みを無効化することにより、クリティカルセクションを作成することができます。
もっとも割込みを無効化すると、すべての割込みが停止してしまいますので、本来は優先させないといけない割込みまで無効化させてしまう可能性があるので、注意が必要です。
割込みの無効化は本来はマイコン固有の機能であり、アセンブリ言語を使用して実行するものなのですが、FreeRTOSではプラットフォームを意識せずに利用できるマクロが用意されています。割込みを無効化してクリティカルセクションに入るのがtaskENTER_CRITICALマクロです。
マクロ名 |
taskENTER_CRITICALマクロ |
マクロプロトタイプ |
void taskENTER_CRITICAL (void) |
動作 |
割込みを無効化してクリティカルセクションを開始します。 |
引数 |
無し。 |
戻り値 |
無し。 |
割込みを有効化してクリティカルセクションを終了するのがtaskEXIT_CRITICALマクロです。
マクロ名 |
taskEXIT_CRITICALマクロ |
マクロプロトタイプ |
void taskEXIT_CRITICAL (void) |
動作 |
割込みを有効化してクリティカルセクションを終了します。 |
引数 |
無し。 |
戻り値 |
無し。 |
実際にこれらのマクロを使用する場合には、クリティカルセクションにしたい部分、つまり割込みなどで中断させたくない部分を、これらのマクロで挟み込むようにします。サンプルプログラムでは以下のようにして、メッセージの表示部分をクリティカルセクションにしています。
なお本来はシリアル通信のような時間のかかる処理をクリティカルセクションとすべきではありません。メッセージの表示を中断させなくないといったニーズがあるのであれば、大きめの送信用バッファを用意しておいて、送信処理時にはそのバッファに書き込むようにします。クリティカルセクションにするにしても、このバッファへの書き込み処理のみをクリティカルセクションとすべきでしょう。そうすることで割込みが無効になる時間を大幅に削減することができます。
//Entering Critical Section to prevent to be interrupted by ISR taskENTER_CRITICAL(); //Print message through COM cprintf("**Low Priority Task**\r\n"); //Exit from critical section taskEXIT_CRITICAL(); |
サンプルプログラムの実行結果は以下の通りです。「**Low Priority Task**」を途切れることなく表示させることができるようになりましたね。
Handler task called. **Low Priority Task** Handler task called. **Low Priority Task** **Low Priority Task** **Low Priority Task** **Low Priority Task** Handler task called. **Low Priority Task** |
Previous: 6.1. クリティカルセクションとは |
Up: 6. クリティカルセクション |
Next: 6.3. スケジューラ停止 |