PIC32でRAM上コード実行
PIC32のFlash回数は1000回(min)です。H8とかの100回よりましですが、PIC24の10000回と比べると、中華LCDとかのデータシートが怪しいデバイスのソフトを作るには、ちょっと心配です。また、Flash書き込みは時間がかかります。そこで、RAM上にシリアルポートからXmodemプロトコルでバイナリコードをダウンロードしてプログラムが実行できる簡易ローダーを作ろうと思いました。オプティマイズのPIC32USBで試作です。昔H8用にオールアセンブラで作ったことあるので、すぐできるかなと思っていましたが・・・
- 4バイトアライメントでバイナリコード格納用配列確保
- Xmodem(1K,128のチェックサムのみ)でバイナリコードを受信して配列へコピー
- インラインアセンブラで絶対ジャンプ命令(MIPSはJR+NOP)を使って片道切符で格納用配列のアドレスへジャンプ
int Jump( unsigned long dwAddress )
{
asm volatile(
".set noreorder\n" ←これが無いとnopが変な位置に移動する。
"jr $a0\n"
"nop\n"
"nop\n"
);
}
という感じで・・・
バイナリコードを転送し、配列をダンプしてダウンロードできていることを確認。
さて、絶対ジャンプ・・・あれ、動かん!!MPLAB SIMでも止まってします・・・
ちなみに転送するコードは別プロジェクトで、リンカースクリプトの.textセクションを格納用配列に設定し、pic32-objcopyでelfの.textを抜き出してbinaryに変換。
次の日、嫁さんの実家で、iPhoneに登録してあるPIC32のマニュアルのバス周りを読む、、、なんか色々なレジスタがあって面倒だなと思いつつ、ああそっか、PIC32はハーバードだ、データ領域として設定されているRAMではコードは実行できんのか、、(ちなみにH8はノイマン)
帰宅後、ということで、まじめに設定するのは面倒だし、PIC32USBのブートローダーのコードは非公開で、どう設定しているかわからないので、
void DummyFunc( void )
{
asm volatile(
".repeat 2048\n"
"nop\n"
".endr\n"
);
}
の関数をつくって、DummyFuncのアドレスに転送し、絶対ジャンプ、動いた!!
次はこの間作ったPIC32MX基板で動かそう。
バスマトリックスのレジスタ設定は、crt0.sとの整合がめんどうなので、.ramfuncセクションをうまく使えば、なんとかなりそうかな。