世界を動かす技術を、日本語で。

組み込みシステムとWebAssemblyについて進む

概要

TinyGoは、Go言語を組み込みシステムやWebAssembly(WASM)向けに利用可能にするLLVMベースの新しいコンパイラ。 100種類以上のマイコンボードや産業用プロセッサに対応。 WASMコード生成にも対応し、ブラウザやサーバー、エッジコンピューティング環境でも動作可能。 オープンソースで、GitHubやMastodonでも情報発信。 オンラインでTinyGoを試せるプレイグラウンドも提供。

TinyGoとは

  • Go言語組み込みシステムWebAssembly 向けに動作させるための LLVMベース コンパイラ
  • 100種類以上の マイコンボード産業用プロセッサ への対応
    • 例: BBC micro:bitArduino UnoNordic SemiconductorST Microelectronics
  • WebAssembly(WASM) コードの生成機能
    • ブラウザサーバーエッジコンピューティング 環境での利用
    • WebAssembly System Interface(WASI) ファミリーのインターフェース対応
  • コードサイズ が非常に小さいことが特徴

TinyGoの始め方

  • 公式ウェブサイト から セットアップガイドチュートリアル を参照
  • TinyGo Playground でオンライン実行・試用が可能
  • GitHub でソースコードやドキュメントを公開
  • Mastodon でコミュニティ参加・情報交換が可能

主な利用シーン

  • 組み込みシステム開発
    • マイコンボード を使ったIoTプロトタイピング
  • WebAssembly開発
    • ウェブブラウザ 向けアプリケーション
    • サーバーエッジデバイス 向けの高速・軽量なGoアプリケーション

参考リンク

  • 公式ウェブサイト: TinyGo公式ページ
  • GitHub: 最新コードやIssueトラッキング
  • Mastodon: コミュニティ交流・最新情報
  • TinyGo Playground: オンラインでのコード実行環境

Hackerたちの意見

Tinygoは年々進化してるね。最近はmacOSのサポートも始めたし!確かに、macOS用のバイナリもかなり小さくなるよ。 yuriy@MacBookAir ~/t/tinygo> time tinygo build -o test-tiny main.go


実行時間: 1.06秒 fish外部 usr 時間: 1.18秒 0.31ミリ秒 sys 時間: 0.18秒 1.50ミリ秒 0.18秒 yuriy@MacBookAir ~/t/tinygo> time go build -o test-normal main.go


実行時間: 75.79ミリ秒 fish外部 usr 時間: 64.06ミリ秒 0.41ミリ秒 63.64ミリ秒 sys 時間: 96.76ミリ秒 1.75ミリ秒 95.01ミリ秒 yuriy@MacBookAir ~/t/tinygo> ll 合計 5096 -rw-r--r--@ 1 yuriy staff 74B 3 Apr 19:17 main.go -rwxr-xr-x@ 1 yuriy staff 2.3M 3 Apr 19:18 test-normal* -rwxr-xr-x@ 1 yuriy staff 192K 3 Apr 19:18 test-tiny* yuriy@MacBookAir ~/t/tinygo> cat main.go package main import "fmt" func main() { fmt.Printf("Hello world!\n") }

-ldflags=“-s -w”を渡すとどうなるの?

非同期対応のプログラミング言語で組み込みコードを書くのは素晴らしいね(Rustのembassyを見てみて)。でも、マイクロコントローラーで大量のデータを送る必要があるとき、どれだけ競争力があるのか気になるな。リアルタイムな処理には向いてないと思うけど。

tinygoではGCを無効にできるから、必要なバッファを事前に割り当てれば、リアルタイム特性で良いパフォーマンスが出せるよ。ただ、動的メモリ割り当てが必要なら無理だね。GCが必要だから、リアルタイム保証はできないよ。

RSTPカメラのフィードをWASMプラグインとホストブリッジアダプターを通してストリーミングしてるけど、問題ないよ。正直、こんなにうまくいくとは思わなかった。

EmbeddedGoのために結構な量のコードを書いたよ。メインループでヒープ割り当てを避ければ、ガベージコレクターは問題にならない。ただ、CPUがボトルネックになると、ゴルーチンが他の処理をかなりの時間ブロックするかもしれない。プラットフォームが非同期プリエンプションをサポートしていれば、リアルタイム機能を持つゴルーチンスケジューラーをパッチできるかも。

これについて詳しく教えてもらえる?割り込みやDMAのシグナルとはどう違うのか気になる。ハードウェアレベルの非同期は理解できるし、データシートも読める。でも、ソフトウェアの非同期は特定するのが難しそうで、ちょっと怖気づいてるんだ。

Rustよりはパフォーマンスがいいけど、GCが重くない処理ではZigには劣るね。 https://github.com/tinygo-org/tinybench

私たちはServiceRadarのWASMプラグインシステムにTinyGoとWazeroランタイムを使ってる。Golangを使ってるなら、どちらもおすすめだよ。

やった!wazeroのメンテナーだよ、紹介してくれてありがとう!

Wazeroは最高だね。Go以外の言語に埋め込みたい人は、Extismもチェックしてみて!

標準のGoと比べて、どんなトレードオフがあるの?

毎回リリースごとに良くなってるけど、欠けてる言語機能があるね。 https://tinygo.org/docs/reference/lang-support/ それに、動かない標準ライブラリの部分もある。 https://tinygo.org/docs/reference/lang-support/stdlib/

TinyGoにはWASIでのネットワーキングがないし、WASMのウェブソケットモジュールは5年前に最後の更新があったよ。標準ライブラリなしのGoはGoじゃない。 [0] https://github.com/tinygo-org/tinygo/issues/4880 [1] https://github.com/Nerzal/tinywebsocket

組み込みシステムについては、https://github.com/tinygo-org/net を見てみて。WASIについてはWASI Preview 2をチェックしてみて。 https://docs.wasmtime.dev/api/wasmtime_wasi/p2/index.html

面白いことに、CやC++の人たちにとって、標準ライブラリなしの組み込み用のコンパイラ特有の方言について、まだ議論が続いてるみたいだね。

TinyGoでtailscaleをコンパイルしてopenwrtで動かせるかな?前にチェックしたときは、tailscaleが8MBのフラッシュルーターには大きすぎたんだよね。

TinyGoの標準ライブラリ、特にnetやcryptoは、コンパイルできないか、コンパイルできても実装がスタブで「未実装」でパニックになることが多いよ。数年前に小さなターミナルHTTPクライアントアプリをコンパイルしようとしたけど、コンパイル段階で失敗した。 https://tinygo.org/docs/reference/lang-support/stdlib/

ESP32に対応してるの?

フルリストはこちらにあるよ: https://tinygo.org/docs/reference/microcontrollers/ いくつかESP32も載ってる。

素晴らしいプロジェクトだけど、今はほとんど活動してない感じ。数週間前に小さなPRを出したんだけど、レビューはされたのにマージされてない。もう一つのパッチはまだ出してないけど、先に前のPRを完了させたいんだ。どちらも自分がハマったバグで、かなりの時間を無駄にしてしまった。1. go:embedは「all:<pattern」をサポートしてるのに、tinygoはそれを無視しちゃう。embedfsでファイルが表示されない理由を探るのに頭を抱えたよ。PRは保留中。2. goではビルドCLIでいくつかのグローバル変数を設定できる(ビルドバージョンやタグなどを考えてみて)。コード内でデフォルトを定義して、CLIで提供された値(あれば)がビルド時にそれを上書きできるんだけど、tinygoはコード内でデフォルト値が設定されてる場合、ビルド時にその値を上書きできないんだ。このPRはまだ出してないけど、もっと手間がかかるから。早く再び活気が戻るといいな。組み込みやCFワーカーでgoを使うのが好きだし、tinygoは通常のgoよりもこれらのユースケースをずっと実現可能にしてくれる。正直、tinygoがメインのgoツールチェーンに「ターゲットアーキテクチャ」として統合されることを願ってる。

コミット履歴を見ると、結構活発みたいだね: https://github.com/tinygo-org/tinygo/commits/dev/ もしかしたら、メンテナが圧倒されてるのかも?

先週だけで4人のコミッターがいたから、活発だよ!gophers.slack.comの#tinygo-devのSlackチャンネルに参加して、PRについて彼らに連絡してみて!

TinyGoはhttps://github.com/rcarmo/go-rdpを動かすのに重要だったよ。すごくタイトで、高パフォーマンスなWASMを生成してくれて、それのおかげでRDPのデコーディングをブラウザ側に押し込むことができたし、ちゃんとしたテストスイートも持てた。心からおすすめ。