割り込み
割り込みは様々な点で例外と違いますが、その動作と使用方法は、ほとんど同じで、同じ割り込みコントローラによって処理されます。 例外がCortex-Mアーキテクチャで定義されているのに対し、割り込みは、命名と機能との両方において、常にベンダ(もっと言うとチップ)固有の実装です。
割り込みは、高度な使い方をしようとする時に必要とされる様々な柔軟性を考慮に入れています。 本書では、そのような高度な使い方は対象外です。しかし、次の点に留意することをお勧めします。
- 割り込みは、ハンドラの実行順序を決めるプログラム可能な優先度を持ちます。
- 割り込みは、ネストとプリエンプションが可能です。つまり、割り込みハンドラの実行は、より優先度の高い割り込みに割り込まれる場合があります。
- 通常、割り込み要因は、割り込みハンドラが無限に再呼び出しされないようにするため、クリアされる必要があります。
ランタイムでの一般的な初期化手順は、常に同じです。
- 必要な時に割り込み要求を起こすように、ペリフェラルを設定します
- 割り込みコントローラで割り込みハンドラの優先度をセットします
- 割り込みコントローラで割り込みハンドラを有効化します
例外と同様に、例外ハンドラを宣言するために、cortex-m-rt
クレートは、interrupt
属性を提供しています。
利用可能な割り込み(そして割り込みハンドラテーブルでの配置)は、通常、svd2rust
を使ってSVDから自動生成されます。
// Interrupt handler for the Timer2 interrupt
// タイマ2割り込みの割り込みハンドラ
#[interrupt]
fn TIM2() {
// ..
// Clear reason for the generated interrupt request
// 発生した割り込み要求の原因をクリアします
}
割り込みハンドラは、通常の関数のように見え、例外ハンドラに似ています(引数がないことを除いて)。 しかし、割り込みハンドラは、特別な呼び出し規約のため、ファームウェアの他の部分から直接呼び出すことができません。 ソフトウェアで割り込み要求を起こし、割り込みハンドラへの転送を発生させることは可能です。
例外ハンドラと同様に、割り込みハンドラ内でstatic mut
変数を宣言し、状態を安全に保持することができます。
#[interrupt]
fn TIM2() {
static mut COUNT: u32 = 0;
// `COUNT` has type `&mut u32` and it's safe to use
// `COUNT`は`&mut u32`の型を持っており、その使用は安全です
*COUNT += 1;
}
ここで示した仕組みの詳細については、例外セクションを参照して下さい。