ch32x035でmrubyc-arduinoを動かす


ch32v203をmrubyc-arduinoから動かすことが出来たので、ch32x035でも出来るだろうと思って、やってみた。 しかし、両者には二つの大きな違いがあることが判明した。 一つは、flashの容量がch32v203が64kなのに対して、ch32x035は少し小さくて62kであることである。 2kぐらいは、工夫すればなんとかなるだろうと予想した。 もう一つの大きな違いが、ch32v203にあった隠しflashがch32x035には無いということである。 mrbのコードを隠しflashに置くことによって、flashが節約できる上に、後からそこだけを書き換えるという使い方が出来たのだが、ch32x035では同じことが出来無い。 これらを以下のように対応して、ch32x035でも、Arduinoを使ってmruby/cから制御できるようになった。

まず、ch32v203と同様に、vm_config.hの設定は、以下のようにした。

#define MAX_VM_COUNT 1
#define MRBC_USE_FLOAT 0
#define MRBC_REQUIRE_32BIT_ALIGNMENT

最適化はsmallest+LTOとしてコンパイルすると、digital,adc,pwmを組込んだ状態で、ギリギリflashには収まるようになったが、mrb用の領域や今後の拡張も考えると、もう少し工夫したい。

そこで、昨日のブログに書いたように、同時に一つのmrbしか動かさないことにして、rrt0をいじってみた。 rrt0.hは、MRBC_TASK_NAME_LENとmrbc_tcbとmrbc_initの部分だけを残した。 rrt0.cは、c_sleepやc_sleep_msからはarduinoのdelayを呼び出すようにして、mrbc_initは以下のように最低限のコマンドだけにした。

void mrbc_init(void *heap_ptr, unsigned int size)
{
  hal_init();
  mrbc_init_alloc(heap_ptr, size);
  mrbc_init_global();
  mrbc_init_class();
  mrbc_define_method(0, 0, "sleep", c_sleep);
  mrbc_define_method(0, 0, "sleep_ms", c_sleep_ms);
}

そして、_autogen_class_rrt0.hは削除した。 mrbのコードを走らせるコマンドは、以下のコマンドの替わりに、mrbc_run_mrblibを用いた。

  mrbc_create_task( MRB_CODE_ADRS, 0 );
  mrbc_run();

これで、一つのタスクしか動かせなくなったが、3kほど容量に余裕ができた。

mrbのコードは、余っているflashに置くことになるのだが、Arduinoには組み込まないようにしたい。 また、ch32x035ではUSBからのプログラムの書き込みが出来るので、それを使いたい。 これらの要請を、どのようにしたら実現できるかを考えていたが、以下のようにすれば可能となることに気が付いた。 まず、mrbのコードはスケッチには組み込まずに、例えば以下のように指定して、コンパイルしたバイナリを出力する。

  mrbc_run_mrblib( 0x8000000+57976 );

そして、そのbinファイルのバイトサイズを先の+以降に指定して、もう一度コンパイルする。 binのサイズが変っていないことを確認する。 もしbinのサイズが変ったら、変らなくなるまでこれを繰り返す。 この直後にmrbのコードを置けば、それが実行される仕組みである。 そのために、実行したいrubyスクリプトを用意して、mrbcで処理してできたmrbをbinファイルと結合する。

mrbc test.rb
cat ch32.ino.CH32X035G8U.bin test.mrb >test.bin

これをflashに書き込めば良いのである。 USBの書き込みは、wchispを用いたが、最初はverifyに失敗して苦労したが、何度も書き込んだらうまく行った。 ch32x035ボードを使ったのだが、書き込みモードにするためにBOOTボタンを押しながらUSBに接続して、すぐに以下のコマンドを実行する。

sudo ./wchisp flash test.bin

udevの設定が面倒なので、sudoを使った。 書き込む時にUSBを抜き差ししないといけないのが面倒だが、追加のハードウェアが不要で、arduinoでのコンパイルも最初だけという、一応納得できる感じにはなった。

ch32x035のマイコンボードは、amazonで400円ぼどで売られている。 マルチタスク機能は削除したが、それ以外の機能が使える形でmruby/cを動かせるマイコンとしては、これが最も安いものの一つでは無いかと思う。 価格的には、RP2040zeroもかなり安くなってきているし高性能なので、mruby/cを動かすマイコンとしては、RPが今後の主流になって来るのかな。 個人的には、装置の制御用に5Vの信号を出せるマイコンをmruby/cで使いたいんだけど、最近mrubyc-arduinoで使ったマイコンはどれも3.3Vだな。