組み込みのセットアップ
それでは、最初にコンパイルするプログラムを見てみましょう。examples/init.rs ファイルを確認してください。
#![deny(unsafe_code)]
#![no_main]
#![no_std]
use cortex_m::asm;
use cortex_m_rt::entry;
use microbit as _;
use panic_halt as _;
#[entry]
fn main() -> ! {
#[allow(clippy::needless_late_init)]
let _y;
let x = 42;
_y = x;
// infinite loop; just so we don't leave this stack frame
loop {
asm::nop();
}
}
マイクロコントローラ向けプログラムは、標準的なプログラムと 2 つの点で異なります。#![no_std] と
#![no_main] です。
no_std 属性は、このプログラムが基盤となる OS を前提とする std クレートを使わないことを意味します。
その代わりに、プログラムは std のサブセットであり、ベアメタルシステム(つまり、ファイルやソケットのような
OS の抽象化がないシステム)上で動作できる core クレートを使います。
no_main 属性は、このプログラムが、引数を受け取るコマンドラインアプリケーション向けに作られた標準の
main インターフェースを使わないことを意味します。標準の main の代わりに、cortex-m-rt
クレートの entry 属性を使って、独自のエントリポイントを定義します。このプログラムでは、エントリポイントに
main という名前を付けていますが、他のどんな名前でも使えます。エントリポイント関数は
fn() -> ! というシグネチャでなければなりません。この型は、その関数がリターンできないことを示します。
これは、このプログラムが main から戻ることで終了することは決してない、という意味です。コンパイラが
それが可能だと検出した場合、あなたのプログラムのコンパイルを拒否します。
注意深く見ていると、Cargo プロジェクト内に、隠しディレクトリになっている可能性のある .cargo
ディレクトリがあることにも気づくでしょう。このディレクトリには Cargo の設定ファイル
.cargo/config.toml が含まれています。
[build]
target = "thumbv7em-none-eabihf"
[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip nRF52833_xxAA"
rustflags = [
"-C", "linker=rust-lld",
]
このファイルは、ターゲットデバイスの要件に合わせてプログラムのメモリレイアウトを調整するために、リンク処理に
手を加えています。このように変更されたリンク処理は、cortex-m-rt
クレートの要件です。.cargo/config.toml ファイルは、Cargo に対して、MB2 上でコードをビルドして
実行する方法も伝えます。
ここには Embed.toml ファイルもあります。
[default.general]
chip = "nrf52833_xxAA"
[default.reset]
halt_afterwards = true
[default.rtt]
enabled = false
[default.gdb]
enabled = true
このファイルは、cargo-embed に次のことを伝えます。
- 使用しているのは NRF52833 であること。
- フラッシュ後にチップを停止させ、プログラムが
mainに入る前で止まるようにしたいこと。 - RTT を無効にしたいこと。RTT は、チップがデバッガーにテキストを送信できるようにするプロトコルです。 RTT が実際に使われているところはすでに見ています。第 3 章で “Hello World” を送っていたのが、そのプロトコルでした。
- GDB を有効にしたいこと。これはデバッグ手順で必要になります。
何が起きているのかを確認したので、まずはこのプログラムをビルドするところから始めましょう。