RL78/G13でのRAM上割り込みについて。

みなさんこんにちは、みなみです。
RAM上での割り込みについての質問です。
 
環境はRL78/G13 R5F101SH、CS+CACXでE1を使ってデバッグしています。
 
RAM上で割り込み処理をしたいときは、フラッシュライブラリのFSL_ChangeInterruptTable()でRAM上の指定の番地に飛ぶように設定する認識でいます。
 
現在12ビットインターバルタイマーの起動後に、上記の関数を実行することでRAM上の指定番地に飛ぶことが確認できています。
 
しかし、飛ぶのは1回だけでそれ以降は割り込みが発生しません。
 
関数の説明を見ると以下のようなことが書かれているので、これが関係あると思うのですがその手段が分かりません
「本関数実行後は割り込みの種類をユーザ側で判断する必要があるため、割り込みフラグは自動的にクリアされません。
割り込み種類の判断後、ユーザ側でクリア処理を行う必要があります。  」
 
どうすればいいのでしょうか?
宜しくお願いします。
  • チョコです。
    セルフプログラミングはやったことはありませんが,セルフプログラミング・ライブラリのマニュアルの「3. 3 割り込みに関する注意事項」に記載された「RAM 上での割り込み発生時にSFR(割り込み要求フラグIF)を参照することにより割り込み要因を判別できますが、判別後は割り込み要求フラグをクリア(0 を設定)するようにしてください。」のことかと思います。
    セルフプログラミング中の割り込みは1つのエントリ(FSL_ChangeInterruptTable()で指定)に分岐するので,そこで,割り込みが発生する可能性がある(許可していた)割り込みのxxIFフラグをチェックして,セットされていたxxIFフラグに対応した処理に分岐し,セットされていたxxIFフラグをクリア(xxIFに0を書き込む)と言うだけです。使っている割り込みが,12ビットインターバルタイマー割り込みであれば,xxIFはITIFになるので,ITIFに0を書き込みます。
    また,割り込み処理が完了したら,割り込み処理から復帰させる必要があるはずです。ここらはきちんと処理されていますか?
  • わわいです
    チョコさんに加えて。。
    割り込み処理で呼び出される関数呼び出しでは、通常の関数とは形式が違うことが多いです
    #具体的に言うとサブルーチンの復帰命令が通常の呼び出しと割り込み/例外呼び出しとで違う
    その割り込みベクタから呼び出されるRAM上の関数はちゃんとその割り込み関数の形式となっているでしょうか。

    それが違うと関数からの戻り番地が狂ってしまうため暴走することになります

    んで、その割り込み関数の指定方法ですが、ルネサスのツールチェインでは、その関数の定義を
    #pragma interrupt(ほにゃらら)
    と記述する事が多いです。が、そこら辺の詳しいことはお使いのツールチェインのマニュアルを見て調べてみてください。
  • みなみさん
    チョコさんわわいさんに加えて、
    サンプルコードが以下のスレッドにありますので参考にどうぞ^^
    japan.renesasrulz.com/.../sizeof

  • わわいです
    それからもうひとつ。
    そのRAM上の割り込み関数というのはどういうふうにRAM上に展開しているのでしょうか。
    ふつう、こういうことをする場合には、実行アドレスをRAM上のアドレスとして指定した関数を、フラッシュ上のアドレスに展開しておき、実行時にフラッシュからRAM上にコピーして実行させる、とややこしいことをするんですが、ここらへんのアドレス指定がうまくいかないとこれまた暴走することになったりします。

    ということで、デバッガで割り込み関数でステップ実行させ、どこでプログラムが暴走するか(メモリのない領域にジャンプするか)、をみるとどこでおかしなことになってるか、がわかるとおもいます
  • みなさん、レスありがとうございます。

    Kirinさんのレスのサンプルコードを参考に、
    割り込み先の関数名に"__interrupt"をつけたら毎回割り込みが発生するようになりました。

    コードフラッシュ関数実行後も割り込みが起きるので大丈夫だと思います。

    ありがとうございました。