mruby/cのStringを無効化した状態でUART


mruby/cでStringを無効化することができるようになった。 私が最近いじっているch32funを用いたCH32X035用の環境では、Stringが無いとそのままではI2CやSPIは動かなかったが、 出力はmake_output_bufferでStringを使わないようにして、 入力は文字列を整数の配列に変換することにより、動くようになった。 しかし、入出力ともにStringであるUARTは動かせていなかった。 APIのガイドラインとは異なる仕様になるが、UARTの入出力もI2CやSPIと同様の処理をすれば、String無しでもUARTを使えるようになるはずである。 今回はそのやり方について考えてみたい。

I2CやSPIでは、マイコンはセンサーなどのICと通信し、やり取りされるデータは数値であることが多い。 一方UARTでは、通信相手はPCや別のマイコンで、文字列をやり取りすることも多い。 それゆえに、UARTの入出力でStringを使うようになっているのだろう。 Stringを無効にした場合には、当然Stringは使えないが、Symbolを使えば限定的ではあるが文字列を扱うことができる。 そこで、 make_output_bufferでSymbolも使えるようにして、それをUARTの出力用に使うと良いと考えた。 UARTで出力するときには、通常はStringが引数として与えられるが、make_output_bufferはStringも受け付けることができるので、UARTでも問題無く動作する。 Stringを無効にしたときも考慮して、数値や数値の配列に加えて、Symbolを使って、出力すべきデータを指定するのである。 入力では、それをSymbolに変換することは可能であるが、mruby/cのSymbolには、GCが働かないようなので、様々なデータを受け付けたてSymbolに変換すると、メモリが圧迫されてしまう。 I2CやSPIと同様に、入力されたデータは数値の配列にするしか無いだろう。

Stringを無効にした このような限定的な仕様にしたときに、UARTが何の程度の実用性があるかを、 例えば標準入出力とUARTのコンバーターが作れるかを考えてみよう。 標準入力は、getbyteで数値として受け取るので、それを数値としてUARTで出力すれば良い。 UARTからの入力は、数値の配列となるが、数値はprintfで%cを指定すれば、文字として標準出力に出すことができる。 つまり、Stringが無くても、コンバーターが作れることが分かる。

mruby/cの コンパイルサイズを小さくするには、使わないAPIを組み込まないという方法もあるが、様々な状況に対応して、ソースを書き換えるのは面倒である。 それに対して、FloatやStringを無効にするのは、vm_config.hの中の指定を変更するだけで良い。 CH32X035用の環境では、Floatをすでに無効にしていたが、 さらにStringを無効にすると約10kバイト小さくなり、 String以外のmrblibを組み込んでも、 flashに10k以上の余裕ができる。 それだけあれば、かなり複雑なrubyのプログラムも組み込むことができる。 Stringを使って手軽に小さなプログラムを使う場合と、Stringを使わずに比較的大きなプログラムを作る場合用に、二種類のbinaryを用意しておけば、本体をコンパイルする必要はなく、mrbcだけ作って、binaryと結合して書き込めば良いので、便利だと思う。