①LED、Buttonの型、グローバル変数宣言
このコード部分の話
type GreenLedPin =
hal::gpio::Pin<hal::gpio::bank0::Gpio22, hal::gpio::FunctionSioOutput, hal::gpio::PullDown>;
type RedLedPin =
hal::gpio::Pin<hal::gpio::bank0::Gpio20, hal::gpio::FunctionSioOutput, hal::gpio::PullDown>;
type OrangeLedPin =
hal::gpio::Pin<hal::gpio::bank0::Gpio21, hal::gpio::FunctionSioOutput, hal::gpio::PullDown>;
type ButtonPin =
hal::gpio::Pin<hal::gpio::bank0::Gpio23, hal::gpio::FunctionSioInput, hal::gpio::PullUp>;
type DelayTimer = hal::Timer;
type LedAndButton = (GreenLedPin, RedLedPin, OrangeLedPin, ButtonPin, DelayTimer);
static GLOBAL_PINS: critical_section::Mutex<core::cell::RefCell<Option<LedAndButton>>> =
critical_section::Mutex::new(core::cell::RefCell::new(None));
グローバルな変数
static GLOBAL_PINS: critical_section::Mutex<core::cell::RefCell<Option<LedAndButton>>> =
critical_section::Mutex::new(core::cell::RefCell::new(None));
GLOBAL_PINS
は、関数間でPin情報の変数を参照変更するためのグローバルな変数です。
関数を超えて変数の所有権、参照、変更のやり取りをするために、static
とcritical_section
のMutex
、RefCell
を利用します。
critical_section
は、並行処理で必要とされるグローバルな変数を制御するのに役立つ組み込み用のクレートです。
Mutex
、RefCell
は、std
が提供していますが、std_no
環境である組み込みでは利用することができません。
そこでcritical_section
が代わりにMutex
とRefCell
を提供してくれています。
ジェネリック<T>
hal::gpio::Pin<>
の<>
は、ジェネリックと言われるもので、構造体の中で異なる複数の型の値を保持できる定義です。
struct Container<T>{
value: T
}
T
が任意の型になります。
hal::gpio::Pin<hal::gpio::bank0::Gpio22, hal::gpio::FunctionSioOutput, hal::gpio::PullDown>
は、hal::gpio::Pin<>
というPinの型で、hal::gpio::bank0::Gpio22
、hal::gpio::FunctionSioOutput
、hal::gpio::PullDown
の3つを指定しており、GPIO22、SioOutput、PullDownのPin設定であることを意味しています。
type
type GreenLedPin = hal::gpio::Pin<...>;
これはhal::gpio::Pin<...>
をGreenLedPin
という名前に省略するよという意味です。
このtypeを定義することで、グローバル変数の記述が読みやすくなります。
static
static
は、静的変数を定義するために使われます。静的変数はプログラムの全体で一度だけ初期化され、プログラムの終了まで存在します。
Rustでは、static変数自体は変更不可能(イミュータブル)ですが、内部のデータが変更可能(ミュータブル)にすることが可能です。
GLOBAL_PINS
は、critical_section::Mutex
とcore::cell::RefCell
を使って内部のデータを安全に変更できるようにしています。
critical_section::Mutex
Mutex
は、変更可能(ミュータブル)な変数として扱うためのものです。
そして、複数の関数から安全にアクセスできるようにするためのロック機構が備わっており、同時に複数の関数がデータにアクセスすることを防ぎます。
core::cell::RefCell
RefCell
は、実行時に変更可能(ミュータブル)な借用をチェックするためもので、同じスコープ内での複数の変更可能(ミュータブル)な参照を可能にします。
Option
変数でNone
を扱うためのものです。
次のようにi32
をOption
でラップすることで、None
を入れることができます。
let val: Opiton<i32> = None