UIAPduino用のArduino環境の改良


先週末は,三連休で時間があったので,最近構築しているch32funをベースにしたUIAPduino用のArduino環境をいじっていた. いくつかの進展があったので,私の目標とするところまでかなり近付いたように思う.

まず,Arduinoでコンパイルする際のやり方が書いてあるplatform.txtを全面的に見直した. 少しいじると,すぐにエラーが出ることが多く,これまでは必要になる度に,最低限の修正を加えるということを繰り返して來たために,見通しが悪くなってしまっていた. Arduinoのコンパイルでは,recipe.c.o.patternなどに基づいてC言語,C++,機械語のソースをそれぞれコンパイルして,recipe.c.combine.patternに基づいて リンクが行われる. そこに与えるオプションを,ボードの種類などによって変えられるようにするのだが,共通のオプションを使っている部分はまとめたりして,見た目をすっきりとさせた. さらに,オプションの意味を調べて,削除したり追加したりもした. その際,ch32funではch32fun.mkにコンパイルのやり方が書いてあるので,そのオプションも参考にした. 最終的なコンパイルサイズを小さくするためのいくつかの工夫が見られたが,リンクのオプションで–whole-archiveという指定を–no-whole-archiveに変えることによって,サイズがかなり小さくなった. これまでは,この指定のために,使っていない関数についても組込まれてしまっていたようだ. 例えば,blinkは768バイトとなり,ch32funだと616バイトだが,スイッチの設定などを変更する部分などを考慮すると,無難なサイズでは無いだろうか. デフォルトでは–no-whole-archiveらしいので,わざわざそれを変えているということに意味があるのならば,不都合が生じる場合もあるかも知れない. しかし,残念なことに,UIAPduinoを持って帰るのを忘れてしまったので,まだ十分な検証ができていない.

ハードに触れないので,ソフトをいじろうということで,他にもいくつか変更を加えてみた. いつか組込もうと思っていたピン割り込みは,megaAVRのコードとch32v003のマニュアルを参考に,実装してみた. ToneはPWMと共通点が多いので,その中に組込む形で取り入れてみた. ついでに,alternate functionを利用して,すべてのピンでPWMを使えるようにした. pulseはWCHのコードにch32funのコマンドを入れて実現した. shiftはWCHのコードがそのまま利用できそうだと思ったら,api/Common.h中の宣言とかち合ったので,megaAVRのコードをそのまま使った. これらも動作の確認はこれからだが. ピン割り込みにはまだバグがある気がする.

なかなか原因が分らなかったSPIのコンパイルもできるようになった. その主な原因は,api/HardwareSPI.hで

virtual ~HardwareSPI() { }

と定義されていて,これが悪さをしていた. クラス名に~を付けると,オブジェクトが削除されるときに実行されるデストラクタを意味しており,このときにdeleteが呼ばれて,それが定義されていないというエラーが起きていたのである. この行をコメントアウトしたら,コンパイルできるようになった. しかし,ArduinoCoreAPIの中身は変更しないという方針なので,他の方法を模索する必要があった. deleteは,AVRmegaではnew.cppの中で定義されている. new.hとnew.cppを持って来て, platform.txtのcppのコンパイルオプションに,

-fno-exceptions -fno-use-cxa-atexit -std=gnu++11

を加えたら,freeが無いというエラーに変わった. freeは,通常はstdlib.h中で定義されているのだが,ch32v003にはfreeが無いのかも知れない. そこで,new.cppの関数の中身を失くしたら,うまく行った. まだSPIにはバグはあるかも知れないが,一番大きな問題がクリアされただろう.

i2cのslaveも少しコードを加えたけど,割り込みの部分がmasterのコードを干渉しそうなので,それをどうするのか悩んで,そこで止まっている. これで,組込む予定だった機能で,組込めていないのは,i2cのslaveのみになった. 本体が無かったので,動作確認が出来ていないのが大きな問題なのだが,一つずつ検証して行こうと思う.

最初は,とりあえず動くものを作ろうと考えていて,Arduinoやch32funの中身を理解するつもりは無かったのだが,いろいろな問題を解決する過程で,それらを避けて通るわけにはいけなかった. 特に,ArduinoからUIAPduinoのUSBを使えるようにするために,rv003usbを組込むところでは,様々な試行錯誤が必要だった. ch32v003の細かい仕様を知らなくても,Arduinoから使えるようにするために始めたはずなのに,目的と手段が入れ替わってしまったかな.