LEDルーレット

それでは、次のアプリケーションを作ることから始めましょう。

このアプリを実装するために高機能なAPIを提供しますが、低レベルなことは後々やっていきますのでご心配なく。 この章の主な目的はフラッシュへの書き込みとデバッグに慣れることです。

ではこの本のレポジトリのsrcディレクトリにあるコードから始めましょう。 ディレクトリ内に、各章の名前を冠したディレクトリがあります。 それらのディレクトリのほとんどはCargoのスタータープロジェクトです。

早速、src/05-led-rouletteディレクトリの内容に入っていきましょう。 src/main.rsファイルを開いてみてください。

#![deny(unsafe_code)]
#![no_main]
#![no_std]

use cortex_m_rt::entry;
use panic_halt as _;
use microbit as _;

#[entry]
fn main() -> ! {
    let _y;
    let x = 42;
    _y = x;

    // infinite loop; just so we don't leave this stack frame
    loop {}
}

マイクロコントローラのプログラムは通常のプログラムと比べて2つの点で異なります。 #![no_std]#![no_main]です。

no_stdアトリビュートはこのプログラムがOSの存在を前提としたstdクレートを使わず、代わりにstdのサブセットでベアメタルシステム(つまり、ファイルシステムはソケットのようなOSの抽象化がないシステム)でも実行できるcoreクレートを使うことを意味します。

no_mainアトリビュートはこのプログラムが標準のmainインターフェースを使わないことを意味しています。 標準のmainインターフェースは引数を受け取るコマンドラインアプリケーション向けに作られています。 エントリーポイントを定義するために、標準のmainの代わりにcortex-m-rtクレートからentryアトリビュートを使います。 このプログラムではエントリーポイントの名前を「main」としますが、それ以外の名前も使えます。 エントリーポイントになる関数はfn() -> !のシグネチャを持たなければなりません。 このシグネチャは関数が戻れないことを表しており、このプログラムが決して止まらないことを意味します。

ディレクトリ内をよく見ると、Cargoプロジェクトに.cargoディレクトリがあることに気がつくと思います。 .cargoディレクトリにはCargoの設定ファイル(.cargo/config)が含まれています。 このファイルはリンク処理を微調整し、ターゲットデバイス用にプログラムのメモリレイアウトを作成します。 このリンク処理の微調整は、cortex-m-rtクレートを使う要件になっています。

さらに、ディレクトリにはEmbed.tomlファイルがあります。

[default.general]
# chip = "nrf52833_xxAA" # uncomment this line for micro:bit V2
# chip = "nrf51822_xxAA" # uncomment this line for micro:bit V1

[default.reset]
halt_afterwards = true

[default.rtt]
enabled = false

[default.gdb]
enabled = true

Embed.tomlcargo-embedに次の情報を与えます。

  • nrf52833もしくはnrf51822のいずれかを使っていること。第3章でやったのと同じように、使用するチップのコメントアウトを外してください。
  • チップのフラッシュに書き込んだあとプログラムの実行を停止したいこと。これはプログラムがすぐにループに到達しないようにするためです。
  • RTTを無効化したいこと。RTTはチップがデバッガにテキストを送るためのプロトコルです。実は第3章で「Hello World」を送信するのに使ったプロトコルがRTTだったのです。
  • GDBを有効化したいこと。これはデバッグするのに必要です。

それでは、プログラムをビルドするところから始めましょう。