Rustに入門するためにSTM32でLチカしてみた
近年、C++の後継となる言語としてRustと呼ばれるプログラム言語が注目されている。 研究やアルバイトではC++を書いているので、今までRustを使う機会は全くなかった。 だけど、食わず嫌いはいけないなと思い、趣味でRustを書くための動機を考えてみた。
そして、組み込み開発をRustでやるのが良さそうという結論に至った。 実は、STM32をHALライブラリ無しで動かそうと、ARMアセンブリを読んだり、C++のTMPでLチカしてみたりと、裏でいろいろやっていたのだ。 どうせなら、この取り組みで使っているC++をRustに置き換えれば、Rustへの理解につながるのではないか?というワケ。
そこで、Rustを使った組み込み開発の先行研究をサーベイしてみた。 すると、いくつかの記事を見つけることができた。
- Introduction - The Embedded Rust Book
- 組込みRustドキュメントを和訳したお話 - simplegifts#tech
- 組込みRust考察①~効率良く安全な組込み開発をしたい~ - 低レイヤ強くなりたい組込み屋さんのブログ
- Rust: Xargoとarm-binutils無しでCortex-Mターゲットのファームウェアをビルドする - ryochack.blog
中でも、あるレジスタへの操作はその時点で適切か?をコンパイル時に検証する、ある種の有限状態マシンがこんなに簡潔に書けることを知って一目惚れしてしまった。 私の知ってる限りでは、C++で有限状態マシンを書くときには、全ての状態遷移をテーブル状に保持する型を用意する必要があり、ここまで簡潔に書くことができない。
また、japaric氏という方が、Rustを使った組み込み開発の先駆者であるということも知った。 Rustで組み込み開発をするときは、この方の情報に注目するのが良さそうだ。
Rustで組み込み開発をする十分な動機や近年の動向を知ることができたので、STM32の開発テンプレートを参考に、STM32F4DISCOVERYでLチカしてみた。
インストール
私の使用しているOSはLinux、ディストリビューションはArch Linuxである。 したがって、他の環境でLチカするためには、適宜読み替えが必要になる。 下記文献を参照されたい。
Introduction - The Embedded Rust Book
Rust
まずはRustをインストールする。
公式サイトによれば、rustup
というツールチェーンマネージャをインストールすれば良い。
$ yay -S rustup
この時点で
$ rustc -V
や
$ cargo -V
をすると
error: no default toolchain configured
というエラーメッセージが出力された。
原因は、文字通りデフォルトのツールチェーンが設定されていないからだ。
そこで、rustup
で安定版のツールチェーンを設定する。
$ rustup default stable
最新版のツールチェーンのダウンロードが始まり、しばらくすると適切な設定がされる。
$ rustc -V rustc 1.43.0 (4fb7144ed 2020-04-20)
$ cargo -V cargo 1.43.0 (3532cf738 2020-03-17)
Cortex-Mターゲット向けツールチェーン
Cortex-Mターゲット向けのツールチェーンをインストールする。
今回使うSTM32F4DISCOVERYは、FPU付きCortex-M4 (Cortex-M4F) を搭載したマイコンを使っている。
STM32F407VGT6 microcontroller featuring 32-bit ARM®Cortex®-M4 with FPU core URL: https://www.st.com/en/evaluation-tools/stm32f4discovery.html
したがって、Cortex-M4Fターゲット向けのツールチェーンをインストールすれば良い。
$ rustup target add thumbv7em-none-eabihf
cargo-binutils
"The Embedded Rust Book"によると、cargo-binutils
というものをインストールする必要がある。
これは一体何なのか?なぜこれが必要なのか?未だに分かってないです…。
$ cargo install cargo-binutils $ rustup component add llvm-tools-preview
GNUデバッガー
ARM EABIターゲット向けのGNUデバッガーをインストールする。
$ yay -S arm-none-eabi-gdb
OpenOCD
デバッグやFlashROMへの書き込みのために使用する、OpenOCD
をインストールする。
$ yay -S openocd
STM32F4DISCOVERYをOpenOCDに対して、ルート権限なしで使うためには、udevルールを設定する必要がある。 下記リンク先を参照されたい。
- https://rust-embedded.github.io/book/intro/install/linux.html#udev-rules
- https://wiki.archlinux.org/index.php/Udev#About_udev_rules
設定の際には、ベンダーIDとデバイスIDが必要である。
これらは、STM32F4DISCOVERYをPCに接続した状態で lsusb
コマンドを使えば、知ることができる。
例えば、
$ lsusb (...中略...) Bus 001 Device 002: ID 0483:3748 STMicroelectronics ST-LINK/V2
であれば、ベンダーIDは0483、デバイスIDは3748である。
コード
Lチカするプログラムは、GitHubに公開した通りである。
プログラムは、このリポジトリを参考にした。
このプログラムは、以下の4つのクレートを利用している。
cortex-m
: Cortex-Mプロセッサへの低レベルのAPIを提供するcortex-m-rt
: Cortex-MプロセッサのスタートアップコードやランタイムAPIを提供するstm32f4
: STM32F4マイコンのペリフェラルAPIを提供するpanic-halt
:panic
の挙動を設定する
使い方
- STM32F4DISCOVERYをPCにつなげる。
- ターミナルでOpenOCDを起動する。
- 別のターミナルで、
cargo run
を実行する。
これにより、openocd.gdb
に書かれたコマンドが実行される。
つまり、マイコンにLチカプログラムが書き込まれ、デバッガが起動する。
もし、STM32F4DISCOVERYのリセットボタン(黒いタクトスイッチ)を押したならば、4つのLEDが全て約1秒周期で点滅する。
次回は…
これで、「RustでLチカする」という目標は達成できた。 しかし、なぜLチカするのか?は明らかになっていない。 したがって、現在、ライブラリを読んで動作原理の理解に努めている。 同時に、Rustの機能や文法なども学んでいる。
次回はこの「なぜLチカするのか?」への問いに答えたい。