verylowfreqのアイコン画像

[作業メモ] M5StackでRustのコードを実行する (2021-10-01)

verylowfreq 2021年10月01日に作成  (2021年10月01日に更新)

[作業メモ] M5StackでRustのコードを実行する (2021-10-01)

M5Stack (ESP32) でRustコードが動けばとても素敵だと思ったので、そのようにしました。私が調べた範囲では最近の定番の環境構築方法が見当たらなかったので、自己流です。

今回使用するプロジェクトのファイルは以下に置いてあります。
https://github.com/verylowfreq/rust_on_m5stack_example

私はDocker歴もRust歴も1週間くらいなのでベストプラクティスに沿っているかは不明ですが、とりあえず今のところ動いているので、記録しておきます。

なお以下のブログ記事のプロジェクトをがっつり参考・拝借しています(Apache 2.0 License)。
https://kerkour.com/blog/rust-on-esp32/ ( https://github.com/skerkour/kerkour.com/tree/main/2021/rust_on_esp32 )

まだまだ変化が激しい界隈なので、この記事の記述がいつまで有効なのかはわかりませんが、執筆時点では動きましたということで。

この記事は2021年9月30日ごろの記述です。

概要

  • Dockerでビルドツールの環境構築
  • VSCodeで、Rustのコード補完を効かせながらコーディング
  • M5StackのLCDとボタンA,B,Cにアクセス
    • M5Stackボードでの実装状況に合わせてライブラリを修正。(ili9341esp-idf-rustにパッチ当て。)

環境

  • M5Stack Fire
  • 検証PC
    • Windows 10 x86-64, Ryzen 5 3600 (6C12T), RAM 24GB
    • Windows 11 x86-64, Intel Core i5 8250U (4C8T), RAM 16GB
  • Docker Desktop
  • Visual Studio Code

ツールの準備

利用するツール:

  • VSCode : IDE。拡張機能を使って、Docker連携とRust補完を効かせる。
  • Docker Desktop : esp32向けRustのバイナリを含んだイメージを利用。
  • rustup : Rust環境構築ツール。Rustコードをビルドするためではなく、ツールのインストール用。

VSCodeには以下の拡張機能をインストール。

  • Remote Container : Docker連携。
  • rust-analyzer : Rustのガッツリな補完。

バイナリの書き込みや動作確認のツールとして、(rustupのインストール後)、cargoから以下のツールをインストールします。

  • espflash : 書き込みツール
  • espmonitor : シリアルモニタ
cargo install espflash espmonitor

ソースコードの準備

プロジェクトのレポジトリを公開したので、クローンします。

git clone https://github.com/verylowfreq/rust_on_m5stack_example

VSCodeで開く

クローンしたプロジェクトをVSCodeで開くとRemote Container拡張機能が反応して、コンテナ内で開くかと聞いてくるので、提案通りコンテナ内で開きます。
(初回起動はDockerコンテナの準備があるので時間がかかります。数十分くらい?)

準備が整うと、VSCodeのターミナルがDockerコンテナ内のシェルになるはずです。このとき、VSCodeで開いているフォルダがDockerコンテナ内の/workspaces以下にマウントされます。
(初回起動時はVSCodeが必要なツールを自動で配置しますが、完了後にシェルに戻らないっぽいので、新しいターミナルを開くなどして、コンテナ内のシェルに入ります。)

ビルドする

VSCodeのターミナルから、以下を実行します。(コンテナ内で処理が走る。)

cargo build

初回はわりと時間がかかります。10分くらい? ESP-IDF関係のビルドが長いようです。

バイナリを書き込み、動作確認

生成されたバイナリの場所は、プロジェクトフォルダ内の
target/xtensa-esp32-espidf/debug/rust_on_m5stack
となります(拡張子はないけどELFファイル)。

これをホスト上から、
espflash COM3 rust-m5stack-example
などとして書き込みます。(COM3がM5Stackのシリアルポートとすると。)

その後espmonitor COM3を実行すると、シリアルコンソールが開けます(デフォルトではコマンド実行時にM5Stackがリセットされます。オプションで変更可。)

解説

ESP32向けのRust

今のところLLVMとRustの本家にESP32(xtensa)向けのコードがマージされていないため、espressifがフォークしているものを利用します。ツールチェーン丸ごとビルドは大変なので、Dockerイメージを利用しました。
Espressif自身によりDockerイメージはいくつか公開されていますが、今回はespressif/idf-rust-examplesを利用します。

Dockerfile

espressif/idf-rust-exampleをベースに、少しだけパッケージを追加しています。

ライブラリのパッチあて

パッチを当てた改変版のライブラリを参照するようにCargo.tomlで設定しています。

ili9341 :
ILI9341チップの制御ライブラリです。このライブラリ単独で利用するというよりは、embedded-graphicsと併用して、図形やテキストの描画はそちらに任せるかたちになります。
https://github.com/yuri91/ili9341-rs をベースに、M5Stackに必要な画面方向と色の反転の設定ができるようにしました。

esp-idf-hal :
ESP32向けのembedded-halの実装です。embedded-halは組み込み向けのハードウェア抽象化ライブラリです。
esp-idf-halでは、GPIO37とGPIO38の定義がないのですが、M5StackではボタンBとCで利用しているため、この2つの定義を書き加えました。
(BtnA : GPIO39, BtnB : GPIO38, BtnC : GPIO37)

sdkconfigの改変

これを検証している9月30日-10月1日時点で以下の問題が発生していて、ESP-IDFのビルドが通らないので、応急処置として設定を加えています。

# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set
CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y

参考: ESP-IDF Issue 7621 "Generating x509_crt_bundle (IDFGH-5933)" : https://github.com/espressif/esp-idf/issues/7621

雑記

  • Rustらしい書き方をしたい。エラー処理も各所で気まぐれに書いていてバラバラなので、一貫性のある記述にしたい。
  • Espressif提供のDockerイメージはいつまでメンテナンスされるだろうか。
  • Rustの補完が不安定。Dockerコンテナを再起動したり、cargo cleanすると治る場合もある。原因不明。
  • cargo buildldproxyエラーで失敗する場合がある。特にパッケージの依存関係やインポートをいじったとき。cargo cleanで治るけど、その後のビルド時間が長いので、ほかの復旧方法を探したい。
  • espressif/idf-rust-examplesには、/opt以下に2つのサンプルプロジェクトがあり、ひとつはcargoのビルドシステムを用いたもの(私が以前試した限りではビルドが通らず)、もうひとつはidf.pyのビルドシステムを利用するもので、CのコードからRustの関数を呼び出す構造のもの(こちらはビルドできたし動いた)。
ログインしてコメントを投稿する