• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:H8Sで割り込み発生時の飛び先アドレスがRAM上にある場合の割り込み関数の記述方法)

H8Sで割り込み発生時の飛び先アドレスがRAM上にある場合の割り込み関数の記述方法

このQ&Aのポイント
  • H8Sマイコンのプログラムで、割り込みが発生した場合の飛び先アドレスがRAM上にある場合、割り込み関数をどのように記述するか知りたいです。
  • 開発環境はHew4で、言語はC言語を使用しています。Boot部分とアプリケーション部分に分かれたプログラムで、Bootのベクターテーブル上で割り込みが発生した場合の飛び先アドレスをRAM上に設定しています。
  • アプリケーションソフトでは、割り込みが発生した場合にRAM上の指定したアドレスからFLASH ROM上の指定したアドレスにジャンプさせる方法と、FLASH ROM上の指定したアドレスに関数を記述する方法を教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

特定のアドレスに特定のデータを書き込む方法。 例:6000番地から、順に、16進数の01,23,45,67を書き込む unsigned char *addr; addr = 0x6000; addr[0] = 0x01; addr[1] = 0x23; addr[2] = 0x45; addr[3] = 0x67; もし「3014番地にジャンプするアセンブラコード」が「5A 00 14 30」であって、RAMの飛び先が6004番地なら unsigned char *addr; addr = 0x6004; addr[0] = 0x5A; addr[1] = 0x00; addr[2] = 0x30; addr[3] = 0x14; と書けば良いです。 また「関数のアドレスにジャンプ」の場合は unsigned char *addr; addr = 0x6004; int int_var; void (*func_addr)(void); func_addr = function_name; /*関数void function_name(void)のアドレスを受け取る*/ int_var = (int)func_addr); /*intにキャストする*/ addr[0] = 0x5A; /*JMP命令の1バイト目*/ addr[1] = 0x00; /*JMP命令の2バイト目*/ addr[2] = (int_var >> 8) & 0xff; /*アドレスの上位をセット*/ addr[3] = int_var & 0xff; /*アドレスの下位をセット*/ *注意* 上記の「0x5A 0x00」の命令コードは「たとえばの値」です。本当のJMP命令が何になるかは、アセンブラの命令コード表で調べて下さい。 また、上記では、16ビットアドレスを「上位、下位」の順にしていますが、H8Sでは順番が異なるかも知れません。命令コード表を良く見て「正しい順番」を確認して下さい。

andocchy
質問者

お礼

折角回答頂いたのですが、試すことが出来ずお礼が遅くなってしまい申し訳ございません。 回答頂いた例に従い記述したのですが、 void (*func_addr)(void); の行で、 以下のようなコンパイルエラーとなってしまいます。 何か解決策がお分かりでしたら教えていただけないでしょうか? C2500 (E) Illegal token "void" C2230 (E) Illegal function call C1000 (W) Illegal pointer assignment 宜しくお願いいたします。

andocchy
質問者

補足

済みません。上記の訂正なのですが、 unsigned char *addr; addr = 0xffb418;(RAM上の割り込みが発生した場合の飛び先アドレス) がコンパイルエラーの原因のようです。 記述方法を以下のようにに変えてみたのですがやはり上手く行きません。 addr = (char*)0xffb418; どなたか、お分かりの方いましたら、お願い致します。

その他の回答 (2)

  • bug_bug
  • ベストアンサー率78% (36/46)
回答No.3

(1)(2)ともにC言語仕様で簡易に記述するすべはありません, コンパイラ, リンカの仕様に依存する記述となりますが, Hew環境であれば仕組みさえ分かってしまえば, 割りと簡単に構築可能です. 以下, 参考になりそうなポイントです. (1) RAM上の特定アドレスにジャンプ命令が記述されており, オペランドとしてROM上のアドレスを示すメモリ空間のオフセットが示されていれば実現します. RAMは揮発性のため, あらかじめプログラムコード(以下, コード)を置いておくことはできませんので, スタートアップ処理内にてコードをROM上からRAM上へ展開(コピー)する必要があります. Bootの処理内にてH'3000以降のコードをRAM上へコピーする処理が書かれているだろうと推測します. 例えば初期値付きの変数などはRead/Write可能とするためにスタートアップ処理にてRAM上へコピーする必要がありますが, 同様の処置をコードに対しても実施し実稼動中はRAM上にコピーされたコードで動作します. このような手間を掛ける理由は, ROM上のコードで動作している場合はその領域からフェッチする為ROMをイレースすることができず, ファームウェアを更新することができません.(イレースした途端暴走します) (2) アセンブラであれば, オペランドに即値を記述すればいいのですが, C言語ベースで開発する場合リンカに割付アドレスを指定しておくことで簡易に実現が可能です. Hew環境で実施するのであれば, ツールチェーンのリンカ設定にてセクションを追加し, ソースコード上で"#pragma section <セクション名>"を記述することで割付セクションを指定します. 既存のファームウェアを読み解く場合, 関数記述による処理フローを追うよりも リンカによるセクション管理がどのように設定されているかを意識して読み解く方が幸せになれると思います.

  • ricardo_
  • ベストアンサー率19% (14/72)
回答No.2

 ルネサス提供のモニタを使っていますか?そのモニタの仮想ベクタを使っていますか?  

関連するQ&A