CH32V006でmruby/c

これまで、EPS8266やESP32についてはArduinoを使って、CH32V203やCH32X035についてはch32funを使って、mruby/cを動くようにしてきた。 これら情報は、ホームページのツールのマイコンのところにまとめてある。 CH32V006は、mruby/cを動かせるギリギリのスペックを持っており、rv003usbによってusbをソフトウェアで扱えるようになっているらしい。 試してみたところ、なんとかmruby/cは動くが、rv003usbがまだ不安定という状況であった。

先日のブログに書いたように、CH32V006は比較的新しいマイコンなので、ch32funではまだ完全に対応しきれていない部分もあり、若干の修正が必要であった。 mruby/cについてのコードでは、PWMではテーブルの変更、ADCではチャンネル番号の変換部分の変更などを行い、ch32v006に対応させることができた。 GPIOはほぼそのままで動作した。 それ以外の機能については、プログラムはそれっぽく修正したが、動作は未確認である。

ch32v006でmruby/cを動かすにあたって最も問題なのは、メモリが8kとかなり少ないことである。 FloatとTaskとmrblibを除いた状態でも、ruby用に割り当てるヒープ領域がかなりギリギリである。 SWDを標準入出力とするものを作ったら、5kか少なくとも4kを確保することができて、簡単なプログラムを動かすことはできて、それなりに安定して動作した。 SWDを接続せずに実行すると、printをすると固まってしまうが、WCH-LinkEと接続してminichlink -Tとしたら、ターミナルへの表示もできる。 USB CDCを標準入出力とすると、最大でも3.5kしか確保できない。 なんとか動くが、ループを回していると、メモリが溢れたり、ハングったりする。 USB HIDを使ったminichlinkのターミナルを標準入出力とすると、4kぐらいは確保でき、minichlink -kT -c 0x1209d003を二回実行すると表示もできるが、しばらくするとハングする。 なお、大きなバイナリをflashに書き込むときには、rv003usbのbootloaderだとしばしばエラーが出るので、書き込はWCH-LinkEで行った。 mrbコードは小さいからか、bootloaderでも書き込めることが多かった。

CDCやHIDが安定しないのは、おそらくrv003usbがCH32V006ではまだ安定して動かないためだろう。 rv003usbのdemo_terminalを動かしてみると、ch32v003で動かすと特に問題は無いのだが、ch32v006では不具合がある。 まず、コマンドを打ったときに、一度目は失敗して、二度目には走る。 そして、ずっと使っているとどこかでハングする。 このように、ch32v006のCDCやHIDの安定性が十分では無いようなので、mruby/cのメモリ不足と合わさって、ch32v006でUSBを使うmruby/cは、すぐに動かなくなってしまう。 USBを使う場合には、CH32V203やCH32X035を使った方が良いだろう。 特に、後者は価格的にもCH32V006とほとんど変らないし。

Read more...

CH32V006についてのch32funのバグ

CH32V006を少しいじってみたが、新しいICということで、ch32funでまだ対応できていないことなどがあって、苦労した。 その際、小さなバグを発見したので、ここに書いておこうと思う。

まず、rv003usbのbootloaderで小さなデータをflashに書き込むときには問題ないのだが、大きなデータのときには問題がある。 2026/8/20のブロクには、minichlinkで32k以上を消去するには、pgm-b003fun.cのerase_block_binの14バイト目を0x16から0x56に変える必要があることを書いたが、おそらくその問題はch32v006でも現われるだろう。 また、消去の待ち時間が足りなくて時々エラーが出るので、以下のようにして同じファイルのmax_retriesの値を100から200に変えると、このエラーは出なくなる。

sed -i -e 's/max_retries = 100;/max_retries = 200;/' pgm-b003fun.c

いくつかのプログラムを試してみたのだが、GPIOはあっさりと動いた。 PWMはうまくいかなかったが、これは私のプログラムの問題だった。 ピンとタイマーの情報をstatic const uint8_tの配列に保存していたのだが、これをうまく読み出せていないようだったので、static volatile uint8_tにしたらうまくいくようになった。 constだとflashに配置しようとして、アラインメントの問題が生じることがあるようだ。

次にADCを使おうとしたら、ここでもうまく動かなかった。 これは、CH32V003とは、使い方が少し変っていたのが原因で、ADCの初期化の部分をCH32V20xと同様に処理するようにしたらうまく動くようになった。 具体的には、以下の様に修正すれば良い。

sed -i -e '/void funAnalogInit/,/#if defined(CH32V20x)/ s/#if defined(CH32V20x)/#if defined(CH32V20x) || defined(CH32V006)/' ch32fun.c

これで、funAnalogInitとfunAnalogReadでADCを使えるようになる。

他の機能については、まだ使ってみていない。 ch32funでch32v006を使う場合には、他にもいろいろとトラブルがあるかも知れないが、徐々に解決していきたいと思う。

Read more...

CH32V006への書き込み

WCH社のCH32マイコンとしては、これまでにCH32V003, CH32V203, CH32X035などを使って来たが、新しく出たCH32V006を、遅ればせながら使ってみたら、思ったよりも苦労した。 CH32マイコンでは、通常はWCH-LinkEを使ってSWDピンを使った書き込みを行い、これまではそこで失敗したことは無かった。 しかし、CH32V006ではうまく行かず、悪戦苦闘した後に分かったのは、WCH-LinkEのfirmwareが古いと駄目だということである。

私が持っているWCH-LinkEはversionが2.8だったのだが、おそらく2.15以降でないとCH32V006には対応していないようだ。 Windowsの場合はfirmwareの書き換えは簡単らしいが、Linuxだと公式には対応していないので、wlink-iapを使った。 以下のコマンドで、2.15のfirmwareの書き込みができた。

cd src
make
mv wlink-iap ../firmwares
./wlink-iap -f FIRMWARE_CH32V305_v2.15.bin

いちいちWCH-LinkEを使うのも面倒なので、rv003usbのbootloader_v006を試してみることにした。 WeactStudioのマイコンボードを使ったので、DFUはPD5に設定する必要があるが、そのままの設定でよかったので、コンパイルしてbootloader領域に書き込んだ。

sudo ./minichlink -w bootloader.bin bootloader

RSTを押しながらUSBに繋ぐとbootloaderが立ち上がるので、minichlinkでUSBから書き込める。 LEDを光らせる単純なプログラムは無事に書き込みすることができた。

ちなみに、rv003usbのrvswdio_programmerだと、時々認識はできたけど、書き込みまではできなかった。 新しいWCH-LinkEを使うのがCH32V006の書き込みには無難なようだ。

Read more...

mruby/cに必要な最低限のメモリ

ch32funを用いて、WCH社のマイコン用のmruby/c環境を構築しているが、どの程度のメモリでmruby/cを動かすことができるのかを調べてみた。 mruby/cは3.4.1を使っているが、CH32X035用の環境としては、flashの容量の関係で、mrblibとTaskとFloatを組み込まないようにしている。 この状態でmruby/cに割り当てるメモリを減らしていって、どこまで動くのかを確かめた。

メモリを使うように、配列のサイズを徐々に増やしていって、どの大きさでエラーが出るかを確かめた。 検証用のプログラムは以下のものを用いた。

g=GPIO.new(24+12,GPIO::OUT)
a=[]
i=0
while true
  g.write 1
  a[i]=i+=1
  print "#{i}\r\n"
  sleep_ms 100
  g.write 0
  sleep_ms 200
end

まずは、4kで試すと、177でエラーが生じた。 同様に、3.5kでは113、3.0kで49と、0.5k当たり64ずつ減っている。 GPIOにも多少のメモリを使っているだろうから、計算上では何もしない状態で、2.6kのメモリを占有していることになる。 そして、余った分のメモリを、プログラム中で使っているのだろう。 つまり、3.0kのメモリをmruby/cに割り当てれば、ほとんどメモリを使わないようなプログラムであれば動くということである。

一方、C言語用にもメモリを残しておかなければならない。 今度はmruby/cに割り当てるメモリの量を増やしていって、0.5kぐらいしかメモリが残らないようにして、簡単なプログラムを走らせてみたが、問題無く動いた。 動かすプログラムにもよるだろうが、C言語用にはあまりメモリを残しておかなくても良いのかも知れない。

これまで、mruby/cには10k程度のメモリを割り当てることが多かったが、mrblibなどを使わない場合には、もっと少なくても動くことが分かった。 mruby/cが一応まともに動くような、最小のスペックのマイコンはCH32X035などだと思っていたが、もう少しメモリが少なくても大丈夫なようだ。 具体的には、flashが64k、メモリ10k程度のマイコンなら、ギリギリ動きそうである。 この程度のスペックを持つマイコンとしては、STM32F103やPY32F030などもあるけど、AVR64DUは8bitだから厳しいかな。

Read more...

ch32x035のbootloaderの書き換え

ch32v203用のmruby/cで、mrbコードだけを書き換えるためには、comuのbootloaderとminichlinkを使うと良いことは、2026/8/20のブログに書いた。 そのときは、主にminichlinkの問題で、32k以上のコードを書き込むことができなかったが、その後にそれを修正して64kまで書き込めるようになり、通常の用途には十分になった。 これで、ch32v203のmruby/c環境には、大きな問題点は無くなったと考えている。

一方、ch32x035についても、mrbコードだけを書き換えられないという同じ問題が残っている。 こちらはch32funのexamples_usbのbootloaderを使うと良いだろうと考えていたので、試してみた。 それをch32x035用にコンパイルして、WCH-LinkEで接続して以下のコマンドを実行すると、ch32x035のbootloader領域を書き換えることができる。

sudo ./minichlink -w bootloader.bin bootloader

すると、bootモードで立ち上げると、新たなbootloaderが立ち上がり、アドレスを指定してminichlinkでコードを書き込めるようになる。 但し、そのアドレスはflashの消去の単位である256の倍数とする必要がある。

mrblibとTaskとFloatを無効にした状態で、現在のmruby/cを動かす本体のバイナリのサイズは57kよりも僅かに小さい。 mrbを57kのところに置くようにプログラムを書き換えて、make buildするとバイナリができる。 それを書き込むには、bootモードにして、以下のコマンドを使えば良い。

sudo ../minichlink -w ch32x035.bin flash

そして、以下のようにmrbコードのみを書き換えることもできる。

sudo ../minichlink -w temp.mrb flash+$((1024*57)) -b

最初にWCH-LinkEを使わないといけないのが面倒だが、一旦bootloaderとメインのバイナリを書き込んだら、その後はUSBからmrbコードだけを書き換えればよいので、mruby/cの運用が楽になった。 minichlinkはそのままだと32k以上のflashの消去に失敗するだろうが、2026/8/20のブログの追記のように変更すれば、問題は起こらなかった。 ch32x035については、ほとんど使わないmethodを消すなど、使い易くするための様々な工夫がまだ考えられるが、mrbコードのみの書き換えが出来るようになったのは大きいだろう。

また、このbootloaderが気に入らなければ、unbrickすると、元のbootloaderに戻るらしい。 これは試してはいないが、元に戻せるのなら、安心してbootloaderを書き換えることができるだろう。 しかし、全体を一括してしか書き換えられないwchispよりも、部分的に書き換えのできるminichlinkがうまく動けば、そのままで通常は問題ないだろう。

Read more...

ESP32とESP8266のDeep SleepとLight Sleep

ESP32やESP8266などのマイコンは、WiFiにアクセスできるのだが、消費電力が大きいという欠点がある。 これを常時稼動させておくと、発熱もするし、電池などでの稼動には適さない。 時々、何かをモニタしたり、WiFiに繋いだりするのであれば、それ以外の時には、消費電力を抑えた状態にしておけば良く、そのような機能がある。

最も電力を小さくできるのは、Deep Sleepであり、電池駆動の場合には、これを使うと良い。 これを実行すると、メモリの内容なども消えて、復帰したときには、プログラムは最初からもう一度実行される。 多少電力は消費しても、メモリやレジスタの内容を保持したいときには、Light Sleepを使うと良い。 様々な機能をoffにすることによって、消費電力を抑えるが、復帰した時には、プログラムの続きから実行できる。

ArduinoでESP32のsleepを使うのは、非常に簡単である。 以下のようにヘッダファイルをincludeして、sleepする時間をマイクロ秒単位で指定して、sleepの開始をすれば良い。

#include <esp_sleep.h>
esp_sleep_enable_timer_wakeup(5 * 1000000ULL); //us
esp_light_sleep_start();

Deep Sleepの場合には、開始命令のlightをdeepにすれば良い。 ただし、それ以降の命令は実行されることは無く、setupに戻るのが、Light Sleepとの違いである。

一方、ESP8266では、少し複雑である。 Deep Sleepはプログラムは以下のようにするだけだが、RSTをD0ピンに繋いでおかないと、自動で復帰ができないので、注意が必要である。

ESP.deepSleep(5 * 1000000ULL); //us

また、Light SleepはForce Power Savingという機能を使って実現しているので、設定が少し面倒である。 以下のようにすると、消費電力が小さいLight Sleepが実行できる。

extern "C" {
  #include "user_interface.h"
}
  uint32_t sleep_ms;
  sleep_ms=sleep_s*1000;
  wifi_station_disconnect();
  wifi_set_opmode(NULL_MODE);
  wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
  wifi_fpm_open();
  wifi_fpm_set_wakeup_cb(NULL);
  wifi_fpm_do_sleep(sleep_ms * 1000);
  delay(sleep_ms + 1);
  wifi_fpm_do_wakeup();
  wifi_fpm_close();
  wifi_set_opmode(STATION_MODE);

これらの機能もmruby/cに組込もうと思う。 これで、ESP32やESP8266でmruby/cから使いたいと思っていた機能がほぼそろったことになる。 ESP32ではBlueToothも使えるけど、今のところ使う予定は無いので、まだしばらくは放置で良いかな。 ESP32上のmicropythonで動かしていたプログラムを、mruby/cに置き換えようかな。

Read more...

VirtualPC上でWin2k

古いPC上のWindowsで動いているシステムを、新しいPCで動かそうと思い、久々にWindowsをいじったが、やはり面倒なOSだと感じる。 最初はLinuxからWineで動かそうと思ったが、癖のありそうなソフトだったので、VirtualPCでWindowsを立ち上げて動かすことにした。 以前、WindowsNTで動いているシステムを、Debian上のVirtualBoxで動かしたことがあるが、その時はレジストリをいじらないといけないので、それなりに苦労したが、なんとかうまく動かすことに成功した。 今回は、より新しいWindows2000だったので、それほど大変では無いと思ったが、Windowsに苦しめられている。 Linux上で動かすVirtualPCとしては、qemuが良いということだったので、まずはqemuで試してみた。 qemuのインストールはaptを使えば問題無くできたが、使い方がVirtualBoxとは違っていたので、いくつかの点で少し戸惑った。 まず、VirtualMachineを作るときにCD-ROMのisoを要求されたが、おそらくOSによって仕様を調整するためであろう。 また、VirtualPCの画面と設定画面が切り替えられるようになっているのだが、ディスクの入れ替えは、設定画面に行かないといけないことに、なかなか気付けなかった。 うまく行かなかったのが、画面の解像度の設定である。 OSが古過ぎるために、ディスプレイのドライバーが対応していないようなのである。 VBEMPというドライバーや、Bochs VBEドライバーを試したがうまく行かなくて、ディスプレイの設定は諦めた。 一方、目的であるシステムは無事に動き、VirtualPCは有効であることが分かった。 そこで、Windows11上でVirtualPCを立ち上げて、同じシステムを動かそうとしたら、結局敗退した。 WindowsではVirtualBoxが簡単だということで、それをインストールしたが、さらにそこにWindows2000を入れるところまでは問題無くできた。 しかし、PCに接続したUSB-serialをVirtualPCのシリアルとして認識させようとしたら、なぜか立ち上がらなくなってしまった。 幾つか設定をいじったが、症状が変らないので、ホストPCとしてWindowsを使うのは適切では無いという結論に達した。 そこで、Linux上でVirtualBoxにWindows2000を立ち上げて、そこでシステムを運用することにした。 Debian13にVirtualBoxをインストールする方法は、大きく分けて二通りあり、Oracleのレポジトリを利用する方法と、Debianのfasttrackを利用する方法である。 後者の方がより安定しているらしいので、そちらを試してみることにした。 まず、backportsを有効にするために、/etc/apt/sources.listに以下の行を加えて、apt updateする。 deb http://deb.debian.org/debian/ trixie-backports main contrib non-free non-free-firmware そして、fasttrack-archive-keyringをインストールする。 fasttrack用に、以下の内容の/etc/apt/sources.list.d/fasttrack.sourcesというファイルを作成してからapt updateする。 Types: deb URIs: https://fasttrack.debian.net/debian-fasttrack Suites: trixie-fasttrack trixie-backports-staging Components: main contrib Signed-By: /usr/share/keyrings/fasttrack-archive-keyring.gpg カーネルヘッダーを入れてからVirtualBoxをインストールして、ユーザーをvboxusersグループとシリアルを使うためにdialoutグループに登録して、再起動する。 sudo apt install linux-headers-$(uname -r) build-essential dkms sudo apt install virtualbox sudo adduser $USER vboxusers sudo adduser $USER dialout sudo reboot ディスプレイの解像度を変更するためには、古いGuest Additionsをインストールすると良いらしい。 私の場合には、 versionが5.2.44のVBoxGuestAddisionsのisoを使った。 そして、フロッピーディスクを使うために、ストーリッジのところにフロッピーのコントローラーとドライブを追加した。 シリアルも/dev/ttyUSB0などをホストデバイスで指定して作った。 Homeキーがデフォルトだと右のctrlであったが、環境設定の高度の入力の仮想マシンから、左ctrl+左altに変更した。
Read more...

古いFD

古いPCをいじる必要があり、かなり久々に3.5インチのフロッピーディスクを使った。 まずは、ディスクを探すところから始める必要があったが、家のダンボールをあさって出て来たものをつかってみようとしたが、エラーが出て使えなかった。 フォーマットもしてみたが、駄目だった。 最初はWindowでフォーマットしたけれど、失敗したという情報しか得られなかったので、Linuxでフォーマットしたら、どうやら最初のセクタの部分がいかれているらしく、その場合はまったく使えないようだ。 結局、三枚試して全滅だった。 FDは沢山もっているが、そのほとんどが駄目になっているかもしれない。

FDDからスマートメディアに書き込むアダプタを以前もらったので、保有しているが、そういうのを使うのも方法かもしれない。 FDDのかわりに取り付けてSDなどに書き込めるFDDエミュレーターなどを使うことも考えても良いかもしれない。 arduinoで作ってみようかな。

あるCDRのデータを吸い出そうとしたら、半分ぐらいで止まってしまった。 CDRの多くも使えなくなっている可能性がある気がする。 長期保存するデータをどこに保存すべきなのかは、難しいところである。 HDDがましだとは思っているけど、古いノートを立ち上げようとしたら、そのHDDの一部が動かなくなっていたし、HDDも安心ではない。 SDDは長期保存には向かないらしいし、難しいなあ。 調べてみると、CD-RやDVD-Rが比較的寿命が長いらしい。 CD-Rなどは駄目になったことが何度もあるんだけどな。

Read more...

comuのbootloader

mruby/cをCH32V203用にカスタマイズしているが、現状では幾つかの課題があった。 その最も重要なものは、USBからはmrbcだけを書き換えることが出来無いことである。 CH32V203はUSBにハードウェアで対応でき、内蔵のブートローダーを立ち上げると、USBからflashを書き換えることができる。 しかし、その仕様ではflashの先頭から書き換えるようになっている。 一方、CH32V203用のmruby/cでは、flashの先頭にはmruby/cを動かすためのコードがあり、その後ろにユーザー用のmrbcコードを配置するようにしている。 mruby/cを使う際には、このmrbcの部分だけを書き換えることが出来れば、便利である。 SWDで接続している場合には、minichlinkを使って、アドレスを指定すればmrbcのみを書き換えることができる。 しかし、USB接続の場合にはその仕様のためにこれが出来無いのである。

ch32funのUSBDのコードが最近修正されたことに先日のブログで触れたが、いろいろと調べていたら、その修正を提案した人が作っているcomuというプロジェクトのことを知った。 comuというのは、CH32V203を使ってUSB-Aポートに収まるような小型のマイコンボードであり、それ用のプログラムなどが開発されている。 その中では、CH32V203用のブートローダーが公開されていて、これを応用するとmrbcのみの書き換えができるのではと思い、試してみた。

comuのブートローダーは、flashの先頭の2kの領域に書き込まれて、USBを介してminichlinkを用いてflashへの書き込みなどを可能にする。 ユーザーのコードはアドレスが2k以降の領域に書き込むことになるので、それだけ使えるflashの容量は減るが、USB用のbootloaderで2kというのは、かなり小さい部類に入る。 CH32V203用のmruby/cのメインのコードは、幸い62kより僅かに小さいぐらいの大きさなので、comuのブートローダーを丁度組み込める。

comuのブートローダーはch32funでコンパイルして、wchispで書き込めば良い。 すると、起動直後の5秒間はそのブートローダーが動き、その間はminichlinkからのアクセスが可能となるが、何も無ければそのままユーザーコードに移行する。 ユーザー用のプログラムの例は、comuのexampleにあるが、2k以降に配置するという指定のためにcomu.ldを使うようになっている。 mrubyのコードは、拡張flashを使うように修正したcomu.ldを組み込んでコンパイルて、minichlinkを使って2k以降と拡張flashにアドレスを指定して書き込めばよいはずである。 ところが、なかなかうまく行かずに、かなり苦労した。

comuの例にあるblinkやprintfは、使っているボード用に少し修正してコンパイルして書き込んだら、うまく動いた。 ちなみに、printfはUSBを使うものなので、ブートローダーの後でも、ユーザーコードでUSBを使えることを示している。 しかし、mruby/cを使おうとすると、全く動かない。 ブートローダーが使った機能やメモリの初期化が完全では無いために動かないのかと予想して、ブートローダーのソースを改造したりもしたが、それらはうまく行かなかった。 書き込みがすぐに終るので、書き込みがうまく行っていないかも知れないと思って、プログラムを書き込んだ後でその領域を読み出して、書き込んだファイルと内容を比較すると、256バイト目以降が一致していないことが判明した。 flashに書き込む際には、その直前にflashの消去が行われる。 消去がうまく行って書き込みが出来ていない場合には書き込めていない部分は規則的なデータになるはずだが、消去がうまく行かずに書き込みは出来ている場合にはその部分のデータは不規則になる。 また、flashの消去はch32v203では256バイト単位で行われるらしく、症状は消去が出来ていないことを示していた。 そこで、wchispでflash全体を消去してから、wchispでブートローダーを書き込んで、minichlinkでmruby/cのコードを書き込んで、その内容を読み出すと、データは一致して、うまく書き込めていることが分かり、mrbのコードが動き始めた。 flashの消去には或る程度の時間がかかるが、消去する領域が大きくなると、消去が終わる前に書き込みが始まり、データが化けてしまっていたのであろう。 書き込むプログラムが小さい時には、消去もすぐに終わるので、問題は起きないのである。 確実なのは、bootloaderとメインのコードを、サイズを調整して結合して、それをwchispで書き込む方法である。

私の目的としては、上記のようにしてmruby/cを一度書き込めば、その後はmrbを書き換えるだけであり、mrbは小さいことが多いので、それほど問題にならないかも知れない。 今のところ、mrbの書き込みで失敗は無いように思われる。 しかし、非常に気持が悪いので、どのように変更すれば良いかを検証してみた。 まず、boot_usercode_addressなどの変数はch32funのbootloaderで使われていたが、comuではユーザーコードへの移行の仕方が異っているために、使われていないようだったので、それらを取り除いたが、これは機能には影響しないはずである。 ブートローダーでは、minichlinkから送られてきたデータをメモリ上にコピーして、それをプログラムとして実行するということが行われている。 メモリ上のコードに実行を移す前後に、USBがそれぞれnakとackを返すように設定するルーチンを加えて、実行が終わるまではUSBから新たなデータが入って来ないようにしても、あまりうまく行かない。 また、minichlinkに待ち時間を入れたりもしたが、変化は見られない。 何が起きているのだろう。 comuの作者がこのバグに気が付いて、改善してくれるのを待つことにしよう。

これで、このブートローダーを使って、当初の課題であったmrbcのみの書き換えができる仕組みが一応出来上がった。 mrbの書き換えがうまく行かない症状が出る可能性が残っているので、注意して使わないといけないが。

2026/9/7追記 書き込むサイズが大きいときに、flashの消去がうまくいかないのは、comuのbootloaderよりも、minichlinkの問題が大きいことが分かった。 32k以上のflashを消去するときには、符号付き16bitとして解釈するとサイズが負の数になるため、256バイトを一度消去したら、もう最後まで行ったと勘違いしてしまっていたので、これを符号無し16bitと解釈させるようにした。 具体的には、pgm-b003fun.cのerase_block_binの14バイト目を0x16から0x56に変更すれば良い。 このminichlinkの問題は、flashが32k以上あるch32x035やch32v006などでも起きそうなので、修正されると良いけど。 そのままだと、Timeoutエラーが出たので、comuの方はscratchpadexecの実行の前後に、以下のそれぞれのコードを入れて、flashの消去中にUSBのアクセスを受け付けないようにしたら、64k足らずまではうまく消去できるようになった。

USBD->CNTR &= ~USBD_CTRM;
USBD->CNTR |= USBD_CTRM;

64k丁度のときには16bitでは表せないので、65535を指定するようにすれば良いはずだ。 それ以上だと、機械語部分を手直ししないといけないので、ちょっと面倒になる。

Read more...

ch32funのUSBDの更新

CH32用にmruby/cを使えるようにするために、ch32funを利用している。 ch32funは、それなりの頻度で更新が行われており、更新があった際にはそれに対応してコードを修正する必要がある場合もある。 先日、USBFSのコードが更新され、それに対応するためにCH32X035用のmruby/cのコードを一部修正した。 そして、USBDのコードも更新の提案があったので、更新されるのを待っていたが、つい最近更新されたので、CH32V203用のmruby/cのコードも修正した。 これらの修正によって、USBFSとUSBDの扱い方にほとんど差が無くなって、使い易くなったように感じる。 また、USBDでもHIDのコードが扱えるようになった。

ch32funを使ったmruby/cについての情報を、私のホームページで公開しているが、使うch32funを一旦固定しようと思う。 githubで特定の時点でのファイルをダウンロードする方法を知らなかったが、少し調べたらやり方が分かった。 githubのページの右側に時計マークとcommitの数が表示されているので、そこを押すと更新履歴が表示される。 どの時点の更新を参照するかを考えて、その右の<>マークを押すと、その時点のファイルが表示される。 そこで、Code-Download ZIPとすれば良いのである。

Read more...