mrubyc_arduinoでのflashの節約


mrubyc_arduinoを小さなflashやメモリのマイコンで動かすために、どのようにすれば良いかを考えている。 GPIO, ADC, PWMを組み込んだ状態で、例えばボードとしてArduino Nano Everyを指定してコンパイルすると、flashが35kほどオーバーする。 この条件のもとで、 最低限のrubyの機能を残した上で、必要なflashのサイズを減らそうと試みてみた。

2026/4/15の記事で書いたように、適切な修正をして、vm_config.hで以下のようにFloatを無効にすると、 5.5kほど削減できる。

MRBC_USE_FLOAT 0

また、debug機能が有効になっているようなので、vm_config.hで以下のようにすると、さらに2kほど減少する。

//#define MRBC_DEBUG

NDEBUGを定義しても同じ効果が現れるのかと思ったが、この定数は特殊な意味を持つようで、逆に大きくなってしまった。

methodを使えるようにするために、プログラムが大きくなるので、最低限のmethodだけを残して、残りのmethodを消せば、さらに小さくできるはずである。 そのためには、_autogen_class_*.hの中のmethod_symbols_*とmethod_functions_*の一部をコメントアウトすると、対応するmethodだけを無効にできる。 array,hash,range,string,rrt0について、多くのmethodを無効にしたら、さらに15kほど減少した。

あと12kぐらい減らせば、Arduino Nano Everyのflashに収まる。 上記に加えてできそうな工夫としては、 objectの不要なmethodの削除や、 taskは一つしか走らせない前提でのrrt0.cの関数の簡略化などが試せるだろう。 flashが少し大きいch32v203などでは、上記の工夫でなんとかflashに入るかも知れないので、いつか試してみたい。

ソースを眺めていて感じたのだが、rubyでは同じ機能のmethodに複数の名前があるのだが、これはマイコンにとっては無駄になっている。 例えば、Arrayの要素数を求めるmethodには、count, size, lengthの三つが定義されている。 mrbcでコンパイルする際にこれらをsizeに統一してしまって、マイコンにはsizeのみを定義するようにすれば、多少ではあるが、無駄が減るように思う。 また、"%d,%d\n"%[a,b]という表現も、mrbcでprintf("%d,%d\n",a,b)に変換するようにすれば、マイコンへの負荷を変えずに、rubyの表現が広がる気がするけど、難しいかな。

2026/4/19追記 使わないであろうmethodを削って、flashの使用量を減らそうとしていたが、おそらくこれはうまくいかないことが判明した。 mrblib.cでmrubyのコードが定義されており、この中で使っているmethodを消してしまうと、エラーが生じる。 例えば、empty?なんかは使わないと思っていたが、消したら駄目のようだ。 または、mrblib.cも同時にいじる必要がある。