プログラムの大枠
プログラムの大枠は、次の通りです。
graph TD A[main] --> C[mainの何もしない無限ループ] C -->|"GPIO割り込み(Button割り込み)"| B[IO_IRQ_BANK0] B -->|IO_IRQ_BANK0の処理完了| C
main
関数は、Pinの設定、割り込み設定を行い最後に何もしない無限ループで終わります。
Button割り込みがなければ、常に何もしない無限ループで待機し続けます。
Button割り込みがあった時に、IO_IRQ_BANK0
関数が実行され、LEDが点灯し処理終了後にmain
関数の何もしない無限ループに戻ります。
つまり割り込みがない限りは、何もしないプログラムになります。 また前章のボタンの入力をmain関数で検知する処理と比較して、GPIO割り込みというハードウェアとして備わっている機能に任せることができため、高速化つ確実にButtonを検知できます。
関数間でやり取りするためのグローバル変数の必要性
本章の処理では、main
関数とIO_IRQ_BANK0
関数の2つの関数がそれぞれ独立して実行されます。
Rustでは、main
関数から別の関数を実行する場合は所有権を渡してPinの参照変更をし、LEDを光らせます。
今回の場合は、IO_IRQ_BANK0
関数をmain
関数が呼び出すのではなく、GPIO割り込み(Button割り込み)が呼び出し実行します。
そのため、main
関数から所有権をIO_IRQ_BANK0
に所有権を貸すことができません。
そこで次のようなグローバルな変数を宣言して、関数間の所有権と変数の参照変更をできるようにしています。
static GLOBAL_PINS: critical_section::Mutex<core::cell::RefCell<Option<LedAndButton>>> =
critical_section::Mutex::new(core::cell::RefCell::new(None));