search
LoginSignup
8

More than 1 year has passed since last update.

posted at

updated at

PyPortal で TinyGo プログラミングを始めよう

この記事では、以下の環境で Windows 10 環境で TinyGo + Pyportal を試した時のメモをまとめます。

  • Windows 10 Home / Pro 64bit
  • TinyGo 0.14
  • PyPortal

個別に記載しない限りは Windows 10 を対象としたメモであることに注意。
また、基本的には PyPortal (および feather-m4) でしか確認していませんが、他のボードも大差ないと思います。

最初に

メモを書くきっかけ

TinyGo でマイコン遊びをしようと思ったがまとまった情報が少なかった。
基本的には TinyGo 専用ボードというのはないので、書き込み方法含め不明点が多かった。
同僚が Windows 10 + Adafruit Trinket M0 で TinyGo デビューしようとして躓いていた。
ボード毎に異なる部分もあり L チカまですんなり進むようにサポートしたいという思いがあった。

TinyGo とは

マイコンや WASM などの Small Places 向けの Go Compiler です。
ここでは Go の文法でマイコン開発ができるもの、という程度の認識でよいです。

PyPortal とは

Adafruit 社の 3.2 インチカラー液晶タッチディスプレイ (320x240) な IoT ディスプレイマイコンボード。
基本的には Arduino や CircuitPython での開発が想定されているが、 TinyGo でも 0.12 でサポートされた。
ESP-WROOM-32 が搭載されていて Wi-Fi 経由で何かをしたり、等も可能。

マイコンは Microchip 社の ATSAMD51J20 (Arm Cortex-M4 120MHz) が搭載されている。

4116-00.jpeg

TinyGo 対応ボード

オフィシャルで対応が謳われているものについては以下に列挙されている。
AVR / RISC-V / Xtensa / ARM Cortex-M などがサポートされている。
現時点では ARM 系が開発の中心となっているので、新しく買うなら ARM 系のボード (※) で試すのが良いはず。
※ATSAMD21 / ATSAMD51 / nRF51822 / nRF52840 等
※クロックは高め (64MHz 以上) の方が楽に遊べる

あとは、 avr や stm32 などは openocd / jlink 等が使える必要があるので、書き込み用の何かを持っていない人は以下のいずれかが始めやすいと思います。

circuitplay-bluefruit
circuitplay-express
clue_alpha
feather-m0
feather-m4
feather-nrf52840
hifive1b
itsybitsy-m0
itsybitsy-m4
metro-m4-airlift
microbit
pybadge
pygamer
pyportal
reelboard
trinket-m0
wioterminal
xiao

2021/12/31 追記)
以下に画像付きで TinyGo 0.21 時点の対応ボード一覧を記載しました。
ディスプレイがあったり、 LED 沢山なものが個人的にはモチベーション維持しやすいです。

なぜ Pyportal を選んだのか

PIC16F あたり?からデビューした世代なので、楽ができるオールインワンなボードが欲しかったから。

  • 本体だけでそれなりに遊べそう
    • ブレッドボードを使わなくてもいい
  • ネットワークにそのままつながる
  • TinyGo 0.12 で新規サポートされた
  • FOSDEM 2020 (2020/02) のデモ でも使われていた
    • 画面描画部分の TinyGo のソースが手に入る
  • CPU (ATSAMD51) が Adafruit Feather M4 等の他の TinyGo ターゲットでも使われている

とはいえ、好きなのを買うのが良いと思います。
引っかからずに進むためには、ドキュメントが多いボードを使うのが安全です。
引っかかるのも経験だし勉強になるのも、そういう考え方も OK です。

サンプルコード

最初にどういうコードをビルドして試せばよいか悩むと思います。
自分も悩みました。

とりあえず以下を書き込むことで、基板上の LED を点滅させることができます。
動作確認が出来たら、反転周期を切り替えてみる等をしてみると良いです。

以下のソースコードは、 TinyGo のオフィシャルにあるサンプルになります。
PyPortal 環境では、液晶の裏側の赤 LED が machine.LED として設定されています。
他のボードでも動く (ように machine.LED とかがボード毎に設定され続ける) と思います。

ビルド方法と書き込み方法は後述。

package main

import (
    "machine"
    "time"
)

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

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

TinyGo の始め方

TinyGo のインストール

最新版の tinygo.*.windows-amd64.zip をダウンロード&解凍し C:\tinygo 以下に配置します。

その後、環境変数 PATH に C:\tinygo\bin を追加します。

$ set PATH=C:\tinygo\bin;%PATH%%

実際にはファイルの場所はどこでも良いので適宜好きな場所に読み替えても OK です。
とにかく tinygo の実行体 (Windows だと tinygo.exe) に PATH が通ってればよいです。

なお、上記では Windows Native 版を紹介しましたが Docker ベースでも開発可能です。
ただし、特別な理由がない限りは Native 版が良いと思います。

ビルド方法

Windows Native 版の TinyGo を使っても良いですし、 docker 版を使っても良いです。
それぞれの実行方法は以下の通り。

ビルド方法 (Windows Native 版 TinyGo)

tinygo build -o app.uf2 -target pyportal [PATH TO YOUR PROGRAM]

マイコンへの書き込み方

Windows Native 版 TinyGo を使って書き込む

以下の例では、再ビルドしてマイコンへの書き込みまで実施します。

tinygo flash -target=pyportal [PATH TO YOUR PROGRAM]

もしも複数のマイコンを接続している等でうまく書き込みができない場合はポートを指定してください。

tinygo flash -port COM4 -target=pyportal [PATH TO YOUR PROGRAM]

devmgmt.png

マウントされたドライブに *.uf2 ファイルをコピーして書き込む

実行後すぐに crash してしまうようなプログラムを書いてしまった場合は、この方法で復帰できます。

リセットボタンをダブルクリックするとブートローダーにとどまるようになります。

マウントされたドライブに作成した *.uf2 ファイルをコピーすることで書き込みができます。
書き込み後は自動的にリセットして、書き込んだファイルの動作を行います。
例えば以下のようなコマンドで書き込みすることができます。

$ copy app.uf2 D:

参照資料等

マイコンボード毎の TinyGo のドキュメント

以下にあります。

PyPortal については以下にあります。

周辺デバイスのドライバ

TinyGo 全般用として、様々な周辺デバイス用のドライバが以下あります。

例えば PyPortal の液晶は ILI9341 TFT Display なので以下を使うと簡単に画面描画できます。

PyPortal 用のものについてのまとめは以下。

日本語情報リンク

雑多なメモ/困りごと/制限事項など

  • math.Abs() や float64 を返す関数を使うとフリーズする
  • goroutine は LLVM coroutine を使ってエミュレートしている
  • goroutine は GOMAXPROX = 1 時の動きに近い
    • time.Sleep() や chan 操作時などに異なる goroutine に切り替わる
  • Windows 10 だと USB-CDC が動いてなさそう
    • 本来は print() とか println() とかからシリアルポートに書き込める感じ
    • デバイスマネージャーで COM ポートとして認識しない
      • ここが解決したら ResetProcessor() が動くようになってリセットボタンのダブルタップが不要になりそう
    • TinyGo 0.13 で修正されました
  • tinygo flash する時、 taget に従ったファイルが読み込まれる (target/pyportal.json) が、 flash-method が msd なので本当は flash-1200-bsp-reset は false が正しいはず
    • この部分が (少なくとも windows 環境に対しては) 間違っているので公式ドキュメント通りに書き込めず -port 指定が必要となっている
    • flash-1200-bps-reset で boot に遷移させてから msd (uf2 を単にマスストレージデバイスにコピー) でやるのが正しい模様
    • 2020/08/07 追記) Windows および Windows + 非英語圏 では書き込めない問題がありましたが TinyGo 0.14 で修正されました

変更履歴

2020/02/25 追記)
以下の Windows 版 tinygo 0.12 だと PyPortal で float 演算をしようとするとフリーズする。
現時点では docker の tinygo/tinygo-dev を使用する事で回避できる。
以下の本文中の記載は、随時 tinygo/tinygo-dev での確認結果をベースとしたものに書き換えていきます。

  • tinygo version 0.12.0 windows/amd64 (using go version go1.13.1)

2020/04/16 追記)
tinygo 0.13 がリリースされましたが、 Windows 版では SAM D5x マイコンで float 演算をしようとするとフリーズする。
今の所は、 docker の tinygo/tinygo-dev (0.13 ベースになっています) を使うと回避できます。
Windows で SAM D5x マイコンを使っている場合は、当面は docker ベースで開発を続ける必要があります。

2020/05/04 追記)
以下について記載を追加

  • ESP-WROOM-32 : WiFi
  • 8MB flash
  • plugin ports for I2C
  • 2 x analog/digital pins

2020/05/22 追記)
雑多なメモに、 windows 版 tinygo で FPU を使ったときにフリーズする問題への対策を記載。
plug-in ports for I2C の使用例を追記。

2020/05/23 追記)
各所に Windows 版の TinyGo で SAMD5x CPU の浮動小数点演算でクラッシュする問題への対策 へのリンクを追記。
マイコンへの書き込み方 2 を追加。
TinyGo 対応ボード に、デバッガ等が無くても導入可能なボード一覧を追記。
変更履歴 (のうち古いもの) を末尾に移動。

2020/06/08 追記)
浮動小数点演算を使うとクラッシュする問題については、 FPU を使わない側に明示的に指定する変更が入りました。
0.14 に含まれるのでリリースされた後は普通に使用できるようになります。
FPU を使う側にすると、 goroutine 使用時の stack 使用量が増え切り替えも遅くなるとのこと。

2020/07/19 追記)
microsd の driver を作成した (まだ作成中ですが最低限動作する) のでリンクを追加。

docker 関連の記述のバックアップ

TinyGo 0.14 では不要かもしれませんが、以下は記録として残します。

ビルドの前準備

2020/08/07 追記)
TinyGo 0.14 は go modules に対応しているため、この手順は必要無いかもしれません。

2020/05/23 追記)
この vendoring の手順は、 docker 版のみに必要な手順です。
windows 版であれば基本的には必要ありません。

ビルドに必要な依存ライブラリ等は事前に vendoring しておきます。
この時の Go は Go1.13 ではなく、また Go1.12 の最新版ではなく少し古めのものである必要があります。
Go 1.14 をインストールしておくと良いです。

その後、開発ディレクトリにて go mod vendor を実行します。

set GO111MODULE=on
go mod init
go mod vendor

正しく実行できると、 import している依存ライブラリが ./vendor 以下に配置されます。
例えばあるプロジェクトだと以下のようになります。
vendor 以下に tinygo.org/x/drivers 以下のファイルが追加されているのが分かります。

./go.mod
./go.sum
./touch.go
./vendor/modules.txt
./vendor/tinygo.org/x/drivers/ili9341/ili9341.go
./vendor/tinygo.org/x/drivers/ili9341/parallel_atsamd51.go
./vendor/tinygo.org/x/drivers/ili9341/README.md
./vendor/tinygo.org/x/drivers/ili9341/registers.go
./vendor/tinygo.org/x/drivers/LICENSE
./vendor/tinygo.org/x/drivers/touch/point.go
./vendor/tinygo.org/x/drivers/touch/resistive/fourwire.go

ビルド方法

Windows Native 版の TinyGo を使っても良いですし、 docker 版を使っても良いです。
それぞれの実行方法は以下の通り。

ビルド方法 (docker 版 tinygo/tinygo)

TinyGo Tutorial - GolangRdyJp に色々記載があるので参照すると良いです。

簡単に書くと以下でビルドします。
Windows 10 Home 等で Docker Toolbox on Windows を使っていて、 Docker Quickstart Terminal (bash) で実行する分には以下が実行可能です。

docker run -it --rm -v $PWD:/go/src/github.com/user/repo \
-w /go/src/github.com/user/repo \
-e GOPATH=/go \
tinygo/tinygo tinygo build -o app.hex -target pyportal .

ただし、 Windows 10 Pro + Docker Desktop + cmd.exe だったりすると以下のようになります。
※カレントディレクトリが %GOAPTH%/src/github/com/user/repo である場合

docker run -it --rm -v %GOPATH%/src/github.com/user/repo:/go/src/github.com/user/repo \
-w /go/src/github.com/user/repo \
-e GOPATH=/go \
tinygo/tinygo tinygo build -o app.hex -target pyportal .

更には、 Docker Toolbox on Windows を使っているけど cmd.exe で実行したい場合は上記だとうまく動かず下記のように実行する必要があります。
試した感じでは Docker Toolbox on Windows の docker の場合は /c/Users のように / 始まりかつ小文字のドライブレターにする必要があります。

docker run -it --rm -v /c/Users/USER/go/src/github.com/user/repo:/go/src/github.com/user/repo \
-w /go/src/github.com/user/repo \
-e GOPATH=/go \
tinygo/tinygo tinygo build -o app.hex -target pyportal .

正直覚えにくいし面倒だと思いましたので、 tinygo-docker というヘルパーコマンドを作りました。
良かったら使ってみてください。
Windows Native 版 TinyGo と限りなく同じやり方で tinygotinygo-docker に変更すればビルドできます。
ただし docker 経由なので flash は出来ません。

tinygo-docker build -o app.uf2 -target pyportal .

tinygo-docker.gif

2020/02/25 追記)
上記では、 tinygo/tinygo を使いましたが、 tinygo/tinygo-dev を指定することで最新の開発版を使うことができます。
手元の環境において Windows TinyGo 0.12 + PyPortal だと float 演算でマイコンがフリーズしてしまいますが、 tinygo/tinygo-dev だと動きました。
以下のようしてビルドを実行します。

docker run -it --rm -v $PWD:/go/src/github.com/user/repo \
-w /go/src/github.com/user/repo \
-e GOPATH=/go \
tinygo/tinygo-dev tinygo build -o app.hex -target pyportal .

tinygo-docker では以下のように設定できます。
引数 --docker-image の位置は tinygo-docker の直後に指定する事。

tinygo-docker --docker-image tinygo/tinygo-dev build -o app.uf2 -target pyportal .

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
8