記事の概要
組み込みRustについて、STM32 NUCLEO-F446RE を用いて、開発環境の構築からサンプルプロジェクトによる動作確認までを説明します。
現在、STM32 NUCLEO-F446RE は入手困難ですが、本記事の内容に沿って設定を修正すれば他のSTM32F4シリーズを使用したボードにも適用できます。
開発環境構築
本記事の内容は以下のWindows環境で動かしています。
Linux (Ubuntu 20.04 LTS)でも同様のことができるはずです
- PC
- Windows 11
- マイコンボード
- STM32 NUCLEO-F446RE
- CPU:STM32F446RET6
- CPUコア:ARM32bit Cortex-M4(+FPU)
- フラッシュ:512KB
- SRAM:128KB+4KB(Backup)
- STM32 NUCLEO-F446RE
開発環境の構築は以下のサイトを参照しました。
上記のサイトは Nucleo-F303K8 を対象としており、本記事では主に設定の差分について解説したいと思います。
まずは上記サイトを参照して以下の準備をしてください。
コマンドの入力にはPowerShellもしくはコマンドプロンプトを使用してください。
- arm-none-eabi-gdb のインストール
- Arm GNU Toolchain Downloadsのサイトから現時点(2023/01/10)での最新の arm-gnu-toolchain-12.2.rel1-mingw-w64-i686-arm-none-eabi.exe をダウンロードして実行
- OpenOCD のインストール
- GNU MCU Eclipse OpenOCD v0.10.0-12 20190422から gnu-mcu-eclipse-openocd-0.10.0-12-20190422-2015-win64.zip をダウンロードして、解凍フォルダ内のopenocd.exeファイルを実行
- インストール後は、環境変数設定画面において、openocd.exeを格納しているフォルダへのPathを通す
- USBでボードをPCと接続し
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg
を実行して、上記サイトと同様のログが出ることを確認- 他のデバッガーやボードを使用する場合は、 \OpenOCD フォルダ内の \scripts フォルダの中から自分の環境に一致するものを選ぶ
- Rustup のインストール
- RustupはRustのインストールと管理をするソフト
- Windows にRustup をインストールするには、 Visual Studio C++ Build toolsのインストールも必要
- 具体的なインストール方法は以下のサイトを参照。(書籍では「基礎から学ぶ組み込みRust」の2章が詳しい)
- クロスビルドツールチェインのインストール
- マイコンボードに対応したクロスビルドツールチェインをインストール
- NUCLEO-F446REのCPUはCortex-M4 (with FPU)なので
rustup target add thumbv7em-none-eabihf
を実行 - thumbv6m-none-eabi
- Cortex-M0
- Cortex-M0+
- thumbv7em-none-eabi
- Cortex-M4 (no FPU)
- Cortex-M7 (no FPU)
- thumbv7em-none-eabihf
- Cortex-M4F (with FPU)
- Cortex-M7F (with FPU)
- thumbv7m-none-eabi
- Cortex-M3
- Cargo-generate のインストール
-
cargo install cargo-generate
を実行
-
- VS Code のインストール
- VS Code拡張ツール Cortex-Debug のインストール
Linux での開発環境構築する場合もWindowsと大差はありません。
以下のサイトなどを参照ください。
サンプルプロジェクトで動作確認
以下のコマンドを実行するとサンプルプロジェクトが生成されます
cargo generate -–git https://github.com/rust-embedded/cortex-m-quickstart.git
サンプルプロジェクトはSTM32 Discovery Board用の設定なので、STM32 NUCLEO-F446RE Board用の設定に修正します
.cargo/config.toml
サンプルプロジェクトのトップ階層から .cargo/config.toml を開いて修正します。
ターゲットを Cortex-M3用の thumbv7m-none-eabi
から Cortex-M4F and Cortex-M7F (with FPU)用の thumbv7em-none-eabihf
に変更します。
また、デバッグツールのopenocdを有効にします
修正前
[target.thumbv7m-none-eabi]
# runner = "arm-none-eabi-gdb -q -x openocd.gdb"
target = "thumbv7m-none-eabi" # Cortex-M3
# target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
修正後
[target.thumbv7em-none-eabihf]
runner = "arm-none-eabi-gdb -q -x openocd.gdb"
# target = "thumbv7m-none-eabi" # Cortex-M3
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)
.vscode/launch.json
VS Codeのデバッグ用設定を修正します。サンプルプロジェクトのトップ階層から .vscode/launch.json を開いて修正します。
Device
CPU の型番を修正します。STM32 NUCLEO-F446RのCPUは STM32F446RET6
です
修正前
"device": "STM32F303VCT6",
修正後
"device": "STM32F446RET6",
OpenOCD Config Files
STM32 NUCLEO-F446RのOpenOCD Config Files の名称 stm32f4x.cfg
に修正します
他のマイコンボードのOpenOCD Config Fileの名称を知りたい場合は、以下のサイトから探してください。
修正前
"configFiles": [
"interface/stlink-v2-1.cfg",
"target/stm32f3x.cfg"
],
修正後
"configFiles": [
"interface/stlink-v2-1.cfg",
"target/stm32f4x.cfg"
],
SVDの設定とダウンロード
マイコンのレジスタ情報が記載されたsvd ファイルを設定します
修正前
"svdFile": "${workspaceRoot}/.vscode/STM32F303.svd",
修正後
"svdFile": "${workspaceRoot}/.vscode/STM32F446.svd",
また、以下のサイトから自分のマイコンボードに対応したSVDファイルをダウンロードし、.vscodeフォルダに格納してください。
CPU Frequency
CPUのマニュアルからCPU Frequencyを調べて修正します。
例えば STM32F446のCPU Frequencyは16 MHz です
修正前
"cpuFrequency": 8000000,
修正後
"cpuFrequency": 16000000,
Cargo.toml
ターゲットマイコンを修正します。
クレート stm32f4xx-hal を使用する予定なので、以下のサイトの設定にします
他のクレートを使用する場合は、それぞれのクレートのページに記載された設定にしてください。
修正前
[dependencies]
cortex-m = "0.6.0"
cortex-m-rt = "0.6.10"
cortex-m-semihosting = "0.3.3"
panic-halt = "0.2.0"
# [dependencies.stm32f3]
# features = ["stm32f303", "rt"]
# version = "0.7.1"
修正後
[dependencies]
embedded-hal = "0.2"
nb = "1"
cortex-m = "0.7"
cortex-m-rt = "0.7"
# Panic behaviour, see https://crates.io/keywords/panic-impl for alternatives
panic-halt = "0.2"
[dependencies.stm32f4xx-hal]
version = "0.13.2"
features = ["stm32f446"] # replace the model of your microcontroller here
memory.x
memory.x の FLASH と RAM のアドレスとサイズを修正します。
これらの値はCPUのマニュアルのmemory mapに記載されています。
例えば、STM32F446のFLASHの開始アドレスは 0x08000000 であり、サイズは 512KBであり、SRAMの開始アドレスは 0x20000000 であり、サイズは 128KBであることが分かります
修正前
FLASH : ORIGIN = 0x00000000, LENGTH = 256K
RAM : ORIGIN = 0x20000000, LENGTH = 64K
修正後
FLASH : ORIGIN = 0x8000000, LENGTH = 512K
RAM : ORIGIN = 0x20000000, LENGTH = 128K
動作確認
実際にプログラムをボードに書き込んで動作確認してみます。
動作確認のコードは以下のサンプルを参照しています。
デバッグ方法の詳細は 組み込みRust開発環境構築【STM32 NucleoとVSCodeで構築】の「サンプルコードの実行」をご参照ください。
ボードをPCにUSBで接続しVS Codeでサンプルプロジェクトを開き、main.rsを以下のコードに置き換えてから、"Run and Debug"をクリック→プルダウンのDebug(OpenOCD)を選択→矢印マークをクリックの順番で、プログラムのビルド、書き込み、デバッグが実行されます
#![deny(unsafe_code)]
#![no_std]
#![no_main]
use cortex_m_rt as rt;
use stm32f4xx_hal as hal;
use panic_halt as _;
use hal::prelude::*;
#[rt::entry]
fn main() -> ! {
if let Some(peripherals) = hal::pac::Peripherals::take() {
let gpioa = peripherals.GPIOA.split();
let mut led = gpioa.pa5.into_push_pull_output();
let gpioc = peripherals.GPIOC.split();
let button = gpioc.pc13;
loop {
if button.is_high() {
led.set_low();
} else {
led.set_high();
}
}
}
}
USERスイッチを押下してLEDが点灯すれば正常に動作しています
ここで使用しているクレート embedded-hal については以下の解説をご参照ください
(ただし以下のサイトで解説しているのはstm32f4xx_halではなく、stm32f3xx_halになります)