昔、Arduino Uno(RAM 2KB)でmrubyのバイトコードを走らせた話
背景
最近、生活が落ち着いてきたので、また電子工作やmrubyを触るようになりました。
ここ数年はPicoRubyが一部で盛り上がっており、私も勉強会に参加しつつエンジョイしているところであります。
PicoRubyのすごいところは、Raspberry Pi Picoのような264kBというメモリが少なめの環境でも、マイコン上でmrubyのコードをコンパイルして、実行できるところです。これまでいちいちPCでバイトコードにコンパイルしてマイコンに焼いたりしないといけないところが不要になります。加えてPicoRubyではターミナルで動くShellや、USBストレージまで実装されていて、それもまた使いやすさに大きく貢献してます。
※ちなみに素のmrubyでもESP32のPSRAM(2MBや4MB)付きのものであればマイコン上でコンパイルできます。(Family mrubyの取り組み)
作者の羽角さんと以前、Arduinoでmrubyをなんか動かしたことがある、という話をしたときに、ふつう動かないよね?となったのですが、その時自分でも自分が何をしたのか完全に忘れていたので、それを振り返っておこうかなと思いました。
Arduino Unoで動かすとは?
Arduino UnoはFROM32KB、RAM2KBです。RAMについて言えば、Raspberry Pi Picoの1/100です。
mrubyの小型VMであるmruby/cでも実行時のメモリ40KBとあるので、ふつうに考えて全く動かないのです。

動かすために何をした?
自分の本に詳しく書いてました。2018年の技術書典5で出した同人誌です。

商用本にもなっているので、ブログにはあまり書き残してなかったので、詳細忘れてました…
やったのは以下のようなことです。
- mrubyのバイトコードのうち、対応するものを削る=mrubyの機能を削る
- mruby/cのVM実装をベースに不要な部分を削っていく
- シンボルなど、定数として扱えるものをROMへ割り当てるようにする
- Arduino用プレフィックスが必要になるため、バイトコードファイルを解析して、C言語コードを吐くような、ポストプロセスを実装
- ArduinoIDEでコンパイルでは、8bitマイコンでも、8bit以上の変数を扱えるように対応してくれているので、mruby/cベースのコードもコンパイルできた
とにかくROMに割り当てることで、2KBのメモリには実行時に生成するオブジェクトだけ乗るようにしました。

ROMにシンボルを置いてRAMを節約、という発想の取り組みはmruby本家でも対応されて、presymとして利用されています(私の理解があってれば)。
結果、この挑戦では、簡単なメソッド呼び出しやループくらいは動くようになりました。

コードは以下で公開しています。
このときはmicro mrubyなんて名前をつけてました。
PicoRubyやMicroRubyが存在している現在だと、FemtoRuby とでも呼んだほうがいいのかもしれませんね。
利用してくださった方々
実用性皆無と思ってましたが、ググッてみたら、利用してくださった方がいることを今さら見つけて嬉しかったので、リンクしておきます。


今後のこと
Arduino Unoでバイトコード動かすのはちょっと無理があるので、この件については特に何も展望はないですが、こういう隅っこを攻める開発は頭の体操によいと思います。
最近は、ESP32を2個使って、Family mrubyの進化版を開発してます。