2年と2ヶ月勤めたGROOVE X株式会社を退職しました(正確には4月13日まで社員で、4月1日からは有給消化)。
理由
会社の業務とは別にやりたいことが次第に大きくなってきて、それが現在の会社の方向性とは違ってきたというのが理由です。もちろん社内での会話とか考察をしばらくやって、数ヶ月考えた上で決断しました。
やりたいことというのはやはり低レイヤーです。入社するときに思っていた「消費者に直接届くハードを作りたい」は目的ではなく手段というのを自覚し、前職のときから好きだった低レイヤーを改めて目的として捉えなおしたというか、そんな感じです。
LOVOTも2018年に比べればありえないくらい安定してますし、そもそもローンチしたし、ということで「後ろ髪を引かれつつ」とかはなく次のステップに突き進めそうな感じです。おおむね前職を出た時と同じような前向きな気持ちで出ていくのでまあ良いんじゃないでしょうか。ここらへんはでなり id:denari01 の金言「逃げで転職をするな」が今回も活きてます。おかげでしっかり考察できました。
やったこと
入る前から宣言していた「低レイヤーをやりたい」をおおむね突き通せました。2018年に入社して最初のタスクだった
- Xilinx UltraScale+ ZynqMPの評価基板でLinuxをブートさせる(Yoctoをビルドするだけに見えるがロジック合成も入れると意外と大変)
にはじまり、
- 評価基板に載るOSを自力でDebianに載せ替える
- チームでDebianを育てて必要なdaemonやらを載せる
- カーネルを改造する・新しくドライバを書く
- FPGAで物理層を生やしてはオシロとにらめっこ
をひたすら繰り返してました。
2018年の夏にZynqMPの載ったカスタムボード(LOVOTの頭の中に入ってるやつの初期版)が上がってきて、生産にGOをかけるため大急ぎで土日でロジックを合成しLinuxをポーティング、ブートしたシリアルを拝めた時の高揚感は忘れられないですね。
そこから2019年の夏ぐらいまではひたすらアナログとデジタルを行き来したり低レイヤーのバグ潰し係として動きつつ、やはりチームで必要な実装をやっていきました。
2019年の夏から冬までは周辺機器のLinuxポーティングとdaemon書きをひたすらやり、2019年末から現在まではもっぱら細かいバグ修正、問題切り分け、ドキュメント書き、引き継ぎをずっとやってました。
低レイヤー以外で特筆すべきは、C拡張を含むPython 2→3移行の話(2018)や、APTとの共存に特化したvenvラッパーを書いた話(2019)のように、Pythonについても随時知見を蓄積し外部発表できたのが良かったです。社長含め全社的に外部発表に寛容なのが助かりました。先日の日経RoboticsのGROOVE X特集にも名を連ね、しかもvenvラッパーの gxenv
の名前も載ったのは超嬉しかったです。もともと厳格にクローズドな環境で開発してたプロダクトなんで、ここまでポートフォリオ的なものが築けるとは思ってなかったのでほんとよかったです。
あと関係ないけど社内バリスタ(笑)を2年間ずっとやってて、ここ1年は特に師の存在もありだいぶペーパードリップの腕も上がりました。
これからやること
これからは、平日の3〜4日程度働き、残りは低レイヤーの興味のあるトピックをちゃんと掘ってちゃんと成果として出す日々になります。
元々は、自分の時間を確保したいという動機から完全フリーになるつもりでした。ところが以前より手伝っていたヘマタイト株式会社でこの話をしていたら、うみさま id:umisama がご厚意で声をかけてくれて、幸いにも時短社員かつリードエンジニアとして雇ってもらえることになりました。やはり正規雇用というのはありがたいもので、国保とか入らなくて済むのが超ありがたいです。
低レイヤー方向のアウトプットとしては、既に電子辞書のSharp Brainのハックが形になりつつあります。これからBrainを通常利用可能なLinux UMPCとして仕上げていこうと思ってるので、他のトピックとともにご期待ください。
Sharp BrainでU-Boot起動→microSDからLinux起動できた!!嬉しすぎる!BrainのWindows CEで必死で遊んでた10年前の自分に教えてやりたい。
— 𝕋𝕒𝕜𝕦𝕞𝕚 𝕊𝕦𝕖𝕕𝕒 (@puhitaku) 2020年3月30日
1: SDをプローブする死闘
2: mmc dev 1でmicroSDを選択し情報表示
3: zImageとDTS読んだ瞬間
4: rootfsが空でinitがないのでpanicする pic.twitter.com/48vVOdvwZg
心に残ったバグ、心に残った開発
ここからはオマケです。とあるエスパー級のエンジニアが語っていた「心に残ったバグ」というのが面白かったので、自分も真似して挙げておきます。情報量が多いので、詳細を知りたい方は直接聞いてくださいw
バグ: 5分〜1時間の幅でランダムにKernel Panicする
対応: SPIの物理層のバッファが小さすぎて異常な頻度の割り込みが起きてたのが問題→バッファを増やして解決
SoC周囲のマイコンと超高速な通信をしているが故の不具合でした。ちなみにXilinx社も未知の問題だったらしく、Forumで報告したら中の人に感謝されました。公式Q&AであるAnswer Recordに登録するとかなんとか。
バグ: USBメモリの読み書きは正常だがマイクやUSB DACをつなぐと音がぶっこわれる
対応: ZynqMPのXHCIホストコントローラをUSB 2.0のみの動作にした時、USB 3.0専用の高速PHYに入れるクロックが生きているとアイソクロナス転送のポーリングレートが正しく生成できなくなるのが問題だった→Device Tree から該当のクロックを消して解決
「えっどういうこと?」と言われそうなわけわからんバグでした。USBメモリのようなバルク転送は通信のペース作りとかないので普通に行けちゃうのですが、音声系デバイスのようなアイソクロナス転送だと厳格なインターバルでポーリングしています。その差が表出していた形になります。
開発: 目のLCDに流す絵をFPGAで力技で生成しGPUの絵と切替えるロジックを組んだ
この実装により、電源投入から目のLCDの描画開始まで10秒〜20秒ほどかかっていたのを、0.5秒ほどに短縮することに成功しました。以下で説明するように、紛れもなく「FPGAでしかできないこと」としてやりがいのある開発でした。
入社した時はまだブートシークエンスへの配慮がまったくなく、電源ボタンを押して十数秒待つと突然目が表示される状態でした。目が真っ暗な状態を0.1秒でも短くするために、FPGAのロジックが読み込まれた瞬間からLCDにLOVOTのロゴを出し、準備が整ったらGPUの絵に切り替える実装をしました。映像信号生成というFPGAの定番ネタに加え、垂直同期に連動したステートマシン付きマルチプレクサを組むという結構な重さ。最終的にLinuxへの結合もできましたし、めちゃくちゃ学びになったと思います。
もちろんロゴ画像を無圧縮でロジックに入れるとデカすぎて入りません。減色して8色3bitのパレットカラーかつRLE圧縮したものをロジックに入れ、描画時にリアルタイムで展開するロジックを書き解決しました。画像のパレットカラー化・圧縮・Verilogコード生成はPythonで全部書きました。
他にも色々ありますが、終わらないのでここまでw