一年近く、組み込み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を使っていきたいと思います。