動機とやったこと
STM32 は、組み込み Rust の抽象レイヤーである embedded-hal がとても整っているようです。
STM32F1xx だけではなく、STM32G0xx などもあり、非常に充実しているようです。 このため、Rust で組み込みファームウェアを作りたいならば、STM32がとても良い選択肢になると思いました。
そのため、Rust で開発を初めてFirmwareを書き込むところまでをやってみました。
STM32F103 用の Rust のパッケージの準備
cargo init して、dependencies に以下を書き換えました。
- まず、stm32f1xx-hal を、features に
stm32f103
と利用するMCUを指定して追加する - stm32f1xx-hal が参照しているcortex-m、cortex-m-rt、nbを追加する(個別にcargo add すると stm32f1xx-hal のバージョンと合わなくなる
- build に target を指定する
# Cargo.toml [dependencies] panic-halt = "0.2.0" cortex-m = "0.7.6" cortex-m-rt = "0.7.1" stm32f1xx-hal = { version = "0.10.0", features = ["rt", "stm32f103"]} nb = "^1"
ビルドするtargetは .cargo/config で指定するようで、stm32f1xx-hal にある .cargo/config ものを利用します。
このビルドには memory.x というファイルで MCUのFLASHとRAMのサイズを指定するため、stm32f1xx-hal にある memory.xかコピーして、目的のサイズに書き換えます。
MEMORY { FLASH : ORIGIN = 0x08000000, LENGTH = 64k RAM : ORIGIN = 0x20000000, LENGTH = 20k }
あと、必要なビルドに必要なターゲットをインストールする。これはstm32f1xx-halのREADMEのinstalling softwareに書かれています。
rustup target install thumbv7m-none-eabi
ライター
STM32 のライターとして、ST-Link V2がAmazon でも安価に購入できます。
ちょっと前に nanoDAP という Type-CのDAP-Link を購入して持っていたので、それを使っています。
Build &Write
cargo-flash を使うと非常に便利です。BuildとWriteが同時に行われます。 これはUSB接続されているDAP Link を認識して、必要な形式に書き換え、
cargo install cargo-flash
cargo flash --chip STM32F103C8
VS Code で can't find crate for test
can't find crate とでる
不必要なターゲットを見ているためらしい。設定に以下を追加して、でなくなりました。
// .vscode/settings.json { "rust-analyzer.checkOnSave.allTargets": false }
cargo-flashを使わずopenocdでbuild & write
一応、cargo-flash を使う前に試していた手順を残しておきます。
ビルドするには、cargo build するだけで良いです。
cargo build
それを、書き込むときに使うものに、書き換えます。Ubuntu 22.04 であれば binutils-arm-none-eabi をインストールすると arm-none-eabi-objcopy が使えます。
arm-none-eabi-objcopy -O binary ./target/thumbv7m-none-eabi/debug/try-rust-stm32 firmware.bin
OpenOCD に ST-Link と DAP-Link(nanoDAP) の設定があり、それを読み込むようにします。
# openocd.cfg # DAP-Link source [find interface/cmsis-dap.cfg] # ST-Link # source [find interface/stlink-v2.cfg] source [find target/stm32f1x.cfg]
これを実行するコマンドをつくりました。いろいろ検索した結果、以下のコマンドになりました。
#!/bin/bash set -xe cargo build arm-none-eabi-objcopy -O binary ./target/thumbv7m-none-eabi/debug/try-rust-stm32 firmware.bin sudo /usr/bin/openocd -f openocd.cfg \ -c init \ -c "reset halt" \ -c "flash write_image erase firmware.bin 0x08000000" \ -c "verify_image firmware.bin" \ -c "reset" \ -c shutdown
STM32G030 でもできた
STM32G030J6M6 は SOP-8 パッケージで、そしてTaoBaoで150円くらいで買えます。内蔵オシレータも付いていて、MCU単体で動作する便利なやつです。 STM32F103 よりは、STM32G030 を小物に使いたく、STM32 での Rust チャレンジをしていました。 stm32g0xx-hal
一度ハンダブリッジがあって動かなかったという凡ミスをしたのですが、その後は動作するようになりました。