点灯させる

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つ、点灯します。