Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

点灯させよう

この章の最後に、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 に設定することで、row1col1 に接続された 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 つが点灯するはずです。