Interrupts: Under the Hood (p.161)非公式訳

割り込みのしくみ

割り込みはハードウェア寄りの機能ですが、魔法ではありませんし、そのしくみを知ればいつか割り込みがらみのバグを見つけ出すことになったときに役に立つかもしれません。

AVRのあらゆる機能がそうであるように、割り込みも各種レジスタの各種ビットですべて操作します。AVRには、発生しうる割り込みの種類ごとにセットできるフラグビットがあります。前出のコード例では、ボタンが押されたときにINT0の割り込みフラグがセットされます。すべての割り込みを確認するかどうかを決めるグローバル割り込みイネーブルビットもあります。

このグローバル割り込みイネーブルビット(グローバル割り込みイネーブルフラグ)がセットしてあるときには、どれか割り込みフラグがセットされたときに察知できるよう、すべての割り込みフラグが絶えず見張られています。セットされた割り込みフラグがひとつでも見つかった場合は、それ以上割り込まれないよう最初にグローバル割り込みイネーブルフラグがクリアされたあと、見つかった最初の割り込みフラグに対応するISRが実行されます。最初のISRの処理が終わると、グローバル割り込みイネーブルフラグが再度セットされます。そのあとは、割り込みフラグのセットされた次のISRへ進むか、中断していたmain()ルーチンへ戻るかします。このように個々の割り込みフラグの順番によって、各ISRの実行される優先順位が決まっています(割り込みの一覧については表8-1を見てください。これはデータシートの表を元に作成したものです)。

割り込みのメカニズムは、コードのどの部分を実行すべきなのかをどのようにして知るのでしょうか? コードを機械語で表現した場合、その先頭には割り込みベクタ空間が配置されます。この割り込みベクタ空間の各エントリには、対応するISRコードの格納されるメモリロケーションへのジャンプコマンドが記述できます。たとえばCPUがUSART_RX割り込みを受け付けると、何らかのデータがUSART経由で受信されたことが信号として伝えられ、USART_RX割り込みフラグがセットされます。このフラグは割り込みテーブルの18番目のフラグであるため、割り込みベクタテーブルの18番目のエントリが読み出されます。割り込みベクタテーブルの18番目のエントリには、該当するISRの開始位置にあるコードを実行するようAVRに命ずるコマンドが記述してあります。

要するに、割り込みフラグがセットされたときにCPUは、(1) そのとき実行していた処理を中断し、(2) それ以上割り込まれないようグローバル割り込みイネーブルビットをクリアし、(3) 対応するメモリアドレスを割り込みベクタテーブル内で探し、(4) そのメモリアドレス(ISRの先頭に来るようセットされたアドレス)に見つかったコードが何であれそのコードの実行を開始します。各ISRの処理が終わるとRETI (return from interrupt)コマンドが発行されます。このRETIコマンドはCPUに対し、(1) グローバル割り込みイネーブルフラグを再度セットするよう命じ、(2) 割り込みフラグがセットされていないかどうかを再確認するよう命じ、(3) セットされた割り込みフラグがなかった場合は、中断していたコードへ戻るよう命じます。最初の割り込み要求の処理中に別の割り込みフラグがセットされた場合は、その新たな割り込みの処理を済ませてからmain()ルーチンへ戻ります。

プログラマーの立場としては何をすればよいのでしょうか? 個々の割り込みフラグは、優先順位が決まっているので必ず同じ順番で実行されます。ハードウェアのレイアウトを設計するときはこのことを考慮したうえで、特に重要な信号を特に重要な割り込みピンに物理的に接続するようにしてください。またグローバル割り込みイネーブルフラグがセットされていないときでも個々の割り込みフラグはセットできます。グローバル割り込みイネーブルフラグがセットされていないときにセットされた割り込みフラグは、グローバル割り込みイネーブルフラグがセットされたときに通常の優先順位どおりにすべて処理されます。割り込みはひとつずつ順番に処理されるので、割り込みルーチンの実行に長い時間のかかる場合や、非常に高い頻度で何度も何度も割り込みフラグがセットされる場合は、しばらく待たないとmain()ルーチンへ戻れないことがあります。また個々の割り込みフラグはハードウェアレジスタのどのフラグともほとんど違いはありませんので、ボタン押しの操作などをシミュレートする必要のある場合は、自分で作成したコードの内部から割り込みをかけることが可能です。
――――――――――――――――――――
prioritize
プライオーラタイズ
http://wdme3.dual-d.net/audio2/P/WDEJ_p0026100.wav