r_flash_rx のサンプルについて

RX71M StarterKit を使用してフラシュアクセスのデモ(flash_demo_rskrx64m)をテストしています。

デモ単体では動作確認できたのですが、CMT(r_cmt_rx)を組み込んでLEDを点灯させようとしました。

フラシュのデモは動作して、CMTのLED点灯だけでも動作しましたが、両方を同時に実行したらフラッシュのアクセス時に停止してしまいました。

(たぶん、CMTの割り込みでハングした)

RXのフラッシュ・アプリケーションノートによると、FRDYI割り込み(ベクタ23)を使用しているとの事で、

デモプログラムでは

static void flash_copy_vector_table(void)
{
uint32_t *pvect_table;

pvect_table = (uint32_t *)__sectop("C$VECT");
ram_vector_table[23] = pvect_table[23];
set_intb((void *)ram_vector_table);
}

と在ったので、23以外(0~255)もコピーするようにしました。(CMTの割り込みベクタもコピー??)

ベクタテーブルのコピーだけではだめで、

さらに、フラッシュにアクセス(R_FLASH_Open)する前に R_CMT_Stop(cmt_hdl); を使用してCMTを停止しないと

フラッシュのEraseで停止する。(停止して、フラッシュアクセス終了で R_CMT_Control(cmt_hdl,CMT_RX_CMD_RESTART,0); でリスタートで問題なし)

フラッシュアクセスとCMT動作は何か関連があるのでしょうか?

フラッシュアクセス時はCMTを停止する必要がある? (とは思えないので)、

割り込みベクタ関連でコピー以外に何か必要な事があるのでしょうか?

r_flash_fcu.c にある

R_BSP_PRAGMA_STATIC_INTERRUPT(Excep_FCU_FRDYI,VECT(FCU,FRDYI))
FLASH_PE_MODE_SECTION
R_BSP_ATTRIB_STATIC_INTERRUPT void Excep_FCU_FRDYI(void)
{

が関係しているのかな?とは思うのですが、R_BSP_PRAGMA_STATIC_INTERRUPT(Excep_FCU_FRDYI,VECT(FCU,FRDYI)) が

何をしているのか理解できていません。これは一体何を示しているのでしょうか?

よろしくお願いいたします。

Parents
  • ka.makiharaさん、こんにちは。NoMaYです。

    > R_BSP_PRAGMA_STATIC_INTERRUPT(Excep_FCU_FRDYI,VECT(FCU,FRDYI)) が
    > 何をしているのか理解できていません。これは一体何を示しているのでしょうか?

    私が昔提案した、CC-RX/GNURX/ICCRXの3種類のコンパイラに対応したソースを記述する為のマクロを使ったものですね。CC-RXでは以下のように展開されたと思います。(他のコンパイラでは他のコンパイラ用の記述に展開されます。)

    #pragma interrupt Excep_FCU_FRDYI(VECT(FCU,FRDYI))

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

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

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

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

  • ありがとうございます。

    今回はCMT割り込みがRAM上ではありませんでした。

    RXフラッシュモジュール・アプリケーションノート

    2.16.2 コードフラッシュメモリから・・・を読んだ時にRX71M(タイプ3)なので

    自分が動作している領域、CMT割り込みが動作している領域以外であれば書き換え可能と考えてしまいました。

    複数の領域というのが、r_flash_rx71m.h にあるBLOCKで表された単位(32kB)と考えてしまったのですが、71Mでのフラッシュの複数の領域、というのはどのような領域となるのでしょうか?

  • ka.makiharaさん、こんにちは。NoMaYです。

    これは、私としてはデュアルバンク機能の機能として認識していた、以下のRX72Mのハードウェアマニュアルに記載の話かな、と思いました。(もっとも、私の理解の仕方がまずくて、リニアモードとデュアルバンクモードは別のモードなので、FITモジュールのドキュメントのように、16.12.2と16.12.3のように節が分かれるのが本来かも知れません。)


    64.17.2 BGO 機能
    BGO 機能とは、コードフラッシュメモリ上の書き換えプログラムで、データフラッシュメモリや他の領域のコードフラッシュメモリを書き換えられる機能です。
    書き換え対象のフラッシュメモリとリード対象のフラッシュメモリが下記の組み合わせである場合には、BGO 機能を利用することができます。

    表64.25 BGO機能を利用可能な条件


    [関連リンク]

    RXファミリ フラッシュモジュール Firmware Integration Technology
    R01AN2184JJ0480 Rev.4.80 Pags 106 Apr.23.21
    www.renesas.com/jp/ja/document/apn/rx-family-flash-module-using-firmware-integration-technology

    RX72Mグループ ユーザーズマニュアル ハードウェア編
    Rev.1.11 2021.02
    www.renesas.com/jp/ja/document/mah/rx72m-group-users-manual-hardware
     

  • ka.makiharaさん、こんにちは。NoMaYです。

    ごめんなさい、こちらはRX71Mでしたね。(別スレッドにてRX72Mの話があって、混同してしまいました。) でも、RX71Mでも、同じ話だと考えています。

  • RX71Mスターターキットを使用しているので、フラッシュは4M、ということは

    前半2M,後半2M になり、書き換えプログラムが前半2Mで動作しているのなら

    後半2Mの領域は書き換え可能ということで、BLOCK_69(0xFFE00000)、後半の先頭を

    Erase,Writeできる事を確認しました。

    ただ、今回FLASH_CFG_CODE_FLASH_RUN_FROM_ROM=1でテストしており、

    *GBOはいずれも0にしています。

    RX ファミリ・フラッシュモジュール、アプリケーションノートには

    「2.4 使用する割り込みベクタ」で、*BGOが1の時割り込みが有効になります。とあるので

    サンプルにありました、ベクタテーブルのコピー(C$VECT)を実行しないようにしましたが、

    R_FLASH_Open() ->flash_lock_state() で停止してしまいました。

    アセンブラで見てみると

    のように、プログラムコードが無い状態でした。

    消去したベクタテーブルのコピーを実施すると、

    flash_lock_state() にはプログラムコードが書かれており、

    一体誰がコピー(?)したのかわかりません。

    他にも割り込みが動作していて、そちらでコピーが走っているのでしょうか?

  • 申し訳ありません。添付する画像を間違えました。

    中身が無いものはこちらでした。

  • 色々、混乱していまして、申し訳ありません。

    FLASH_CFG_CODE_FLASH_RUN_FROM_ROM の値を0,1を切り替えてテストしていたのですが、

    評価ボードの電源をOnしっぱなしで切り替えて実行していたため、メモリ上にコピーしたものが残った状態でした。

    電源OFFして起動したあとはFLASH_CFG_CODE_FLASH_RUN_FROM_ROM を1にした状態では、Open->flash_lock_state() で停止する事は変わりませんでした。(該当アドレスの中身は00)

    RX71M ではRAMコピーの方法しかないのでしょうか?

    使用するRX71Mのフラッシュ容量が2Mタイプのものでも前半(1M)、後半(1M)として利用可能でしょうか?

  • ka.makiharaさん、こんにちは。NoMaYです。

    FIT RXフラッシュモジュールのデモプログラムの中に以下のものがあったことに気付いたので中を見ていたのですけど、関数のコメントが気になりました。何かしらの、とある期間においては、デバッガでフラッシュメモリが読めなくなるのは、もともと、とにもかくにも何かの事情があるのかも知れない、という気がしてきています。

    また、このデモプログラム(RX64Mですが)ではベクタのコピーは行われていませんけど、それでも動作するデモになっていて(BGO機能も使っていません)、行っていることは、ka.makiharaさんがされていることと同じですよね?

    RX Family Flash Module Using Firmware Integration Technology Rev.4.80 - Sample Code
    www.renesas.com/jp/ja/document/scd/rx-family-flash-module-using-firmware-integration-technology-sample-code

    r01an2184xx0480-rx-flash/FITDemos/flash_demo_rskrx64m_runrom/src/demo/main.c

    /*******************************************************************************
    * Function Name: cf_driver_in_rom
    * Description  : Erases, programs, and verifies a block of ROM in a different
    *                region than the app is executing from (flash driver in ROM).
    *                See section 2.13-2.14 in app note for linker setup.
    *                See table 63.16 (RX64M) and 63.18 (RX71M) in Hardware Manual
    *                for address regions.
    * Arguments    : none
    * Return Value : none
    * Note         : Debugger cannot inspect ROM contents when in ROM P/E mode
    *              : (executing code flash command).
    *******************************************************************************/
    static void cf_driver_in_rom(void)
    {
        uint32_t    i;
        flash_err_t err;
        volatile uint32_t addr;


        /* Make all of code flash writable */
        err = R_FLASH_Control(FLASH_CMD_LOCKBIT_DISABLE, NULL);
        if ( FLASH_SUCCESS != err)
        {
            while(1);
        }


        /* Erase code flash block */
        err = R_FLASH_Erase(FLASH_CF_BLOCK_4, 1);
        if(err != FLASH_SUCCESS)
        {
            while(1) ;
        }


        /* write 1 block of data (easily modified for more) */
        addr = (uint32_t)FLASH_CF_BLOCK_4;
        while (addr < ((uint32_t)FLASH_CF_BLOCK_4 + FLASH_CF_SMALL_BLOCK_SIZE))
        {
            err = R_FLASH_Write((uint32_t)g_buf, addr, sizeof(g_buf));
            if(err != FLASH_SUCCESS)
            {
                while(1) ;
            }

            /* Verify code flash write */
            for (i = 0; i < sizeof(g_buf); i++)
            {
                if (g_buf[i] != *((uint8_t *)(addr + i)))
                {
                    while(1) ;
                }
            }

            addr += sizeof(g_buf);
        }

    }

     

    /***********************************************************************************************************************
    * Function Name: main
    * Description  : This program demonstrates sample function calls to erase, blank check, write, and read data back
    *                from both code and data flash on the RX64M.
    * Arguments    : none
    * Return Value : none
    ***********************************************************************************************************************/

    void main(void)
    {
        uint32_t    addr, i;
        flash_err_t err;
        flash_res_t result;


        /* Initialize data to write */
        for (i = 0; i < sizeof(g_buf); i++)
        {
            g_buf[i] = (uint8_t)i;
        }

        /* (no need to copy vector table to RAM because not erasing/writing ROM from region executing from) */

        /* Open driver */
        err = R_FLASH_Open();
        if (err != FLASH_SUCCESS)
            while(1);


        /* ERASE AND WRITE A BLOCK OF CODE FLASH */
        cf_driver_in_rom();


        /* DATA FLASH */

        以後、省略
    }

     

    r01an2184xx0480-rx-flash/FITDemos/flash_demo_rskrx64m_runrom/src/smc_gen/r_config/r_flash_rx_config.h

    /******************************************************************************
     ENABLE CODE FLASH PROGRAMMING
    ******************************************************************************/
    /* If you are only using data flash, set this to 0.
     * Setting to 1 includes code to program the ROM area. When programming ROM,
     * code must be executed from RAM, except under certain restrictions for flash
     * type 3 (see section 2.16 in App Note). See section 2.15 in the App Note for
     * details on how to set up code and the linker to execute code from RAM.
     */
    #define FLASH_CFG_CODE_FLASH_ENABLE (1)


    /******************************************************************************
     ENABLE BGO/NON-BLOCKING DATA FLASH OPERATIONS
    ******************************************************************************/
    /* Setting this to 0 forces data flash API function to block until completed.
     * Setting to 1 places the module in BGO (background operations) mode. In BGO
     * mode, data flash operations return immediately after the operation has been
     * started. Notification of the operation completion is done via the callback
     * function.
     */
    #define FLASH_CFG_DATA_FLASH_BGO   (0)


    /******************************************************************************
     ENABLE BGO/NON-BLOCKING CODE FLASH (ROM) OPERATIONS
    ******************************************************************************/
    /* Setting this to 0 forces ROM API function to block until completed.
     * Setting to 1 places the module in BGO (background operations) mode. In BGO
     * mode, ROM operations return immediately after the operation has been started.
     * Notification of the operation completion is done via the callback function.
     * When reprogramming ROM, THE RELOCATABLE VECTOR TABLE AND CORRESPONDING
     * INTERRUPT ROUTINES MUST BE IN RAM.  
     * See sections 2.17 Usage Notes in the App Note.
     */
    #define FLASH_CFG_CODE_FLASH_BGO   (0)


    /******************************************************************************
     ENABLE CODE FLASH SELF-PROGRAMMING
    ******************************************************************************/
    /* Set this to 0 when programming code flash while executing in RAM.
     * Set this to 1 when programming code flash while executing from another
     * segment in ROM (possible only with RX64M, RX71M, RX65N-2, RX72M groups).
     * See section 2.16 in the App Note.
     */
    #define FLASH_CFG_CODE_FLASH_RUN_FROM_ROM   (1)

     

Reply
  • ka.makiharaさん、こんにちは。NoMaYです。

    FIT RXフラッシュモジュールのデモプログラムの中に以下のものがあったことに気付いたので中を見ていたのですけど、関数のコメントが気になりました。何かしらの、とある期間においては、デバッガでフラッシュメモリが読めなくなるのは、もともと、とにもかくにも何かの事情があるのかも知れない、という気がしてきています。

    また、このデモプログラム(RX64Mですが)ではベクタのコピーは行われていませんけど、それでも動作するデモになっていて(BGO機能も使っていません)、行っていることは、ka.makiharaさんがされていることと同じですよね?

    RX Family Flash Module Using Firmware Integration Technology Rev.4.80 - Sample Code
    www.renesas.com/jp/ja/document/scd/rx-family-flash-module-using-firmware-integration-technology-sample-code

    r01an2184xx0480-rx-flash/FITDemos/flash_demo_rskrx64m_runrom/src/demo/main.c

    /*******************************************************************************
    * Function Name: cf_driver_in_rom
    * Description  : Erases, programs, and verifies a block of ROM in a different
    *                region than the app is executing from (flash driver in ROM).
    *                See section 2.13-2.14 in app note for linker setup.
    *                See table 63.16 (RX64M) and 63.18 (RX71M) in Hardware Manual
    *                for address regions.
    * Arguments    : none
    * Return Value : none
    * Note         : Debugger cannot inspect ROM contents when in ROM P/E mode
    *              : (executing code flash command).
    *******************************************************************************/
    static void cf_driver_in_rom(void)
    {
        uint32_t    i;
        flash_err_t err;
        volatile uint32_t addr;


        /* Make all of code flash writable */
        err = R_FLASH_Control(FLASH_CMD_LOCKBIT_DISABLE, NULL);
        if ( FLASH_SUCCESS != err)
        {
            while(1);
        }


        /* Erase code flash block */
        err = R_FLASH_Erase(FLASH_CF_BLOCK_4, 1);
        if(err != FLASH_SUCCESS)
        {
            while(1) ;
        }


        /* write 1 block of data (easily modified for more) */
        addr = (uint32_t)FLASH_CF_BLOCK_4;
        while (addr < ((uint32_t)FLASH_CF_BLOCK_4 + FLASH_CF_SMALL_BLOCK_SIZE))
        {
            err = R_FLASH_Write((uint32_t)g_buf, addr, sizeof(g_buf));
            if(err != FLASH_SUCCESS)
            {
                while(1) ;
            }

            /* Verify code flash write */
            for (i = 0; i < sizeof(g_buf); i++)
            {
                if (g_buf[i] != *((uint8_t *)(addr + i)))
                {
                    while(1) ;
                }
            }

            addr += sizeof(g_buf);
        }

    }

     

    /***********************************************************************************************************************
    * Function Name: main
    * Description  : This program demonstrates sample function calls to erase, blank check, write, and read data back
    *                from both code and data flash on the RX64M.
    * Arguments    : none
    * Return Value : none
    ***********************************************************************************************************************/

    void main(void)
    {
        uint32_t    addr, i;
        flash_err_t err;
        flash_res_t result;


        /* Initialize data to write */
        for (i = 0; i < sizeof(g_buf); i++)
        {
            g_buf[i] = (uint8_t)i;
        }

        /* (no need to copy vector table to RAM because not erasing/writing ROM from region executing from) */

        /* Open driver */
        err = R_FLASH_Open();
        if (err != FLASH_SUCCESS)
            while(1);


        /* ERASE AND WRITE A BLOCK OF CODE FLASH */
        cf_driver_in_rom();


        /* DATA FLASH */

        以後、省略
    }

     

    r01an2184xx0480-rx-flash/FITDemos/flash_demo_rskrx64m_runrom/src/smc_gen/r_config/r_flash_rx_config.h

    /******************************************************************************
     ENABLE CODE FLASH PROGRAMMING
    ******************************************************************************/
    /* If you are only using data flash, set this to 0.
     * Setting to 1 includes code to program the ROM area. When programming ROM,
     * code must be executed from RAM, except under certain restrictions for flash
     * type 3 (see section 2.16 in App Note). See section 2.15 in the App Note for
     * details on how to set up code and the linker to execute code from RAM.
     */
    #define FLASH_CFG_CODE_FLASH_ENABLE (1)


    /******************************************************************************
     ENABLE BGO/NON-BLOCKING DATA FLASH OPERATIONS
    ******************************************************************************/
    /* Setting this to 0 forces data flash API function to block until completed.
     * Setting to 1 places the module in BGO (background operations) mode. In BGO
     * mode, data flash operations return immediately after the operation has been
     * started. Notification of the operation completion is done via the callback
     * function.
     */
    #define FLASH_CFG_DATA_FLASH_BGO   (0)


    /******************************************************************************
     ENABLE BGO/NON-BLOCKING CODE FLASH (ROM) OPERATIONS
    ******************************************************************************/
    /* Setting this to 0 forces ROM API function to block until completed.
     * Setting to 1 places the module in BGO (background operations) mode. In BGO
     * mode, ROM operations return immediately after the operation has been started.
     * Notification of the operation completion is done via the callback function.
     * When reprogramming ROM, THE RELOCATABLE VECTOR TABLE AND CORRESPONDING
     * INTERRUPT ROUTINES MUST BE IN RAM.  
     * See sections 2.17 Usage Notes in the App Note.
     */
    #define FLASH_CFG_CODE_FLASH_BGO   (0)


    /******************************************************************************
     ENABLE CODE FLASH SELF-PROGRAMMING
    ******************************************************************************/
    /* Set this to 0 when programming code flash while executing in RAM.
     * Set this to 1 when programming code flash while executing from another
     * segment in ROM (possible only with RX64M, RX71M, RX65N-2, RX72M groups).
     * See section 2.16 in the App Note.
     */
    #define FLASH_CFG_CODE_FLASH_RUN_FROM_ROM   (1)

     

Children
  • 紹介していただいたサンプルコードを改めてダウンロードしてみましたが、

    main.c では

    flash_copy_vector_table()を実行しているコードになっています。

    /* (no need to copy vector table to RAM because のコメントも

    /* Copy vector table to RAM if interrupts となっていまして、ベクタコピーを実施していると思えます。

    FLASH_CFG_CODE_FLASH_RUN_FROM_ROM の設定を1に設定すると、
    ベクタコピーをしてもしなくても動作しないのは同じです。

    セクションの指定で、RPFRAM を設定しているのと、
    ROMからRAMへマップするセクションでPFRAM=RPFRAM を設定していますが、
    FLASH_CFG_CODE_FLASH_RUN_FROM_ROM を1に設定する場合はこれらの設定も無しとすべきだと思いましたが
    いかがでしょうか?
  • ka.makiharaさん、こんにちは。NoMaYです。

    RX64Mのデモプログラムは2つありますよ。違う方を参照されていませんか?

  • 失礼しました、flash_demo_rskrx64m_runrom の方でしたか。

    こちらで使用していたのは、flash_demo_rskrx64mでした。

  • ka.makiharaさん、こんにちは。NoMaYです。

    試しに、flash_demo_rskrx64m_runromのmain.cを手元のRX72Nのプロジェクトで使ってみましたが、コードフラッシュの書き換えは出来ました。(RX72Nはタイプ4ということでしたのでR_FLASH_Control(FLASH_CMD_LOCKBIT_DISABLE, NULL)は外しましたけれども。逆にRX71MはRX64Mと同じくタイプ3ということのようですので必要なままの筈と思います。)

  • NoMaYさん、こんにちは。

    こちらも試しに、runrom のプロジェクトを実行してみました。(スマートコンフィグでRX71Mに変更)

    コードフラッシュの書き換えも無事に実行することができました。

    一点、気になったのが、セクション設定で設定していたRPFRAMの追加やROM,RAMマッピングの設定が無いという事です。コードのコピーが無いので当然と思えるので

    実際にテストしているプロジェクト(CS+)でセクション設定、ROM,RAMマッピングを消去しましたが、

    こちらは、(E) F0563100 F0563100:Section address overflow out of range : "RPFRAM" となってしまいました。

    r_flash_rx のコンポーネント設定はどちらも同じにしてあるので、何が影響してoverflow... となっているのか、わかりません。

    runromプロジェクトのmapファイルを見ると、PFRAMセクションはありましたが、RPFRAMはありませんでした。

    何がRPFRAMを必要としているのか調べる方法をご存知ないでしょうか?

  • 自己解決しました。

    内部にR_BSP_SECTOP(RPFRAM);があったので、こちらを消去したところoverflow はなくなりました。

    記述してあるだけで、overflowになるんですね。

    エラーがなくなったところで実行して、無事にベクタコピー無し、ROMでの実行でコードフラッシュの書き換えが実行できました。

    ありがとうございます。