組み込みLinuxでGolangのススメ

一年近く、組み込みLinuxでのユーザープロセスをgolangで書くことを試していたのですが、これはいける! という感触を持ちました。
仲間を増やしたいと思うので、ここにその情報を紹介します。

#何をしたか
既存の製品をベースにして、新機能の実装をGolangで書いてみました。
既存の部分はCで書いてあります。Golangで書いた新機能部分は別プロセスになっています。
既存部分とのやりとりは場面によって以下を使い分けました。

- cgoによる関数呼び出し
- UNIXドメインソケットの通信
- シグナル

Golangで書いた部分には以下の要素を含みます。

- UARTやi2cで接続されたセンサーからデータを受け取る
- インターネット上のWebサービスのAPIを使用する
- 2Dグラフィックスの描画 (cairoを使用)

最大性能を目指すよりも、十分な性能を手早く形にすることを重視しました。

#Golangでよかったところ
 (私の感想です。)

- mmapやioctlのシステムコールを扱うことができる。これで低レベルの部分までcgoに頼らずに直接Golangで記述できた。
- goroutineを使った非同期処理が非常に簡潔に書ける。
- GCによるメモリ管理があること。GCによる遅延は問題にはならなかった。
- PC Linuxで部分的に動作確認したコードを実機(ARM Linux)に持って行くのが楽であった。
- シミュレータやデータ変換などの周辺ツールもGolangで書くのが楽であった。
- 意味不明のクラッシュが発生することがなく、デバッガは不要だった。(例えば、sliceの範囲を超えたときにはpanicになってスタックトレースが出力される)

- cgoでCの関数を呼ぶのも容易。
- 有用なライブラリが豊富。
- 既存ライブラリのGolang bindingも多い。(cairoのgo bindingを使用した)

#Golangで困ったところ

うまいやり方がわからずに迷ったことはありましたが、そんなに困ったことはありませんでした。
強いてあげれば

- 実行ファイルのサイズが大きい。

これの対策を別の記事に書きました。
[Golangの実行ファイルを複数まとめてトータルのファイルサイズを減らす工夫(busybox方式)](https://qiita.com/tetsu_koba/items/53d84286ba5d87de607a)

#実践的な情報
組み込みLinuxで使う上で必要だったことに関して別に記事を書きました。
[Golangから物理メモリを読み書きする](https://qiita.com/tetsu_koba/items/dba170bf220c45781428)
[Golangでioctlのシステムコールを使う](https://qiita.com/tetsu_koba/items/decee4d1a6ff621a7d37)
[GolangでGPIOの割り込み通知を受け取る](https://qiita.com/tetsu_koba/items/1928730136736c9dd133)
[GolangのプロセスをFIFO priorityにセットする](https://qiita.com/tetsu_koba/items/1ccca9b3f4bd1e6b7f5c)
[Golangでシリアルポート(UART)を使う](https://qiita.com/tetsu_koba/items/f8afbb8326ee42fd27f5)
[GolangでBLE (Bluetooth Low Enagy)を使う](https://qiita.com/tetsu_koba/items/7d8f2f40e45e1549a6fa)
[Golangでlogのタイムスタンプをマイクロ秒単位にする方法](https://qiita.com/tetsu_koba/items/8401f99a39c9757fcff1)
[Golangで周期的に実行するときのパターン](https://qiita.com/tetsu_koba/items/1599408f537cb513b250)

#というわけで
これからも積極的にGolangを使っていきたいと思います。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">私はGCのある言語は好き派。大昔の携帯Javaの頃はGCでの動作停止時間がかなり気になったものだけど、現在のgolangでは私の用途ではGCの停止時間はほとんど感じられないほど小さい。</p>&mdash; 組み込みの人。 (@tetsu_koba) <a href="https://twitter.com/tetsu_koba/status/953461473631551488?ref_src=twsrc%5Etfw">2018年1月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">GolangはOS無しのマイコンでは動かせない。(実験的なプロジェクトはあるみたいだけど。) LinuxがあればOK。ラズパイとかナノパイとか。</p>&mdash; 組み込みの人。 (@tetsu_koba) <a href="https://twitter.com/tetsu_koba/status/953468291258892288?ref_src=twsrc%5Etfw">2018年1月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">OS無し(ベアメタル)の環境に何かの言語のランタイムを実装するのって難しくて、誰にでもできることじゃない。Golangの場合はLinuxカーネル(あるはBSD)さえあれば、「ランタイムを実装する」手間が一切無いのが好き。</p>&mdash; 組み込みの人。 (@tetsu_koba) <a href="https://twitter.com/tetsu_koba/status/953470686466539526?ref_src=twsrc%5Etfw">2018年1月17日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#追記 2018.1.31

参考になりそうなページ
https://github.com/rakyll/go-hardware
http://embd.kidoman.io/

#追記 2022.4.12
こちらの記事に講演した時のスライドとビデオがあります。
[「組み込みLinuxでのGolangのススメ」を講演しました](https://qiita.com/tetsu_koba/items/3dec876f8bb4ef3eb9b3)