課題:WSLにTinyGoのビルド環境を構築する。動作確認を兼ねてBlinkyをビルドしてPico上で走らせる
結論:TinyGoは入った。PicoでLチカやったがLEDは光らない
取り組み:
当初、WLS上のDockerにTinyGoを入れたが、コンテナ内でコンパイルされても実際何をやってるのか詳細わかりづらく、結局、素のWSLにGoとTinyGoを入れることにした。まぁ環境が汚れると言えば汚れるが、WSLだしまぁええかと。。コンテナで動かせるのは、使い込んだコマンドというのを痛感した。勉強中のコマンドがコンテナ内で動いていてもよく分からん。
まずGoLangが必要だそうで、以下からGoLangをDLして入れる
https://go.dev/dl/ Linux 2.6.32 or later, Intel 64-bit processor go1.21.3.linux-amd64.tar.gz rm -rf /usr/local/go && tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz export PATH=$PATH:/usr/local/go/bin
GoLangを入れた後、TinyGoを入れる
wget https://github.com/tinygo-org/tinygo/releases/download/v0.30.0/tinygo_0.30.0_amd64.deb sudo dpkg -i tinygo_0.30.0_amd64.deb export PATH=$PATH:/usr/local/bin
素で入れるとさすがに手触り感がある。。
/usr/local/go$ tinygo version tinygo version 0.30.0 linux/amd64 (using go version go1.21.3 and LLVM version 16.0.1)
これでTinyGo本の通りに進められそうだ。
今風の知的な言語の場合、パッケージ管理が働くのか、普通にはビルドできそうにない。よく分からん。
~/lang/tgo/hello$ tinygo build -o blink.utf2 -target pico main.go:3:7: missing import path
pico用のライブラリ群が無いと怒られている?*1
再度、go mod initを実行する。確かに、go mod tidyしろとメッセージが出るのでいわれるままにやってみる。
$ go mod init blinky go: creating new go.mod: module blinky go: to add module requirements and sums: go mod tidy $ go mod tidy
やはり、怒られる。これはたぶん、import用のpathが定義されていないからではなかろうか(エラーメッセージそのまま書いてますが)
$ tinygo build -o blink.utf2 -target pico main.go:3:7: missing import path
原因はソースコードの書き方であった。正しくは以下なのだが
import( // 丸かっこ "machine" "time" )
間違って、{ (波かっこ) を使っていた。が、修正してbuildすると、Toggle()が無いと怒られる。なぜなのか。。
Toggleがないなら、自力でLow/Highということで、以下に修正した。これでビルドができた
package main import( "machine" "time" ) func main(){ led := machine.LED led.Configure(machine.PinConfig{Mode: machine.PinOutput}) for{ println("hello world\n"); //led.Toggle() led.High() time.Sleep(100 * time.Millisecond) led.Low() time.Sleep(100 * time.Millisecond) } }
$ cat make.sh #!/bin/sh tinygo build -o hello.uf2 -target pico -size short blinky $ ls -l hello.uf2 -rwxrwxrwx 1 foo bar 16384 Nov 4 00:13 hello.uf2
RPi Picoに焼いてみた。すると、、LEDは光らない。なぜだろう(ポートを間違っている?)。シリアルコンソールにはhelloと表示されるので、プログラム自体は走っているようだ。
仕様書には、GPIO25と書かれている。ここに接続されていない? 確か、Pico-Wの場合、LEDはUSB IFのチップに繋がっているのではなかったか。
Pin Hardware pin Alternative names PWM LED GPIO25 PWM4 (channel B)
次はポートを指定してHigh/LowしてIOから出力されるかを確認する。sleepなしでループさせると、どれぐらいの速度でL/Hできるか性能が分かる。
まとめ
自分の表記ミスだが、ライブラリへのパスが無いのかと誤解してしまった。いったん動くとTinyGoは楽だと思う。組み込みRustも安全な言語でいいのだが、言語仕様の難解さと組み込み用のライブラリ体系がめちゃややこしいのでなかなか手が出せない。TinyGoは試作アプリをさくっと作る分には良いのではなかろうか(WiFiサポートの状況はよく調べる必要あるが)
■追記
なぜTinyGoなのか? ソフトウエアにより1MHzのCLKを生成してMEMSマイクからデータを引き抜きたい。MicroPythonだとWhile文+GPIO操作だけでも9.4us(106KHz)程度なので、性能が一桁オーダ足りない。バッファへの書き込みするとさらに遅くなる。次の手として、ESP32のCで書こうとしたが、RTOSが介在するのかどうもタスクスイッチが入るようだ。だから、CLKが途中で止まる(確かそうだったはず。なぜ不採用にしたか詳細忘れた)。Rustも同様であり、RTOSを使わずにno stdで書く必要がある。 TinyGoだったらRTOSなしで走ってるそうなので、割り込み入らず連続的にCLKとデータ引き抜きができると期待。MEMSマイクネタでは1か月ぐらいぐずぐずとやっているので、TinyGoでMEMSマイクの生データを欠損なく引っこ抜け開発が加速されるのを期待したい。
■追記
Hatena Blogに記事を書くと、過去の関連記事が紹介される。振り返ると昔からTinyGoを使おうとしていたことが思い出されつつ、なぜか途中で使うのをやめている。なぜなのか??多分WiFiサポート状況に起因して、TinyGoの利用をあきらめたと思うのだが。。
Raspberry Pi Pico | TinyGo
過去にもRPi PicoのLED点滅の試作を行っていて、GPIOを修正して動かしたようだ。理由は書かれていないが、オリジナルのままだと動かなったのだろう。
*1:ちなみに出力形式のutf2はuf2の間違い。だが、パーズ?の段階でエラーが出ていて、バイナリを生成するまでは進んでいない