FreeBSD/mrubyのgem


私がFreeBSD上のmrubyで作ったgemの紹介です。どれも100行くらいの小規模なgemです。

mruby-bsdgpio

はじめて作ったgemでGPIOのコントロール用です。

t = BsdGpio.new(0)
t.setflags(1, BsdGpio::OUTPUT)
t.set(1,1)
usleep 1000*1000
t.set(1,0)

LED点灯やスイッチの状態を確認できます。こちらはFreeBSD 11Rから入ったライブラリを使って作りました。

FreeBSDではspiドライバをユーザランドから直接叩く事はできないですが、gpioにつないだspiデバイスであればbitbangでアクセスできます。確認のためにgpioでspiするスクリプトも作ってみました。

mruby-bsdiic

I2Cのコントロール用のgemです。IoTやるやらI2Cもあった方が良いのではと意見をもらったので作ってみました。ioctlで実装してあります。

t = BsdIic.new(0)
p t.read(0x50,2)

リアルタイムクロックサウンドチップの制御してみました。

mruby-etherswitch

ルーターなどのswitchチップを制御するためのetherswitchドライバ経由でswitchチップのレジスタを読み書きするgemです。ioctlで制御していて、etherswitchのヘッダーはまだシステムに入っていないので、ローカルにコピーしてビルドしています。ヘッダーに変更があると動かなくなります。

t = EtherSwitch.new(0)
p t.readreg(0x0509)

etherswitchドライバはetherswitchcfgというコマンドで設定をおこないます。このコマンドでVLANの設定をおこなう事はできますが、mibを拾う機能などはサポートされていません。データシートが公開されているチップであればこのgemを使いレジスタにアクセスしてmibを拾ったり、細かい設定をおこなう事ができます。

mruby-remocon

ビット・トレード・ワンさんのUSB赤外線リモコンモジュールの制御用のgemです。libusbベースのコードを組み込んで実装してあります。

# Sony CD Player Play
play = [0x33, 0x4d, 0x10]

t = Remocon.new()

t.send(play)
usleep 45*1000
t.send(play)

このgemの元になっているソースはLinuxで作られているので、おそらくLinuxでも使えるのではないかと思います。またMac用のコードも組み込んであります。

ビルドについて

これらのgemは全てmipsなルーターに入れて使っています。FreeBSDのカーネルとmrubyを含むrootfsはZRouterというビルドシステムでビルドしています。このビルドシステムはamd64などの普通のホストで実行してクロスコンパイルでターゲット用のバイナリを作ってくれます。gemを利用するためにはmrubyをターゲットに入れてビルドするときに環境変数のMRUBY_CONFIG設定されたbuild_config.rbにgemを追加して、ビルドを実行する事でgemが入ったmrubyが出来上がります。ZRouterでビルドできるシステムはぎりぎり4MのFlashに入りますが、mrubyを入れると1.5MByteくらいの容量が必要になるので最低8MのFlashが必要になります。

最後に

ちょっと気になっているのですがmipsにはビッグエンディアン(mips/mips:Atherosなど)で実行される環境とリトルエンディアン(mips/mipel:Mediatekなど)で実行される環境があります。mrubyの実行が同程度のクロックのSOCでビッグエンディアンの場合、リトルエンディアンの倍くらい遅くなっています。ビルド時になにかおまじないが必要だったりするのでしょうか。

それはさておき、結構この環境が気に入っています。FreeBSDでmrubyも楽しいですよ。