点灯させる
embedded-hal
この章ではmicro:bitの背面にある多くのLEDのうちの1つを光らせます。
これは組込みプログラミングでの「Hello World」です。
このタスクを完了するためにembedded-hal
で提供されるトレイトの1つを使います。
OutputPin
トレイトがピンのオン、オフを可能にします。
micro:bitのLED
micro:bitの背面に5x5のLEDがあります。 これをLEDマトリクスと呼びます。 25本のピンでLEDを1つずつ駆動するのではなく、マトリクス配置を使うことで10(5+5)ピンだけを使って、マトリクスのどの行とどの列を点灯するか、を制御します。
注意 micro:bit v1では少し違う実装になっています。 回路図のページを見ると、実際は3x9マトリクスとして実装されおり、いくつかの行は使っていません。
特定のLEDを点灯するためにどのピンを制御するかは、micro:bit v2回路図やmicro:bit v1回路図を読まなければなりません。 幸運なことに、全てを良い感じに抽象化するmicro:bit BSPを使えます。
実際に点灯する!
マトリクスのLEDを1つ点灯するコードは、とても簡単ですが、少し準備が必要です。 まずコードを見てから、1つずつ見ていきましょう。
#![deny(unsafe_code)] #![no_main] #![no_std] use cortex_m_rt::entry; use panic_halt as _; use microbit::board::Board; use microbit::hal::prelude::*; #[entry] fn main() -> ! { let mut board = Board::take().unwrap(); board.display_pins.col1.set_low().unwrap(); board.display_pins.row1.set_high().unwrap(); loop {} }
main関数までの最初の数行は、いくつかの基本的なインポートやすでに見たセットアップのコードです。 しかしながら、main関数はこれまでに見たものと全く違います。
最初の行はRustで書かれたほとんどのHALが内部的にどう動くかに関係しています。
先述した通りHALはチップの全ペリフェラルを(Rust的な意味で)所有するPACクレートの上に構築されています。
let mut board = Board::take().unwrap();
はPACから全ペリフェラルを取得し、変数に束縛します。
今回の場合、HALだけではなくBSP全体が対象となります。
これはボード上の他のチップをRustで表現した所有権も取得します。
ノート: なぜここで
unwrap()
を呼ぶ必要があるのかというと、じつはtake()
は2回以上呼ぶことが可能です。 するとペリフェラルは2つの別の変数として存在することになり、同じリソースを2つの変数から変更できるため、数々の混乱を巻き起こすことになります。 この事態を避けるために、ペリフェラルを2回取得しようとするとパニックを起こすようにPACが実装されています。
今から行1
、列1
に接続されているLEDを点灯します。
そのために行1
ピンをhighレベルにします(つまり、オンにします)。
列1
をlowレベルのままにしておく理由は、LEDマトリクス回路の仕組みのためです。
さらに、embedded-hal
は単なるピンのオン、オフも含め、ハードウェアの各操作がエラーを返し得ることを想定して設計されています。
今回の場合、まずありえないので、結果を単にunwrap()
します。
テストする
私たちの小さなプログラムをテストする方法はとても単純です。
まず、プログラムをsrc/main.rs
に書きます。
そのあと、前節でやったように単にcargo embed
コマンドを実行し、前回と同様にフラッシュに書き込みます。
そして、GDBを起動して、GDBスタブに接続します。
$ # 前節と同じGDBデバッグコマンドをここで実行します
(gdb) target remote :1337
Remote debugging using :1337
cortex_m_rt::Reset () at /home/nix/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.12/src/lib.rs:489
489 pub unsafe extern "C" fn Reset() -> ! {
(gdb)
GDBのcontinue
コマンドでプログラムを実行すると、micro:bitの背面にあるLEDが1つ、点灯します。