ROM化支援機能でRAMに展開した関数から,ROM上の関数を呼ぶことができない

お世話になっております.

HEWのROM化支援機能でRAMで実行されている関数からROMに置かれている関数を呼び出すと,関数呼び出しが失敗し,INT_Illegal_codeが呼び出されてしまいます.

使用マイコンは,SH2AのSH7254Rです.

 

現在の実装詳細をお伝えします.

REPRO と呼ばれるセクションをきりまして,

0x00100000 : PREPRO, CREPRO, DREPRO (内蔵ROM)

0x04000000 : RREPRO, BREPRO(外部RAM)

と,さらにプログラミングのRAM展開場所として,

0x02200000 : PRREPRO, CRREPRO(外部RAM)

とセクションを割り当てています.

 

そして,HEWの最適化リンカ→出力→ROMからRMAにマップするセクションで,

DREPRO→RREPRO

PREPRO→PRREPRO

CREPRO→CRREPRO

と設定しています.

 

そして,以下の添付画像のように,

BOOT_LOADER_test関数をRAMに展開し,

その内部でROMにある関数BOOT_LOADER_test_innerを呼び出しているのですが,

処理がそちらのROMの関数へ飛ばず,全く別のアドレスへ飛んでしまい,結局INT_Illegal_codeとなってしまいます.

 

RAMへ割り付けた関数からROMにある関数を呼び出す方法を教えてくださいませ.

どうぞよろしくお願いいたします.

 

  • わわいです
    まずは、BOOT_LOADER_test_innerがどこのセクションに属しているか、mapファイルを出してしっかり確認しましょう
    んで、その関数のアドレスをどこかに出力させるなどして出して、どういうアドレス関係にあるのかチェックしてみてはどうでしょう
  • 回答,ありがとうございます.

    BOOT_LOADER_test_innerは,想定通り,ROMのPセクション(ROM上)である0x00001000にあります.
    (2枚めの画像でも,メモリマップでも確認しております.)

    > その内部でROMにある関数BOOT_LOADER_test_innerを呼び出しているのですが,
    > 処理がそちらのROMの関数へ飛ばず,全く別のアドレスへ飛んでしまい,結局INT_Illegal_codeとなってしまいます.
    と書きましたが, "全く別のアドレス" は PRREPRO とRAMに展開したプログラムがいるセクションに飛んでいました.

    アドレスの飛び先を相対アドレスで指定する,相対サブルーチンや相対無条件分岐などを疑っています.
    「HEWの最適化リンカ→出力→ROMからRMAにマップするセクション」
    でプログラムがROMからRAMへとコピーされたとき,その関数の呼び出し元や,コピーされた関数内から他の関数を呼ぶときのアドレスは,自動的に変換される,という理解でよろしいでしょうか?
    それか,他に設定する場所はありますでしょうか?

    例えば,
    「0x10先の関数へ飛ぶ」
    のようなコードをRAMへコピーした場合,"0x10先" を適切に変更しないとおかしなことになりますが,
    これは自動的に処理される,との理解でよろしいでしょうか?

    お手数をおかけしますが,ご返答のほど,お待ちしております.
  • わわいです
    BOOT_LOADER_test_inner 関数のプロトタイプ宣言はきちんと行ってますか?
    プロトタイプ宣言はなくても(ワーニングが出るだけで)コンパイルはできますが、解釈の段階で同じセクションと仮定されてるのかもしれません
    #もしかしたら、プロトタイプ宣言の方にもsection指定が必要なのかもしれませんが

    まあ、手っ取り早いのはBOOT_LOADER_test_inner関数を、BOOT_LOADER_test関数の前に持っていくことですね

  • ご返答,ありがとうございます.

    お世話になっております.

     

    プロトタイプ宣言はきちんと書かれています.

    その後,いろいろ試しました結果,

    「HEWの最適化リンカ→出力→ROMからRMAにマップするセクション」

    で設定した上で,下図のように転送するコードを追加しましたところ,正常に動作いたしました.

     

    これについて,1件質問があります.

    D→Rへのコピーは初期データで,このDTBLはデータセクション用だと思っています.

    ここに,Pセクションのようなプログラムセクションを設定してもよろしいでしょうか?

    他に適切な設定方法がございましたら,ご教授ください.

     

    どうぞよろしくお願いいたします.

     

  • わわいです
    > ここに,Pセクションのようなプログラムセクションを設定してもよろしいでしょうか?
    かまいません。
    というより、そこらへんの初期化ルーチン的には、データ/プログラムセクションの区別はないので、単にコピーするだけと言うならそこに書いておけば、初期化時に自動的にコピーしてくれます

    ましかし、DBSCTの記述でコピーするのはあくまで初期化時、でしかないので、
    例えば、特定の場面にしかそこには展開しない、とか、RAM領域を他の用途で共用するという場合には、ユーザプログラムの方で、memcpyなどでコピーしたりしますね。

    まあ、ワタシ的にはDBSCTに記述することでコピーのタイミングが分かりづらい、余計なセクション名が増える、ソースファイルが無駄に増える、とかを嫌って、dbsct.cは削除してしまって自前の初期化関数を書いてコピーするとかしますね
  • アドバイスありがとうございます.

    とりあえず所望のうごきができるようになりました.感謝いたします.

    頂いたアドバイスを元に,改良を加えていきたいと思います.