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の書き換えがうまく行かない症状が出る可能性が残っているので、注意して使わないといけないが。

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...

mruby/cで複数のtask

mruby/cでは複数のtaskを走らせることができる。 その機能を使ったことはこれまで無かったが、折角使えるので使い方を考えてみた。 私が構築しているシステムでは、mrbのコードはflashの特定のアドレス以降に書いておいて、そこを書き換えることによって、mrbだけを入れ替えることができるようにしている。 そこに複数のmrbコードを並べて、それらを読み込んで実行できるようにすれば良いだろう。 一つのmrbのすぐ後に、またmrbのコードがある場合には、それを次のtaskとして登録するようにするのである。 そのための関数は以下のように定義することができる。

void load_continuous_tasks(const uint8_t *start_addr) {
  for (int i = 0; MAX_VM_COUNT > i ; i++) {
    if (memcmp(start_addr, "RITE", 4) != 0) break;
    mrbc_create_task(start_addr, 0);
    start_addr += // big endian
      ((uint32_t)start_addr[8]  << 24) |
      ((uint32_t)start_addr[9]  << 16) |
      ((uint32_t)start_addr[10] <<  8) |
      ((uint32_t)start_addr[11] );
  }
}

試しに、GPIOを使うmrbと、printを使うmrbを同時に走らせてみたら、問題なく動いた。 変数などはそれぞれのtaskで独立のようだ。 グローバル変数を使うと、taskを越えて使えるそうだが、まだ試していない。 マイコンでマルチタスクを使ったことは無いので、どう使うと便利なのかも考えてみたい。

Read more...

基板設計の半自動化

最近はマイコンとして、安価なCH32シリーズに注目している。 中でも比較的性能の高いCH32V203を使う機会が多くなってきている。 しかし、CH32V203のマイコンボードで入手しやすいblue pill+は比較的大きいので、pro micro程度の小型のものを欲しいと思っている。 そのようなものも販売されているが、部品の価格と比べて、かなり高額なものしか見当たらない。 そこで、自分でボードを設計しようかとも思うのだが、いくつか課題がある。 一つは回路を設計するのが面倒であるという点であり、もう一つはボードを注文すると個人で使うには過大な枚数になってしまうという点である。 設計が面倒だという点については、AIと配線の自動化を使うと解決できるということを知ったので、これを試してみた。

まず、AIにボードのピンとマイコンのピンの割り当てを考えてもらう。 そして、それに基いてkicad用のネットリストを作ってもらう。 pro microの端子にSWD用の端子を付け加えると、32pinのCH32V203K8T6の場合、外部振動子を除くと、一つだけピンが余るので、それをLEDに割り当てることができた。 最初は、kicadで読み込むとエラーは出ないが何も表示されなくて苦労したが、version Eということを指定して作ってもらったら、うまく行った。 必要なら、部品のパッケージなどを変更するように指定すると良いだろう。

それをkicadのpcb editorでファイル-インポート-ネットリストとして読み込むと部品が表示される。 部品の配置は、人間がやらないといけない。 配置も自由度がそれなりにあり、悩むところなのだが、マイコンのICを配線が単純になるような向きに置くことが最も重要で、それ以外の部品は、使い易い位置にすれば良いだろう。 USBの二本のデータ線は、同じ長さにしなければならないので、他の配線の邪魔にならないように意識しながら、あらかじめ配線しておく。 また、忘れないように、基板の外形を描く。 そして、Specctra DSN形式でエクスポートする。

次に、Freeroutingを実行して、DSNファイルを開いて、自動配線をする。 配線が無事に終ったら、ses形式でセーブする。 うまく配線が出来無い場合には、kicadに戻って部品の配置やUSBの配線などを改良してから、自動配線を試みる。 sesファイルをkicadにSpecctraセッションとしてインポートすると、配線が取り込まれる。 無駄な部分を修正するために、ツール-配線とビアをクリーンアップとする。 配線が不用意に蛇行したりすることもあるので、配線を選択してDを押してから、場所を調整すると良い。 これで、ボードの設計は終了である。

確かに、全部自分でやるよりは、かなり楽になった。 部品の配置は考えないといけないが、これは人によって好みが異なるので、完全な自動化は難しいだろう。 このやり方は初めてだったので、今回は多少の試行錯誤が必要だったが、次に似たような基板を設計する時には、比較的短時間でできると思う。 次に問題なのは、このボードのPCBを注文するかどうかである。

Read more...

ESP32用のmruby/c

ESP32用のmruby/cとしては,FemtoRubyを使ったR2P2があるが,PWMを使おうとしたらエラーが出たので,自分でもESP32用にmruby/cの環境を作ってみることにした. 自分のブログを見直してみたら,私がmruby/cを最初に使ってみたのはESP32だった. そのときには,Arduinoを使ってmrbのコードをソースに埋め込んでコンパイルしていた. そのため,rubyのコードを変えると,mrbを作って,それを埋め込んでArduinoでコンパイルして,マイコンに書き込むという作業をする必要があり,時間もかかるし面倒だった. これまで,何種類かのマイコン用にmruby/cの環境を作ってきた. それらにおいては,mrbファイルはflashに書き込んで,そのアドレスを使って直接mrbコードを読み出して使っている. しかし,同じことをESP32でやろうとしたら,そのままではうまく行かなかった. ESP32では,フラッシュに直接アドレスが割り当てられるわけでは無く,その内容が使われるときにcacheにコピーされるので,単にflashに書き込むだけでは駄目である. また,mrbコードをプログラムに埋め込んでおいて,その部分だけを書き換えようとしても,チェックデジットや誤り訂正などがあり,その内容を不用意に書き換えるとエラーが出てしまった. いろいろ試行錯誤した結果,使っていないflash領域にmrbを書き込んで,それをメモリに割り当てることで,ほぼ同じ感覚で使えるようになった. まず,私のホームページに載っているようにArduino用のmruby/cをセットアップする. そして,Arduinoで以下のコードをコンパイルして,ESP32に書き込む. #include "spi_flash_mmap.h" #include <mrubyc.h> #define MEMORY_SIZE (1024*30) static uint8_t memory_pool[MEMORY_SIZE]; #define FLASH_CODE 0x10000 + 0x120000 //esp32 spi_flash_mmap_handle_t s_data_map_handle; const uint8_t *flash_code = NULL; int hal_write(int fd, const void *buf, int nbytes) { Serial.write((char*)buf,nbytes); return (nbytes); } int hal_flush(int fd) { return 0; } void hal_abort(const char *s){} unsigned char hal_read(int fd) { while (Serial.available() == 0); return Serial.read(); } void setup() { uint32_t data_flash_offset = FLASH_CODE; // running->address + 1114112; uint32_t map_size = 0x10000; // 64KB esp_err_t err = spi_flash_mmap( data_flash_offset, map_size, SPI_FLASH_MMAP_DATA, // as rodata (const void **)&flash_code, &s_data_map_handle); Serial.
Read more...

ESP32でFemtoRuby

以前、raspberry pi picoでPicoRubyを動かしてみたことがあるが、その時にはESP32では動かす方法が見付からなかった。 ESP32では、mruby/cベースのFemtoRubyを使うらしく、それを簡単に使う方法を見付けたので、少し試してみた。 以前はPicoRubyと読んでいたものを、FemtoRubyと呼ぶことにしたらしく、名前が混在していてよく分からないこともある。

ESP32への書き込みは、 Webインストーラー を使って行う。Chromiumでこのサイトに行って、ESP32を繋いで書き込みを行う。 Webからこんなことが出来るようになっているのかと関心した。 別のモジュールで試したら、書き込みに失敗したりしたけど、うまくいったやつで、少し使ってみた。 書き込みは53%から一気に100%になって、不安だったが大丈夫のようだ。

今度は<a href=“https://picoruby.org/terminal>Webターミナルに行って、connectを押してから、リターンキーを何度か押したら、Shellが立ち上がった。 irbと打ったらrubyが使えるようになる。 GPIOを使ってみたら、無事に動いた。 次はADCかなと思ったら、require ‘adc’としないといけないようだ。 その次はPWMを試したら、require ‘pwm’まではできたが、PWM.newしたら、エラーでリセットがかかってしまった。

使えないボードがあったり、エラーでリセットがかかったりと、まだ不安定なようだが、手軽に使えるようになって来ているようだ。 私もESP32でArduinoを使ってmruby/cを動かしているが、その情報を公開する価値があるかどうか迷っている。 ESP8266でmruby/cを使っている人はあまりいないようで、情報が少かったので、このブログにも書いたこともあるし、ホームページにもまとめておいたので、誰かが使ってくれるかも知れない。

Read more...

ch32funのMakefile

ch32funで作ったプログラムのmapファイルを見ていたら,使っていないはずの関数が残っていたので,なんでだろうと思って調べてみたら,Makefileのオプションの指定が間違っていたことが分かった.

別のフォルダにあるライブラリも含めないといけなかったので,それをMakefile中のCFLAGSで指定し, さらに最適化して使っていない関数を除去しようと,以下のように指定していた.

CFLAGS += -Os -flto

理由はよく理解していないが,さらに以下のオプションを加えないと,使っていない関数が適切に除去できなかった.

CFLAGS += -ffunction-sections -fdata-sections

ch32funのexampleの多くでは,これらのオプションの指定はしていない. 調べてみると,ch32fun.mkの中では,以下のような記述がある.

CFLAGS?=-g -Os -flto -ffunction-sections -fdata-sections -fmessage-length=0 -msmall-data-limit=8 -fno-tree-loop-distribute-patterns

しかし,Makefile中でCFLAGSの設定したことによって,この設定が無効になってしまったようだ. Makefileで,ライブラリについての情報はEXTRA_CFLAGSに書くようにして,CFLAGSを指定しないしないようにしたら,期待通りの結果が得られた.

Read more...

mruby/cの表示ルーチンの改良

mruby/cには,表示をするやり方が複数ある. ruby側からは,p,puts,print,printfなどがあり, C言語からもいくつもの表示方法がある. ruby側から表示する関数は,c_object.cの中で定義されているが, p,puts,printでは,対応するC言語側の関数を呼び出しているのに対して, printfはsprintfを通して,mrbc_printf_intやmrbc_printf_floatを呼び出している. C言語から表示する関数は,console.cの中で定義されており, mrbc_print,mrbc_printfなどを使って表示することになっているが, 整数の場合にはmrbc_printf_intで, 浮動小数の場合にはmrbc_printf_floatとmrbc_format_floatで整形されている. 整数を扱うmrbc_printf_intでは,整数を適切に整形するプログラムが書かれているが,負の数でゼロ埋めをする際の処理に軽微なバグがあることを,2026/6/29のブログで紹介した. 一方,浮動小数を扱うmrbc_printf_floatとmrbc_format_floatでは, 共に整形の部分はsnprintfに丸投げしている. この関数は,非常にコンパイルサイズが大きく,mruby/cにFloatを組み込んだときに大きくなる一つの要因になっていると思われる. 小数はC言語のライブラリを使って整形しているのに,整数はmruby/cでコード書いているのは,Floatを無効にしたときに,整数を整形できるようにするためであろうが,Floatを使う際には整数の整形ルーチンがダブってしまい,無駄が多い. そこで,小数の整形をするルーチンを独自に書き下して,snprintfを使わないようにすれば,Floatを組み込む際にも,それほど大きくならないように出来るかも知れない. また,ch32funのsnprintfでは小数は表示できないので,Floatの表示ができないが,その問題も解消できる. mrbc_format_floatは,value.cの中で定義されているが, その中のsnprintfはmrbc_snprintfに変更することができる. console.cの中で定義されているmrbc_printf_floatは, mrbc_snprintfで使われているので, 元の関数はmrbc_format_float2と名前を変えて, mrbc_printf_floatを新たに定義することにした. Floatの表示は,通常の小数表記,科学的な表記,自動判定の3つの方法があり,これらはそれぞれ’f’,’e’,‘g’で表され,大文字を使う’E’と’G’もある. これらの表示をするためには,どのような処理が必要かを考えると,整数部と小数点以下を分離して桁数などに応じての表示と,指数部と仮数部の計算などをしなければならないことが分かる. 指数部は,自動判定時の小数表記と科学的表記の分岐にも使われる. そこで,通常の小数を表示する関数と,指数部と仮数部を計算してそのまま科学的表記をするか先の関数を呼び出して小数の表示をする関数の2つの関数を定義し,mrbc_format_floatからは指定に応じてこれらの2つの関数を呼び出すことにした. 通常の小数を表示する関数では,絶対値に直してから,その整数部分と精度を考慮した小数部を,整数として求めて,小数点を挟んでそれらをそれぞれmrbc_printf_intを用いて表示すれば良い. 前者は必要なら符号も表示し,後者は精度の幅でゼロ埋めして表示する. この関数は,科学的な表記の仮数部分を表示するときに呼び出すが,四捨五入で繰り上がりが生じて桁が変わる場合には,仮数を桁を調整しなければならないので,科学表記のときにはそのための処理も行うようにした. この関数を定義するときに,できるだけサイズを小さくするために,効果が大きな2つの工夫を行った. 1つ目の工夫は整数部と小数部に分ける際に,小数点の位置を精度の分だけ下にずらしてから四捨五入のために0.5を足した後で,うまくその2つの部分を取り出したことである. 単精度のときには,全体を整数に変換して,その上位の整数部と下位の小数部を割り算を用いて計算すると,32bitのCPUで扱いやすく,サイズを抑えることができた. 倍精度のときには,整数部は小数点の位置を戻して整数化して取り出し,小数部は整数部の桁数をずらして引くことによって取り出すと,小さくすることができた. 両者で小さくなるようなアルゴリズムが違うのは奇妙な気もする. しかしこのやり方では,整数部や精度が大き過ぎる場合には,問題が起こる可能性もあることに注意が必要である. 2つ目の工夫は,符号と絶対値を求める際に,専用の関数を使ったことである. 単にx<0や-xを計算するだけなら,バイナリでも単純になると思っていたのだが,doubleでは複雑な処理が行われるらしく,math.hを組み込んで,signbitとfabsを使うことで,100バイト以上小さくなった. 指数部の計算などをする関数では,絶対値に直してから,仮数xが1<=x<10になるまで,10を掛けたり割ったりして,同時に指数部を数える. そして,表示方法を自動判定するときには,精度と指数から判定して,小数表記なら先の関数を呼び出して,科学表記なら仮数を同様に表示して指数部は整数として表示する. この関数でも,doubleの処理の部分を工夫することが重要である. 絶対値を取る部分は,先と同様にも処理できるが,1.0や10.0との比較する部分を小さくするために,doubleをuint64_tとして解釈して,処理することにした. 正の数の場合には,doubleの大小とuint64_tの大小が一致することを利用して,大小を判定した方が,コンパイルサイズが小さくなったので,そのようにすることにした. それに伴って,絶対値や符号の処理はbit演算で表した. ソースの可読性が下がるという欠点はあるが,コンパクトにするためには仕方ないだろう. これで,浮動小数点も表示できるようになったが, 精度を指定しなかったときには,それが0になるようになっており, そうすると,printf “%f”,3.14としても,3しか表示さらなくなってしまった. 精度が0のときには,6にするようにすると,今度は精度を0にできなくなってしまう. そこで,精度を指定しなかったときの値を-1にした. そのために,関数mrbc_printf_mainの中でpf->fmtが初期化された直後に-1を代入する. pf->fmt.precision=-1; そして,ピリオドがあったら,その値を0にして,精度を取り込む. pf->fmt.precision=0; しかし, pf->fmt.precisionが0で無い場合に,精度が定義されているという判断をしている箇所が, mrbc_printf_bstrとmrbc_printf_intの中に見つかったので, それらの条件を以下のように書き換えた. pf->fmt.precision > 0 この修正により,デフォルトの表示の精度の問題も無くなり,思った通りに表示できるようになった. snprintfを使っていた場合には,フォーマットの文字列もこの関数で処理されるので,この問題は生じていなかったのである. console.cにこれらの修正をした後に,その末尾に先に考えた以下のコードを追加すれば, 新たなmrbc_print_floatが定義される. #if MRBC_USE_FLOAT #include <math.h> static void mrbc_printf_f(mrbc_printf_t *pf, double value, int *exponent) { int is_negative = signbit(value); value=fabs(value); int precision = pf->fmt.
Read more...

ch32funのfsusb

WCH社のマイコンでmruby/cを使うときなどに、ch32funを使っているのだが、 いつの間にかUSB部分のファイルが更新されたようだ。 github上のプログラムを利用するときには、できるだけreleaseを使うようにしており、そうするとファイルの内容は変更されない。 しかし、ch32funについては、最新のreleaseが一年半以上前のもので、CH32X035などの新しいマイコンを使うこともあるので、github上の最新のファイルを使っている。 普段は、以前downloadしているzipを使って作業をしていたので気付かなかったが、新たにdownloadしたら私のプログラムがコンパイル出来無くなっていたので、原因を調べたら、私が参照しているファイルが更新されたことが原因だった。

CH32X035でUSBを使うために、ch32funのfsusbを使っている。 このファイルは二週間前に更新されており、その仕様が変更になった。 以前と同じようにコンパイルしたら、fsusbで定義されている関数が参照できないというエラーが出て、原因が分からずにしばらく苦労していたが、 ADDITIONAL_C_FILESで指定しないといけなくなったことに気が付いた。 さらにエラーが出たが、それは変数や関数の名称が変更になっていたためであることも分かった。 これらに対応して、修正を加えたら、コンパイルは通るようになった。 追って、動作確認をしてみようと思う。

プログラムを安定して使うためには、やはりreleaseを使った方が良いことを実感したが、ch32funの新しいreleaseが早く出ないかな。

Read more...

ArduinoでCH32V203の隠しflash

CH32V203は、公式のflashは64kであるが、低速のflashが160kあり、 Arduinoからこれを利用する方法は2026/5/17のブログに書いたが、その手法は少し手間がかかった。 それを少し簡単にする方法を見出したので、紹介したい。 まず、160kのflashの情報をLink.ldに記述するのだが、ch32funでの記述を参考にして、EXTという名称にすることにした。 そして、EXTにはrodataを格納することにする。 そのように変更するためのシェルスクリプトは以下の通りである。 cd ~/.arduino15/packages/WCH/hardware/ch32v/1.0.4/system/CH32V20x/SRC/Ld/ sed -i -e 's/\r/\n/g' Link.ld sed -i -e 's@FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K@FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K\n\tEXT (rx) : ORIGIN = 0x08010000, LENGTH = 160K@' -e '/[.]rodata/d' -e 's@\.fini @.storage :\n{\n. = ALIGN(4);\n*(.rodata)\n*(.rodata*)\n. = ALIGN(4);\n} >EXT AT>EXT\n\n\t.fini @' Link.ld 以前に紹介した方法では、スケッチをコンパイルした後で、 通常のflashとEXTに書き込むバイナリを取り出す必要があったのだが、 platform.txtをいじると、これを自動で出来るようにすることができる。 バイナリを保存するように指定したときに、flashとEXTについて、バイナリを取り出して64kになるようにして、スケッチのあるフォルダにコピーするように、するのである。 その設定のためのシェルスクリプトは以下の通りである。 cd ~/.arduino15/packages/WCH/hardware/ch32v/1.0.4/ sed -i -e 's@recipe.objcopy.bin.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.elf2bin.flags} {compiler.elf2bin.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin"@recipe.objcopy.bin.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.
Read more...