💨

Wio TerminalでRustでWi-Fiを使えるようになりたい(未完成)

2022/12/11に公開

これはモダン言語によるベアメタル組込み開発 Advent Calendar 2022 11日目の記事です

組込み開発の新しい選択肢として注目されているRustですが、昨年出版された基礎から学ぶ 組込みRustではWio Terminalというマイコンモジュールを利用して、Rustでの組込み開発を体験することができます。

https://wiki.seeedstudio.com/jp/Wio-Terminal-Getting-Started/

このマイコンモジュールは今年自分が出版した本Rustで始める自作組込みOS入門でも利用しています(宣伝)。

さて、このWio Terminalは無線のモジュールも積んでいて、Arduino向けにはHTTPで通信したりWeb Serverを構築する例が紹介されています。

https://wiki.seeedstudio.com/Wio-Terminal-Advanced-Wi-Fi/

Rustで開発する場合はArduinoのライブラリは使えないので、純Rust製ライブラリであるwio-terminalクレートを使うのが現状だともっとも楽な選択肢です。

https://crates.io/crates/wio-terminal

現在最新版はv0.6.1となっています。こちらを利用すればArduino同様に簡単にWi-Fiをつかってワイファイできます…と言いたいところですが、残念ながら実装がまだ不完全な状態で、無線モジュールの機能をフルに使うことができません。

目標としてはこのライブラリに手を加えてローカルホストのサーバーにTCP/IPで通信くらいはできないかな…とか思ったのですが、時間がとても足りなかったのでこのWi-Fiモジュールの仕組みを簡単に説明して、どのようにすればWio TerminalのWi-Fiでワイファイできるかの展望について解説しようと思います。

Wio Terminalの内蔵無線モジュール

Wio TerminalにはRealtek RTL8720DNというモジュールが内蔵されていて、これを利用することでWi-FiやBluetooth Low Energy(BLE)が使えます。
無線モジュールとコアのCPUはeRPCという方式でシリアル通信することでその機能を利用することができます。

https://github.com/EmbeddedRPC/erpc

無線モジュールには専用のファームウェアが入っていて、eRPCのサーバーとして機能しています。lwIPという組込み向けの軽量のネットワーク通信ライブラリが使われているようで、このモジュール内でDHCPクライアントやmDNSサーバーなどの機能が提供されています。

モジュールの中でかなりの機能が提供されているのでこちら側で開発する機能はかなり少なくて済むはずなのですが、これらの機能をどう利用すればいいのかのeRPCのプロトコルについてのドキュメントが存在しておらず、これらをなんとかして解読する必要があります。
幸い無線モジュール用のファームウェア自体はオープンソースになっていて、そちらでプロトコルの定義ファイルも存在しているので、へそに力を込めればなんとかどういう機能があるかはかろうじてわかります。

https://github.com/Seeed-Studio/seeed-ambd-firmware

また、Arduinoライブラリもソースは公開されているのでそれらも参考になる資料です。
eRPCをどのように使っているかはrpcUnifiedを、その上でWi-Fiの機能を使いやすくまとめたのがrpcWiFiです。

wio-terminalクレートの現状

eRPC通信はUARTモジュールを介して行われています。通信量が多いのでDMAモジュールを使った形式で通信することになります。
これらのモジュール用のクレートはすでに実装が終わっています。しかし、実際に使うeRPCのリクエストとレスポンスの型への定義がまだ完了していない状態です。
特にlwIP関連の機能の部分が全く出来上がっていない状態です。eRPCの定義はこちらです。

https://github.com/twitchyliquid64/seeed-erpc-rs

これらのeRPCの定義を終わらせた上で、それらをいい感じに使うラッパがwio_termianl側に実装される必要がないと使うのは難しいでしょう。
現状だとWifi::connect_to_apが使えて、とりあえずWi-FiにつないでDHCPでIPアドレスを取得するところまでは実装されています。

ところが、最新バージョンである0.6.1では割り込みが発生したところでパニックして終了してしまいます。
一応issueになっていて解決されたことになっているのですが、手元で試したところreleaseビルドでは動いたのですが、debugビルドでは動作しませんでした。

そんなわけで、まだまだHTTPクライアント実装までの道のりはまだまだ長そうです。

その他

Rust以外のモダン言語の選択肢としてtinyGoを使うというものがあります。こちらの方はきちんと実装が終わっています。Rustやその他の言語で実装をする場合は参考になるかもしれません。

https://github.com/tinygo-org/drivers/tree/81bc1bcad1862f719556d3c7ff411c3f56b143dd/rtl8720dn

Discussion