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セクションをうまく使えば、なんとかなりそうかな。