コンテンツにスキップ

組み込み Rust を始める(probe-rs と最小プロジェクト)

このページは、組み込み Rust を「実機で動かす」ところまでを最短距離で案内する入門ガイドです。 主に Cortex-M 系 MCU(STM32 / nRF52 / RP2040 など)を想定しますが、考え方は他のターゲットでも役立ちます。


ゴール(このページでできるようになること)

Section titled “ゴール(このページでできるようになること)”
  • Rust のクロスコンパイル用ターゲットを追加できる
  • cargo generate でテンプレからプロジェクトを作れる
  • probe-rs でフラッシュ書き込み・実行できる
  • defmt + RTT によるログ出力の基本が分かる
  • よくある詰まりポイントを切り分けられる

  • デバッグプローブ(例: ST-Link / J-Link / CMSIS-DAP など)
  • 対応ボード(例: Nucleo, Discovery, nRF DK 等)

以降の手順は「プローブで書き込み・デバッグできる」構成を前提にします。 USB シリアル(UART)だけでも開発は可能ですが、最初はプローブがある方が圧倒的に楽です。


Rust を未導入なら rustup を使うのが標準です。

導入確認:

Terminal window
rustc -V
cargo -V

1.2 クロスコンパイル用ターゲット

Section titled “1.2 クロスコンパイル用ターゲット”

Cortex-M4F/M7F などでよく使う例(FPU あり):

Terminal window
rustup target add thumbv7em-none-eabihf

どれを選ぶかは MCU のコア種別 + FPU の有無 で判断します。

  • Cortex-M0/M0+: thumbv6m-none-eabi
  • Cortex-M3: thumbv7m-none-eabi
  • Cortex-M4/M7(FPUなし): thumbv7em-none-eabi
  • Cortex-M4F/M7F(FPUあり): thumbv7em-none-eabihf

1.3 probe-rs(フラッシュ・デバッグ)

Section titled “1.3 probe-rs(フラッシュ・デバッグ)”
Terminal window
cargo install probe-rs-tools

確認:

Terminal window
probe-rs --version
probe-rs list-probes

1.4 cargo-generate(テンプレから雛形作成)

Section titled “1.4 cargo-generate(テンプレから雛形作成)”
Terminal window
cargo install cargo-generate

ゼロから memory.x やリンカ設定を書くのは、最初はつらいです。 テンプレを使って「動く構成」を作るのがおすすめです。

Terminal window
cargo generate --git https://github.com/rust-embedded/cortex-m-quickstart

[package]
name = "blinky"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
defmt = "1"
defmt-rtt = "1"
panic-probe = { version = "1", features = ["print-defmt"] }

3.2 src/main.rs(最小プログラム)

Section titled “3.2 src/main.rs(最小プログラム)”
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt_rtt as _;
use panic_probe as _;
#[entry]
fn main() -> ! {
defmt::info!("Hello, embedded Rust!");
loop {
// メイン処理をここに書く
}
}

重要な3点:

  1. #![no_std]: 標準ライブラリなしで動かす
  2. #![no_main]: OS 前提の fn main() を使わない
  3. #[entry] fn main() -> !: 終了しないエントリポイント

メーカーのハードウェアマニュアルを読み MCU に合わせて必ず確認してください。

MEMORY
{
FLASH : ORIGIN = 0x08000000, LENGTH = 512K
RAM : ORIGIN = 0x20000000, LENGTH = 128K
}
[build]
target = "thumbv7em-none-eabihf"
[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip STM32F407VGTx"
rustflags = [
"-C", "link-arg=-Tlink.x",
]

Terminal window
cargo build

リリースビルド:

Terminal window
cargo build --release

Terminal window
probe-rs chip list
Terminal window
cargo run --release

6. よくあるトラブルシューティング

Section titled “6. よくあるトラブルシューティング”
  • プローブが接続されているか確認
  • USB ケーブルが充電専用でないか確認
  • Linux の場合、udev ルールの導入を検討
  • memory.x が存在しパスが正しいか確認
  • ターゲットとリンカ設定の整合を確認
Terminal window
rustup target add thumbv7em-none-eabihf
  • memory.x の FLASH/RAM サイズ・アドレスをデータシートと照合
  • HAL の初期化が正しいか確認
  • defmt_rtt as _; があるか確認
  • defmt::info!("boot"); を main の最初に置く

  1. GPIO 出力(LED 点滅)
  2. タイマ割り込み(一定周期処理)
  3. UART / I2C / SPI(センサ読み取り)
  4. 低消費電力、ウォッチドッグ
  5. ログ設計(defmt のレベル、panic の扱い)

「あなたのボード名 + HAL crate + blinky」でサンプルを探し、最小構成に HAL を足す形で進めるのがおすすめです。