2024/06/16

Embedded Swift Example のビルド (ESP32-C6)

最近は仕事が充実(忙しい)しているので電子工作は全くやってませんでした。

というところで、 WWDC2024 にて Embedded Swift なるものが紹介されてる。。というのを知り合いの facebook の投稿で知る。

Swift だと何がいいのか?うん、よくわからないけど Swift で書いたコードが組み込みマイコンで動かしてみたいじゃないですか。

というわけで Example のビルドに成功したっぽいので、そこまでの軌跡を忘れないようメモしておきます(2024/6/16)。

WWDC2024 のビデオはこちら。各種ドキュメントなどのリンクもまとまってるので便利。
ESP32-C6 のボードを Home app でコントロールできるようにするデモです。
Matter API というのを導入して、Smart Home Network に接続できるようにしてるみたい。

開発環境の導入

対応するマイコンボードはいくつかあるようですが、手元にあるのはラズピコ、ラズピコw なので、まずはラズピコの環境を整えてみました。
結論からいうとビルドの途中でリンク時にこけます。どうやら ** (冪乗かな?)の記述を受け付けないライブラリなのに、コードの中にそういう記述があってリンクできないでこけるようです。最新のツールチェーンでもダメなようなので、ラズピコは諦めて ESP32-C6 の Example のビルドを試みました。

インストール

インストールは Swift の Toolchain とマイコンの SDK を入れる二つの作業が必要です。
うちは M2 MacBook Air なのでそれに合うツールをインストールしていきます。

Swift

https://www.swift.org/install/macos/ から持ってきます。現状は組み込み向けの Toolchain は普通の最新版を持ってきてはダメで、リンク先の main っていうところの Download Toolchain から dev 版をダウンロードしました。pkg なんで、ダブルクリックして開いてインストールします。
それで TOOLCHAINS という環境変数をセットしてあげると dev 版を使えるようになります。
TOOLCHAINS という環境変数に与える値は、
/Library/Developer/Toolchains/swift-DEVELOPMENT-SNAPSHOT-2024-06-13-a.xctoolchain/Info.plist
(バージョンによってパスが異なるので適宜合わせること)の中を見れば書いてあります(正式にはどうやって調べるのかわかりません)。以下の string に囲まれたのが TOOLCHAINSS に与える値です。
<string>org.swift.59202406131a</string>

以下のように指定します。
% TOOLCHAINS=org.swift.59202406131a

すると
% swift --version
で、バージョン確認できます。

% swift --version
Apple Swift version 6.0-dev (LLVM 57177aa1b91540b, Swift 8be62863326595c)
Target: arm64-apple-macosx14.0

ちゃんと 6.0-dev に切り替わってました。
これで Swift は OK。

ESP32C6 SDK

マイコンの SDK を入れます。
こちらの macOS のところを参考にインストールしていきます。
brew は入ってるので、
% brew install cmake ninja dfu-util
% brew install ccache
% mkdir -p ~/esp
% cd ~/esp
% git clone -b v5.2 --recursive https://github.com/espressif/esp-idf.git
% cd ~/esp/esp-idf
% ./install.sh esp32c6
を順に実行していきました。すでに rosetta は有効にしてあったのか、特に問題でなかったので rosetta はインストールしませんでした。
インストールしたツールを有効にするために以下のコマンドを実行します。
% . $HOME/esp/esp-idf/export.sh
これ、小さなドットがあるのに注意。忘れると動きません。

Example のビルド

Example を GitHub からもってきます。
% git clone https://github.com/apple/swift-embedded-examples.git

こちらに ESP32-C6 のビルドの仕方がでているので実行してみます。

% cd esp32-led-strip-sdk
% export TOOLCHAINS=org.swift.59202406131a
% . $IDF_PATH/tools/export.sh
% idf.py set-target esp32c6
% idf.py build

これで特に問題なければいいのですが、自分の場合は libssl.1.1.dylib がないっぽく、export.sh の実行がエラーで中断しました。
以下の Qiita の投稿を参考にインストールしてとりあえず export.sh が少し進みました。

しかしこの先二度ほどひっかかりました。
一つは、
% idf_tools.py install-python-env
を実行する必要があったようです。
あとは、なんだろ、メッセージにこれを実行したら?というのが出てたのでその指示に従ってたので、Error メッセージをよくみて対応してみてください。

以上で、ようやくビルドが成功したっぽいのですが、実機がないので書き込めるのか、実行できるのかは不明です。

実機を秋月から手に入れて書き込んでみたらボード上の LED をランダムに点灯させることに成功しました!LED の繋がってるポートと数が違うので、main/Main.swift の一部を書き換える必要があります。
  let n = 1
  let ledStrip = LedStrip(gpioPin: 8, maxLeds: n)
  // let n = 8
  // let ledStrip = LedStrip(gpioPin: 0, maxLeds: n)
ビルドと書き込みとシリアルモニターをいっぺんにやるには以下のコマンドでOK。ただ、シリアルモニターを有効にすると、どうやって抜けるのかがわからない。。
% idf.py build flash monitor



雑談

Swift ではやはり低レベルなアクセスはできないようで、ベンダーの用意した SDK の API を叩かなければならない。もしくは自前で C/C++ でその部分のコードを書く必要がある。
Example にある BridgingHeader.h をみるに、FreeRTOS.h をインクルードしているところから、結局は FreeRTOS の上で走ってるのねということ。ファーム屋ではないので、何が良くて悪いのかわかりませんが。

あと GPIO を直で叩いてみたいのですが、ライブラリに見つからず。Button/ADC の Read 系ならあるんだけど。また WWDC2024 のデモのコードも置いてあったのでビルドしてみようと思ったら Matter を入れないとだめっぽく、こちらも面倒だなと先に進まず。ちなみにこのデモも簡単な L チカから始まるように見えるんだけど、そもそも乗っかってる LED が GPIO H or L だけでは光ってくれない代物 (WS2812B) なので、同じく led_strip の API を叩いているという。。

とりあえず GPIO H/L と単純に叩きたいー。

(追記) ビデオ最後までちゃんと見るべきでしたね。最後の方に Swift MMIO なるものをチラッと説明してます。リンクもありますね。memory mapped register を直接安全に叩けるとか。これだー。