点灯させよう
この章の最後に、MB2 上にある多数の LED のうち 1 つを点灯させます。この作業を行うために、embedded-hal が提供するトレイトの 1 つ、具体的にはピンをオンまたはオフにできる OutputPin トレイトを使います。
micro:bit の LED
micro:bit の背面には 5x5 の正方形に並んだ LED があり、通常は LED マトリクスと呼ばれます。このマトリクス配置により、各 LED を個別に駆動するために 25 本の別々のピンを使う代わりに、どの列とどの行を点灯させるかを制御するための 10 本(5+5)のピンだけで済みます。
ここでは LED を操作するために microbit-v2 クレートを使います。次の章では、利用可能なすべての選択肢を詳しく見ていきます。
実際に点灯させよう!
LED マトリクス内の LED を点灯させるために必要なコードは、実際にはかなりシンプルですが、少しだけ準備が必要です。まず src/main.rs を見て、そのあとで順を追って確認していきましょう。
#![deny(unsafe_code)]
#![no_main]
#![no_std]
use cortex_m_rt::entry;
use embedded_hal::digital::OutputPin;
use microbit::board::Board;
use panic_halt as _;
#[entry]
fn main() -> ! {
let mut board = Board::take().unwrap();
board.display_pins.col1.set_low().unwrap();
board.display_pins.row1.set_high().unwrap();
loop {
core::hint::spin_loop();
}
}
main 関数までの最初の数行では、これまでに見てきた基本的なインポートとセットアップを行っているだけです。しかし、main 関数は、これまで見てきたものとはかなり違って見えます。
最初の行は、Rust で書かれたほとんどの HAL が内部でどのように動作しているかに関係しています。 前に説明したように、これらはチップのすべての周辺機器を(Rust の意味で)所有する PAC クレートの上に構築されています。次のように書くと
let mut board = Board::take().unwrap();
PAC からそれらの周辺機器を取り出し、変数に束縛します。この具体的なケースでは、HAL だけでなく BSP 全体を扱っているため、ボード上のほかのチップの Rust 上の表現についても所有権を取得することになります。
注: なぜここで
unwrap()を呼ばなければならないのか疑問に思っているなら、理論上はtake()が複数回呼ばれる可能性があるからです。そうなると、周辺機器が 2 つの別々の変数で表現されることになり、2 つの変数が同じリソースを変更するため、多くの混乱を招く可能性があります。これを避けるため、PAC は周辺機器を 2 回取得しようとすると panic するように実装されています。
(繰り返しになりますが、ここまでの話で混乱しているなら、次の章でもう一度、さらに詳しく説明します。)
これで、row1 ピンを high に設定することで、row1、col1 に接続された LED を点灯させられます(つまりオンにします)。col1 を low のままにしておける理由は、LED マトリクスの回路の仕組みにあります。さらに、embedded-hal は、ピンのオン/オフ切り替えのような操作であっても、ハードウェアに対するあらゆる操作がエラーを返しうるように設計されています。今回のケースではその可能性は極めて低いため、結果に対して単に unwrap() を使えば十分です。
試してみる
この小さなプログラムのテストはとても簡単です。cargo embed を実行して、これまでと同じように書き込みます。次に GDB を開き、GDB スタブに接続します。
$ gdb ../../../target/thumbv7em-none-eabihf/debug/meet-your-software
(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 つが点灯するはずです。