SSブログ

Raspberry Pi開発をSwift化したい [Raspberry Pi]

今年OPIEでやったデモを来年のPhotonics Westでもやろうということになった。もうあと3ヶ月しかない。OPIEでやったデモのセットアップはデータ取り用のバラックをそのまま持ち込んだ。会場までの行き帰りは車で、僕が膝の上にバラックを抱いて運んだ。それでもしょせんは実験用なのでいろいろなところが壊れてしまった。

Photonics Westへはちゃんと梱包したとしても、航空貨物になるので開けたらバラバラで現地で組み立て直し、ということになりかねない。バラックの方は時間さえあれば組み立てられるけど、僕がはんだ付けした基板が壊れたら現地対応はほとんど不可能になってしまう。

そもそもデモでは合計6本の半導体レーザをアナログ変調しながら点灯させることになって、それぞれに汎用のレーザドライバ(例えばこんなの)を繋いでいたら大げさになってしまうので、僕が回路設計してはんだ付けした基板にRaspberry Piから制御するようにした。レーザドライバ基板ごとにRaspberry Piがついたのでそれでもけっこう大げさになった。OPIEでは裸の基板をスタックしてアクリルカバーを被せたんだけど、撤収のときに電源(+5Vと±12Vとレーザに注入するための±7V)が接触して基板2枚を壊してしまった....

というわけで、Photonics West用にヘビーデューティなものを作り直している。離ればなれだった電源とドライバ基板をひとつのゴツめのアルミシャーシに入れて、ひとつのRaspberry Piから全部の基板の制御をして変調までするようにした(基板枚数を増やすと変調周波数の上限が下がってしまうけど、デモには影響が少ない)。回路のうちアナログ部分は同じだけど、レーザのシャントや極性の切り替えなんかのデジタルはひとつのRaspberry PiからできるようにGPIOを使うのではなく、IOエキスパンダを使った。この石はSPIのチップセレクト以外に2ビットのハードウェアアドレス(I2C用のは3ビット)を持っていて基板ごとに1つずつ乗せることができる。

当然それに合わせてソフトも書き換えている。でも似たようなコードを何度もなんども書いているので、これも汎用化したい。いちおうバス->チップ->チャンネルがどう変わっても書き直さなくて済むようにCoreFoundation風の、それぞれがオブジェクトになったマルチインスタンスな書き方にしてある。基板上のEEPROMに回路構成を記述したファイルを置いて、それにしたがってSPIやI2Cなんかのバスごとに専用のThreadを起こしてそこでチップの読み書きだけをすれば、A/D、D/Aの最高スループットで回すことができる。そしてEEPROMの内容は基板に固有なので基板を入れ替えても動作する。でもそれをCで実装するのは非常に煩わしい。

たとえばバス上のチップはDeviceという抽象クラスのサブクラスになってる(Cで書いてるので「のつもり」みたいなもん)けど、Cではポリモーフィズムが表現できないので関数ポインタの配列を書き換えるように書いたり、ループの底で高速に要素を参照したい小さな可変配列は、自分でリンクトリストを実装している。30年前ならアルゴリズムが分かっていれば自分で実装するというのは当たり前だったが、今ではそんなことをしなくてもなんでもある。

しかしRaspbianとmacOS共通で使えるものというとあまりない。macOS側にGObjectを導入すればいいんだけど、いらないいろんなものまでいっぱいついてくる(というよりGObjectをなぜかあまり好きではない、というほうが大きいかも。ちなみにmacOSのアプリでバンドルの中にlibgobject.dylibを抱いているのはけっこうある。例えばMathematicaもそのひとつ)。でも結局はGObjectの小さなサブセットを実装しているようなもので、無駄が多い。

なんで両方で同じコードがコンパイルできることにこだわるかというと、ひとつはやはりデバグのため。QEMUなんか(最近の人はDockerを使うのか)のエミュレータも場合によってはいいけど、やはりネイティブにデバグできた方が簡単(ジジイなのであっち行ったりこっちへ来たりするとすぐわからなくなる)。それとRaspberry PiをmacOSのサーバとして動かして、Raspberry Pi側が持っている回路構成をmacOSで知るためにサーバであるRaspberry Piから自分の記述ファイルをまるごと送るようにしている(そうすることによってクライアントであるmacOSではいくつもあるRaspberry Piのどれがどんな回路を持っているかというデータを持つ必要がない)。macOS側でそれを解釈するのはRaspberry Pi側とまったく同じコードでいい。またサーバ-クライアント間の通信にsocketを使っているので、共通部分をなるべく多くした方がデバグは簡単になる。

僕がやってることはSwift+StandardLibrary+POSIXだけで十分カバーできて、その上さっきのリンクトリストみたいな汎用的な部分は辞書や文字列操作なんかも含めて効率的に実装済みで、さらに当然CoreFoundationのマネのようなまわりくどいことをしなくてもいい。CからSwiftにすれば、たぶん記述量は5分の1ぐらいにできるはずである。

ということで、このさいSwiftに統一したい。macOSはもちろん、Raspberry PiネイティブにはSwift for ARMが非常にお手軽なのを作ってくれていて、すでにRaspbianでREPLを除いてSwift5がちゃんと動く。IDEとしてはこれまで使っていたEclipseではなくVisual Studio Codeにしたい。RaspbianとmacOSの両方で動いて、Eclipseよりは動作が軽くてRaspbian上ではまだマシである(busterではうまく動かないみたいだけど)。ちゃんと整備できれば両方で同じ環境ができるはずである。あとはmacOS側でarmhfへのSwiftクロスコンパイルができれば(リンカはbinutilsで、その他のtool-chainはSwift for ARMのが使えたとして)いいんだけど、そうなってくるとまだよくわからない。LLDBのコマンドも覚えないとけない。

そうやって徐々にRaspberry Pi用のSwift開発環境を整えたい。先は長いけど。

しかし僕はいつまでこんなことをやるんだろう。自分の残り時間以内にできるんだろうか。
nice!(0)  コメント(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。