chakokuのブログ(rev4)

テック・コミック・ごくまれにチャリ

TinyGoをRPi Pico上で動作させたい->LチカまではOK

背景:これまで組み込み用プログラミングではMicroPythonで緩くやってきた(とにかく楽なので)
課題:本屋でTinyGoの本を見つけて、言語仕様がコンパクトでコンパイル型言語(LLVM)ということで使ってみたくなった。MQTT等のライブラリもあるそうだ。RPiPico上でTinyGoを走らせて、ポーリング性能を測ったり、Lチカ等をやってみたい
取り組み:まずはWindows環境にTinyGoの開発環境を構築
結果:環境構築、Lチカまで行えた(トラブルなしに1時間程度で完了)

詳細:
まずGoをインストールする必要がある。Go 1.19.4をDL、Windows環境にインストール
Downloads - The Go Programming Language
次に、TinyGo binaryをDLしてパスを通す。
自分は普段Cygwin環境を使っていて、パスを通すと以下のように動作する。

$ tinygo version
tinygo version 0.26.0 windows/amd64 (using go version go1.19.4 and LLVM version
14.0.0)

試しにビルドしてみる。tinygoのZIP一式の中にサンプルコード集があり、LED点滅サンプルが入っているのでそれを使う。
file: cat blinky1.go

package main
// This is the most minimal blinky example and should run almost everywhere.
import (
        "machine"
        "time"
)
func main() {
        led := machine.LED
        led.Configure(machine.PinConfig{Mode: machine.PinOutput})
        for {
                led.Low()
                time.Sleep(time.Millisecond * 500)

                led.High()
                time.Sleep(time.Millisecond * 500)
        }
}

本に倣って、targetをwioterminalとしてビルドしてみる。。バイナリが生成されるまで結構時間がかかる。裏側で何パスも走っているからだろうか。。 多分RPi Pico用にtargetを変える必要があると思われる。

$ tinygo.exe build -o blink.uf2 -target wioterminal -size short blinky1.go
   code    data     bss |   flash     ram
   7396     108    6280 |    7504    6388

targetオプションは pico とする必要がありそうだ。あと、、picoのLEDってややこしかった記憶が。。その辺も吸収してくれるのか??
Raspberry Pi Pico | TinyGo
pico用にビルド実施

$ tinygo.exe build -o blink.uf2 -target pico -size short blinky1.go
   code    data     bss |   flash     ram
   8104     108    2880 |    8212    2988

uf2形式でファイルはできた。これをそのままpicoにDrug&Dropしたら動くのだろうか。。あるいは仮想Serialからflashツールで焼くのか?

picoはBOOTボタンを押しながら起動すると仮想ドライブとしてPCから見えるので、UF2形式のバイナリであればDrag&DropでコピーすればFlashに書き込める。ということで、そのようにしてみたが、LEDは点滅せず。暴走しているのか、ピン配置が異なるのか。。自分のボードには、GP15(20番Pin)にLEDを接続しているので、GP15をL/Hしてみる。
Pico用に修正したソースは以下。これをビルドして、Picoに書き込むと、LEDが点滅した。

package main

// This is the most minimal blinky example and should run almost everywhere.

import (
        "machine"
        "time"
)

func main() {
        //led := machine.LED
        led := machine.GP15
        led.Configure(machine.PinConfig{Mode: machine.PinOutput})
        for {
                led.Low()
                time.Sleep(time.Millisecond * 500)

                led.High()
                time.Sleep(time.Millisecond * 500)
        }
}

使ってみようと思って1時間ぐらいで環境構築とLチカまで進めることができた。解説本やTInyGoの公式サイトによる分かりやすい説明も助けになったが、TinyGoのビルド環境やライブラリ群がよく整備されていて使いやすいおかげと思う。また、Picoの場合、仮想ドライブが実現されていて、Flashへの書き込みもDrug&Dropで済み、書き込みツールは不要だ。はまりポイントはほとんどなく、手軽ですばらしいと思う。
ただ、、ビルドに結構時間がかかるのが難点か。自分のPCの性能が低いためかもしれないが。
OpenOCD+GDBによるデバッグ(SWDデバッグ)も可能らしいので、デバッグ環境も整えたい。
■参考URL
Windows | TinyGo
GDB | TinyGo
Windows用 RaspberryPi Pico デバッグ環境(C言語)の作り方(PicoProbe編)
Raspberry Pi Picoをデバッガーで動かす | neocode
https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf#page=19
GitHub - georgerobotics/cyw43-driver

Pico-WのWiFiモジュールは、CYW43439