0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【組み込みRTOS設計編①】割り込み管理 ― ISR1とISR2の使い分け

0
Last updated at Posted at 2026-08-19

はじめに

組み込みシステムではハードウェアからの割り込みを適切に処理することが重要です。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はネストの有無に応じて使い分ける

次回(設計編②)はタスク設計の勘所を取り上げます。何をタスクにするか、優先度をどう決めるか、スタックサイズをどう見積もるかを整理します。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?