Edited at

組み込みLinuxでGolangのススメ

More than 1 year has passed since last update.

一年近く、組み込み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方式)


実践的な情報

組み込みLinuxで使う上で必要だったことに関して別に記事を書きました。

Golangから物理メモリを読み書きする

Golangでioctlのシステムコールを使う

GolangでGPIOの割り込み通知を受け取る

GolangのプロセスをFIFO priorityにセットする

Golangでシリアルポート(UART)を使う

GolangでBLE (Bluetooth Low Enagy)を使う

Golangでlogのタイムスタンプをマイクロ秒単位にする方法

Golangで周期的に実行するときのパターン


というわけで

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


追記 2018.1.31

参考になりそうなページ

https://github.com/rakyll/go-hardware

http://embd.kidoman.io/