はじめに
組み込みシステムではハードウェアからの割り込みを適切に処理することが重要です。OSEK/ATK1では割り込みサービスルーチン(ISR)を2つのカテゴリに分けて管理しています。
このカテゴリ分けはOSEK/ATK1の特徴的な仕組みの一つで、割り込み処理の設計に大きく影響します。今回はISR1とISR2の違いと使い分けを整理します。
ISR1 ― OSの管理外の割り込み
ISR1はOSの管理外で動作する割り込みハンドラです。OSのAPIを呼び出すことができません。
ISR1(isr1_handler) {
/* OSのAPIは使えない */
/* ハードウェアの操作のみ */
clear_hardware_interrupt_flag();
}
OSの管理外で動作するため、オーバーヘッドが最小限です。非常に短時間で完了するハードウェアの処理(割り込みフラグのクリアなど)や、OSが停止していても動作しなければならない処理(ウォッチドッグタイマーなど)に使います。
ISR2 ― OSの管理下の割り込み
ISR2はOSの管理下で動作する割り込みハンドラです。OSのAPIを呼び出すことができます。
ISR2(isr2_handler) {
/* OSのAPIが使える */
SetEvent(task_control, event_sensor_ready);
/* タスクへの通知など */
}
ISR1よりオーバーヘッドはやや大きくなりますが、タスクへのイベント通知やリソースの操作など、OSの機能を使った処理ができます。多くの割り込み処理はISR2で実装します。
ISR内でやっていいこととダメなこと
割り込みハンドラは処理時間を極力短くするのが原則です。長い処理を割り込みハンドラ内で行うと、他の割り込みやタスクの応答性が悪化します。
やっていいこと
- ハードウェアの割り込みフラグのクリア
- データのバッファへの格納
- タスクへのイベント通知(ISR2のみ)
避けるべきこと
- 重い演算処理
- ブロッキング操作(待ち処理)
-
WaitEvent()などの待ち系API(ISR2でも使用不可)
割り込みからタスクへの通知パターン
ISRでは最低限の処理だけを行い、重い処理はタスクに任せるのが基本パターンです。
/* ISR2:割り込みを受けてタスクに通知 */
ISR2(uart_receive_isr) {
receive_buffer[buf_index++] = read_uart_data(); /* データ格納(buf_indexはvolatile修飾・排他制御を要検討) */
SetEvent(task_uart, event_data_received); /* タスクに通知 */
}
/* 拡張タスク:ISRからの通知を受けて処理 */
TASK(task_uart) {
while (1) {
WaitEvent(event_data_received); /* ISRからの通知待ち */
ClearEvent(event_data_received);
process_received_data(); /* 受信データの処理 */
}
}
このパターンを「遅延割り込み処理(Deferred Interrupt Processing)」と呼びます。割り込みの応答性を保ちながら、重い処理をタスクコンテキストで安全に実行できます。
割り込みの禁止と許可
クリティカルセクションを保護するために、一時的に割り込みを禁止したい場面があります。OSEK/ATK1では用途に応じて使い分けられる複数のAPIを提供しています。
DisableAllInterrupts(); /* すべての割り込みを禁止 */
/* クリティカルな処理 */
EnableAllInterrupts(); /* すべての割り込みを許可 */
SuspendAllInterrupts(); /* ネスト可能な全割り込み禁止 */
ResumeAllInterrupts();
SuspendOSInterrupts(); /* Category 2 ISR(ISR2)をマスク */
ResumeOSInterrupts();
DisableAllInterrupts() と SuspendAllInterrupts() の違いはネスト可否です。ネストして呼び出す可能性がある場合は SuspendAllInterrupts() を使ってください。
ISR1とISR2の使い分けまとめ
| ISR1 | ISR2 | |
|---|---|---|
| OSのAPI呼び出し | 不可 | 可 |
| オーバーヘッド | 小 | やや大 |
| 主な用途 | HW操作・最速応答 | タスク通知・データ転送 |
まとめ
- ISR1はOSの管理外。オーバーヘッド最小だがOSのAPIは使えない
- ISR2はOSの管理下。OSのAPIが使えるため多くの割り込み処理に向いている
- ISR内の処理は短く保ち、重い処理はタスクに委譲する
- 割り込み禁止APIはネストの有無に応じて使い分ける
次回(設計編②)はタスク設計の勘所を取り上げます。何をタスクにするか、優先度をどう決めるか、スタックサイズをどう見積もるかを整理します。