デュアルバンク機能時の割り込み処理について

RX65N(2MB)で、FIT(r_flash_rx)を使用してコードフラッシュの書き換え機能を実装しています。

デュアルバンク機能を用いて、非動作バンクへ書き込む処理をしていますが、

フラッシュのアクセス時に、割り込みが発生するとプログラムが停止してしまいます。

当該箇所を割り込み禁止にすることで期待する処理は実装できるのですが、デュアルバンク機能では

割り込み処理をRAMに置く必要がないという認識でしたので、納得がいっておりません。

この認識は間違っているのでしょうか?

また、デュアルバンクなら動作バンクのフェッチが可能だと思うのですが、r_flash_rx の一部の関数を

RAMに配置する必要があるのは何故なのでしょうか?

  • YYさん、こんにちは。NoMaYと申します。

    過去、何度かデュアルバンク機能の質問に返答したことがありますが、YYさんの本来こうである筈という認識、と異なるという議論に発展することは無かったです。その認識で合っていて、過去の皆さんもそう出来ていた、ということです。

    自分はデュアルバンク機能をFITデモプログラムでしか使ったことが無いですけれども、デュアルバンク機能搭載品なら自動的にデュアルバンク機能向け設定になる、のでは無かった記憶があります。r_flash_rxのコンフィグレーションを適切な設定にしたり、デバッガでのデバイス選択を適切に選択したり、といったことは必要だったと記憶しています。

    例えば、以下のスレッドでは、r_flash_rxのFITデモプログラムを試して、質問者さんの勘違いが解決した後に、今回の質問のようなことは無かったです。

    r_flash_rx のサンプルについて
    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/7726/r_flash_rx
     

  • YYさん

    シェルティです、こんにちは。ルネサスの中の人です。

    >>この認識は間違っているのでしょうか?

     ⇒認識は合っていますが、一部例外があります。

    >>r_flash_rx の一部の関数をRAMに配置する必要があるのは何故なのでしょうか?

     ⇒オプション設定メモリがコードフラッシュメモリとtiedになっているためです。オプション設定メモリを書き換える際はRAM実行が必要でしてこれが上述の一部例外となります。コードフラッシュ内のバンク0と1においては、0で1を書き換え、1で0を書き換えはRAM実行が不要です。

    以上です

  • NoMaYさん、回答ありがとうございます。

    教えていただいたスレッドにあったサンプルを、e2studio、GCCプロジェクト、RX65N用に改造し、
    CMTのFIT(r_cmt_rx)を追加して、プログラムフラッシュアクセス時の動作を確認しました。

    確かに、割り込み禁止にしなくても、R_FLASH_Erase関数とR_FLASH_Write関数でプログラムが停止することはありませんでした。
    しかし、イレーズ対象のブロックを限定する為に、R_FLASH_Control(FLASH_CMD_ACCESSWINDOW_SET)関数をコールすると、プログラムが停止しました。

    デバッガで処理を追うと、flash_write_faw_reg関数の処理中に割り込みが発生すると、プログラムが停止してしまう様です。
    flash_write_faw_reg関数はデュアルバンク時にRAMに置かれるのですが、RAMに置かれた関数の処理時は割り込み禁止する必要があるという事でしょうか。

  • シェルティさん、回答ありがとうございます。

    >> ⇒認識は合っていますが、一部例外があります。
    >> オプション設定メモリを書き換える際はRAM実行が必要でしてこれが上述の一部例外となります。

    一部例外、というのは、RAM実行の関数処理中は割り込みを禁止するか、発生する可能性のある割り込み処理をRAMに置く必要があるという事でしょうか?

  • YYさん、こんにちは。NoMaYです。

    > flash_write_faw_reg関数はデュアルバンク時にRAMに置かれるのですが、RAMに置かれた関数の処理時は割り込み禁止する必要があるという事でしょうか。

    ドキュメントやソースを追ってみないと、とっさには分からないです。週末にでも調べてみます。あるいは、シェルティさんからのリプライが先にあるかも知れません。

  • こんにちは。NoMaYです。

    > ドキュメントやソースを追ってみないと、とっさには分からないです。週末にでも調べてみます。

    まずは、ドキュメントを追ってみました。R_FLASH_Control(FLASH_CMD_ACCESSWINDOW_SET)を実行する時にはRAM実行をする必要がある、という記載は無さそうですね。(「まずは」ということですけれども、、、)

    RXファミリ フラッシュモジュール Firmware Integration Technology
    R01AN2184JJ0491 Rev.4.91 Pages 107 Dec.23.22
    www.renesas.com/jp/ja/document/apn/rx-family-flash-module-using-firmware-integration-technology
     

  • こんにちは。NoMaYです。

    > オプション設定メモリを書き換える際はRAM実行が必要

    次に、ユーザーズマニュアル ハードウェア編を確認してみると、フラッシュアクセスウィンドウ設定レジスタ(FAW)は
    オプション設定メモリ(OFSM)に配置されていることが分かりましたので、RAM実行が必要である、ということですね。

    RX65Nグループ、RX651グループ ユーザーズマニュアル ハードウェア編
    R01UH0590JJ0230 Rev.2.30 Pages 2763 2019.06.20
    www.renesas.com/jp/ja/document/mah/rx65n-group-rx651-group-users-manualhardware-rev230

    7. オプション設定メモリ(OFSM)

    7.1 概要

    オプション設定メモリ(OFSM) は、以下に示すレジスタの総称です。

    ・ シリアルプログラマコマンド制御レジスタ(SPCC)
    ・ OCD/ シリアルプログラマID 設定レジスタ(OSIS)
    ・ オプション機能選択レジスタ0(OFS0)
    ・ オプション機能選択レジスタ1(OFS1)
    ・ エンディアン選択レジスタ(MDE)
    ・ TM イネーブルフラグレジスタ(TMEF)
    ・ TM 識別データレジスタ(TMINF)
    ・ バンク選択レジスタ(BANKSEL)(コードフラッシュメモリ容量が1.5M バイト以上の製品のみ)
    ・ フラッシュアクセスウィンドウ設定レジスタ(FAW)
    ・ ROM コードプロテクトレジスタ(ROMCODE)


  • YYさん、こんにちは。NoMaYです。

    > デバッガで処理を追うと、flash_write_faw_reg関数の処理中に割り込みが発生すると、プログラムが停止してしまう様です。
    > flash_write_faw_reg関数はデュアルバンク時にRAMに置かれるのですが、RAMに置かれた関数の処理時は割り込み禁止する必要があるという事でしょうか。

    R_FLASH_Control(FLASH_CMD_ACCESSWINDOW_SET)を実行する時にはRAM実行をする必要がある、ということを理解しましたので、RAM実行時の注意点を以下のスレッドから引用します。必ずしも割り込み禁止にする必要はありませんが、発生する可能性のある割り込み全ての割り込み関数が、フラッシュメモリからコード/データをフェッチ/リードすることが絶対に無い、ようにしておく必要があります。加えて、以下の引用元では書き忘れてしまったのですけれども、割り込みベクタテーブルもRAMに配置する(あるいは一時的にフラッシュメモリからRAMへコピーしたものを使用する)必要があります。

    思うに、ここが、ちょっとでも気を抜くとプログラムが動かなくなってしまう、そういう難しい点のように思うのです。

    r_flash_rx のサンプルについて
    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/7726/r_flash_rx/40473#40473

    > フラッシュアクセスとCMT動作は何か関連があるのでしょうか?
    > フラッシュアクセス時はCMTを停止する必要がある? (とは思えないので)、

    関係あります。コードフラッシュ書き換え中は、書き換える領域以外の部分であっても、フラッシュメモリからコード/データを
    フェッチ/リードすることが出来ません。ですので、この場合の言わばセオリー的に気になりますことは、以下の点です。

    (1) 割り込み処理コードがRAM上で実行されるようになっていますか?(今回はCMT割り込みです)
    (2) この時、割り込み関数だけでなく、以下の点にも気を配る必要があります
    (2-1) 割り込み関数から呼ばれているサブルーチンも全てRAMに配置されていますか?
    (2-2) 加えて、もしコンパイラがランタイムライブラリを呼び出していたら、それもRAMに配置する必要があります
    (3) データに関しても気を配る必要があります
    (3-1) 割り込み処理内でconstデータをリードしようとしていませんか?
    (3-2) 加えて、コンパイラが生成したコードでswitch文のジャンプテーブルがフラッシュメモリに配置されている場合もあります

    このあたりはどうでしょうか?


  • YYさん、NoMaYさん

    シェルティです、こんにちは。

    解析がありがとうございます。ここまでの書き込みを確認させていただきました。

    ご推察の通りで、①オプション設定メモリを書き込む際はRAM実行である必要があるのと、②RAM実行の最中に割込みが発生した際、割込み先の関数もまたRAM実行である必要があります。②の方でCMT割込みが発生した際に動作不良になっているのだと思います。

    実際のコードではオプション設定メモリのうち、アクセスウィンドウやバンクスワップのビットを書き換える際は以下ループに到達してRAM上でステータスビットをポーリングして完了待ちしています。# 本当は他の処理と同じく割込みを使いたかったのですが、上記②の問題もありちょっと妥協してこの形にしてあります。

    https://github.com/renesas/rx-driver-package/blob/efa200d686d4f5083e21a8b9ef57f49950dd3c3c/source/r_flash_rx/r_flash_rx_vx.xx/r_flash_rx/src/flash_type_4/r_flash_type4.c#L221

    ということで、対処方法としては、②実行中に割込みが入らないように、R_FLASH_Control() 前後で割込み禁止・許可になるかと思います。

    あるいは難しいかもしれませんが、CMTの割込み関数もFRAM2セクションに配置してしまうことですね。

    当該関数(CMTの割込み関数)前に「R_BSP_ATTRIB_SECTION_CHANGE(P, FRAM2)」、関数後に「#define FLASH_SECTION_CHANGE_END R_BSP_ATTRIB_SECTION_CHANGE_END」を書くとRAMに関数を配置できます。RAMにコードをコピーする処理はR_FLASH_Open()時に実行されますので、CMTの処理がR_FLASH_Open()より前にあるとこれまた暴走します。CMT以外にもR_FLASH_Control() 実行中に割込みが発生する可能性がある場合同様に暴走するので割込み関数をそれぞれRAM実行する処置を施す必要があります。

    以上です

  • YYさん

    シェルティです、こんにちは。

    こちらに回答しますと、Yesになります。

    以上です