RX631のメモリプロテクションユニットの件

IKUZOと申します、RX631のメモリプロテクションユニットの使用方法がわかりません、サンプルコードも探したのですが該当が無いようです、アドバイスをいただけませんでしょうか?

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

    RX62N,RX621グループ用の資料がありますが、RX63N,RX631グループでも参考になりそうな気がします。(すみません、検索して見つかったものをチラ見した程度ですが、、、)

    Renesasキーワード検索: メモリプロテクションユニット
    www.renesas.com/ja-jp/search/keyword-search.html#q=メモリプロテクションユニット

    ドキュメント: RX62N、RX621グループ メモリプロテクションユニットの設定例
    www.renesas.com/ja-jp/doc/products/mpumcu/apn/rx/001/r01an1078jj0100_rx62n.pdf

    サンプルプログラム: RX62N、RX621グループ メモリプロテクションユニットの設定例
    www.renesas.com/ja-jp/software/D3014498.html

  • NoMaYさん
    いつもお世話になっております、有益な資料をお教えいただき感謝します、早速調べまして活用するようにいたします、良い結果が出ましたらまたご報告いたします。
  • NoMaYさん
    Renesasキーワード検索: メモリプロテクションユニット
    www.renesas.com/ja-jp/search/keyword-search.html#q=メモリプロテクションユニット
    これはそのものズバリでした、
    RX62N、RX621グループ メモリプロテクションユニットの設定例
    サンプルコードがございました、ありがとうございました、マニュアルを見ながら四苦八苦しなくてもよさそうです、私の検索の仕方がまずかったようです、至らないところをお教えいただきありがとうございました。
  • メモリプロテクションユニットを追加いたしました、SDRAM部分に書き込み例外を設定すると、即、例外が発生いたします、SDRAM部分というのはリフレッシュ動作しているので、これは書き込み例外の要因になるのでしょうか?、そうではなく、どんな領域でも初期化時に例外が発生いたします、アドバイスお願いできませんでしょうか下記ソースコード

    void mpu_init(void)
    {
    uint32_t check_reg=CLEAR;
    long reg_start[1];
    long reg_end[1];
    reg_start[0]=(_UDWORD)__sectop("PResetPRG");
    reg_end[0]=mpu_reg_set((_UDWORD)__secend("RBF"),0x00000007);//0111 RWXV
    MPU.RSPAGE0.LONG=reg_start[0]; //セクションの開始アドレス
    MPU.REPAGE0.LONG=reg_end[0]; //セクションの終了アドレス(要調整)
    MPU.RSPAGE1.LONG=0;
    MPU.REPAGE1.LONG=0;
    MPU.RSPAGE2.LONG=0;
    MPU.REPAGE2.LONG=0;
    MPU.RSPAGE3.LONG=0;
    MPU.REPAGE3.LONG=0;
    MPU.RSPAGE4.LONG=0;
    MPU.REPAGE4.LONG=0;
    MPU.RSPAGE5.LONG=0;
    MPU.REPAGE5.LONG=0;
    MPU.RSPAGE6.LONG=0;
    MPU.REPAGE6.LONG=0;
    MPU.MPBAC.LONG=0;
    //メモリプロテクション機能を有効
    MPU.MPEN.LONG=(long)1;
    verify_mpu_reg(MPU.RSPAGE0.LONG,reg_start[0])
    verify_mpu_reg(MPU.REPAGE0.LONG,reg_end[0])
    if(check_reg !=0){
    printf("MPUの初期化を失敗!\r");
    }else{
    Change_PSW_PM_to_UserMode();
    }
    }

  • わわいです
    SDRAMをどうやってRXにつなごうとしてますか?それがわからないとこたえようがないですが。
    別の質問もそうなんですが、ちょっとはハードウエアマニュアルを読みましょうよ。

    #右も左もわからない初心者ならともかく。。
  • わわいさん
    「SDRAM」の話を出したので、話がおかしくなってしまいました、当方ROMでも試してみるべきと思いまして今defaultBuildでやっております、完全なROMの部分でございますRWXVを0111で設定しております、Change_PSW_PM_to_UserMode();ユーザーモードにすると即に、例外が発生いたします、「#右も左もわからない初心者」ですわ、わわいさんみたいな長年のソフトやってませんから、まーフォーラムですから気楽にやらせていただいてます、ごめんなさい。
Reply
  • わわいさん
    「SDRAM」の話を出したので、話がおかしくなってしまいました、当方ROMでも試してみるべきと思いまして今defaultBuildでやっております、完全なROMの部分でございますRWXVを0111で設定しております、Change_PSW_PM_to_UserMode();ユーザーモードにすると即に、例外が発生いたします、「#右も左もわからない初心者」ですわ、わわいさんみたいな長年のソフトやってませんから、まーフォーラムですから気楽にやらせていただいてます、ごめんなさい。
Children
  • マニュアルの記述ですが
    1.RSPAGEとREPAGEに設定
    2.MPENに1としてプロテクション=有効
    3.設定内容を比較(設定値==RSPAGEとREPAGEレジスター値)確認
    4.ユーザモードへの移行
    以上のような簡単なものです、
    現状4.の後時点でメモリー例外が発生いたします、例外発生処理に繰り返し飛んで来ます。

    試しに1.RSPAGEとREPAGEに設定をオール0(何も登録しない)にしまして

    4.ユーザモードへの移行した場合にも、メモリー例外が発生いたします。

  • 例外の処理中でレジスターを表示させてみました

    Tでvoid mpu_init(void)を実行するのですが、保護する範囲がFFF00000~FFF559EBでして、これをやると、06が繰り返し表示されます

    void Access_Inst(void)
    {
    // Access_Inst_long=(long)&Access_Inst_default;
    // Access_Inst_();

    CMA=(_UBYTE)MPU.MPESTS.LONG; ←ここで06を繰り返し表示する

    sys_beep(100);
    }
    ///////////////////////////////////////////////////////////////////////
    //アクセス例外
    ///////////////////////////////////////////////////////////////////////

    06とはDRW DA IA 110ですから

    DA ビット(データメモリプロテクションエラー発生ビット)
    オペランドアクセスによるメモリプロテクションエラー発生状態を示します。
    DA ビットは、メモリプロテクションエラーステータスクリアレジスタ(MPECLR)のエラーステータスク
    リアビット(CLR)を“1” にすることによってのみ、“0” になります。
    DRW ビット(データリード/ ライトビット)
    オペランドアクセスによるメモリプロテクションエラーを発生したアクセスのリード/ ライト属性を示し
    ます。DRW ビットは、DA ビットが“1” の場合のみ有効です。
    DRW ビットは、メモリプロテクションエラーステータスクリアレジスタ(MPECLR)のエラーステータス
    クリアビット(CLR)を“1” にすることで、“0” になります。

    ということで、FFF00000~FFF559EBの書き込みはやっていないのですけどね~。

  • マニュアルを見て気が付きました
    MPU.MPBAC.LONG=0;
    ではダメですよね


    MPU.MPBAC.LONG=0xE;
    にしたらどうかな?

  • void mpu_init(void)
    {
    //111 R:Enable,W:Enable,X:Disable,Area_Valid:V
    //1011
    //0:禁止
    //1:許可
    MPU.RSPAGE0.LONG=0;
    MPU.REPAGE0.BIT.REPN=0;
    MPU.REPAGE0.BIT.UAC=7;
    MPU.REPAGE0.BIT.V=0;
    MPU.RSPAGE1.LONG=0;
    MPU.REPAGE1.BIT.REPN=0;
    MPU.REPAGE1.BIT.UAC=7;
    MPU.REPAGE1.BIT.V=0;
    MPU.RSPAGE2.LONG=0;
    MPU.REPAGE2.BIT.REPN=0;
    MPU.REPAGE2.BIT.UAC=7;
    MPU.REPAGE2.BIT.V=0;
    MPU.RSPAGE3.LONG=0;
    MPU.REPAGE3.BIT.REPN=0;
    MPU.REPAGE3.BIT.UAC=7;
    MPU.REPAGE3.BIT.V=0;
    MPU.RSPAGE4.LONG=0;
    MPU.REPAGE4.BIT.REPN=0;
    MPU.REPAGE4.BIT.UAC=7;
    MPU.REPAGE4.BIT.V=0;
    MPU.RSPAGE5.LONG=0;
    MPU.REPAGE5.BIT.REPN=0;
    MPU.REPAGE5.BIT.UAC=7;
    MPU.REPAGE5.BIT.V=0;
    MPU.RSPAGE6.LONG=0;
    MPU.REPAGE6.BIT.REPN=0;
    MPU.REPAGE6.BIT.UAC=7;
    MPU.REPAGE6.BIT.V=0;
    //111 R:Enable,W:Enable,X:Disable
    //0:禁止
    //1:許可
    MPU.MPBAC.BIT.UBAC=7;//111
    MPU.MPEN.LONG=(long)1;//メモリプロテクション機能を有効
    printf("RSPAGE0=0x%08lX\r",MPU.RSPAGE0.LONG );
    printf("REPAGE0=0x%08lX\r",MPU.REPAGE0.LONG );
    printf("MPBAC =0x%08lX\r",MPU.MPBAC.LONG );
    Change_PSW_PM_to_UserMode();//ユザーモードに
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    printf("設定成功\r");
    }

    関数の最後まで、行ってますが、暴走しております(割り込?)、例外は発生していないようです。

  • void Change_PSW_PM_to_UserMode(void)
    {
    MVFC PSW,R1
    ; OR #00100000h,R1
    PUSH.L R1
    MVFC PC,R1
    ADD #10,R1
    PUSH.L R1
    RTE
    NOP
    NOP
    }


    PSW.PM ビットを1にしなければ、暴走しないです、ということはユザーモード後の
    なんらかの不都合があるのか?

  • 関数の最後まで、行ってますが、暴走といいますか、どこかでぐるぐる回っているようです
    pingすると問題ないようです、ウェブサーバー等も問題ないです、つまり割り込みで駆動
    している動作は問題ないです、止まっているのはメインループのみのようです、
    メインループのどこで止まっているのか、PCはどのようになっているのか、
    こういう時はやはりE10のようなエミュレータがあったらいいなと思う次第です。
  • void mpu_init(void)
    {
    ここは省略
    Change_PSW_PM_to_UserMode();//ユザーモードに
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    nop();
    printf("設定成功\r");←ここまでは正常に来ています
    }←ここのリターン先がおかしくなっているのでしょう(スタックが壊れた?)
    //MPUの初期化
    ///////////////////////////////////////////////////////////////////////

    //デバックテスト用
    ///////////////////////////////////////////////////////////////////////
    int cmd_test(char *str)←"T"コマンドでここから開始
    {
    mpu_init();//メモリ保護
    printf("----->ここに来ないです\r");←ここに帰ってこない(ユザーモードにしなければ来ます)
    return CMD_OK;
    }

  • こんにちは。circleです。
    いまひとつIKUZOさんが何をしたくて、
    現状、何が問題なのかが分からないのですが、
    整理してまとめていただけませんでしょうか?

    ハードウェアマニュアルの「表17.1 メモリプロテクションの仕様」に

    "スーパバイザモード時はメモリ保護なし"という記載と関係しているのではないでしょうか?

  • circleさん
    お世話になります、ここでひとまず以前使用していた、YRDKRX63N評価ボードに最初から設定してみたいと思います
    1.intprg_.srcを作成->_Excep_AccessInst
    2.intprg_.srcをプロジェクトに追加
    3.intprg.c のExcep_AccessInst(void){/* brk(); */}をコメントアウト
    4.mpu.cにvoid Access_Inst(void)アクセス例外処理追加
    5.mpu.cにvoid Change_PSW_PM_to_UserMode(void)処理追加
    6.mpu.cにvoid mpu_init(void)処理追加
    7.com.cのコマンドに"T"コマンドからmpu_init(void)を呼び出すように処理追加
    そこでまず、void Change_PSW_PM_to_UserMode(void)のユザーモード設定処理の中の
    OR #00100000h,R1のコードをコメントアウトします、
    8."T"コマンドでmpu_init(void)処理開始
    T
    RSPAGE0=0x00000000
    REPAGE0=0x0000000E
    RSPAGE1=0x00000000
    REPAGE1=0x0000000E
    RSPAGE2=0x00000000
    REPAGE3=0x0000000E
    RSPAGE3=0x00000000
    REPAGE3=0x0000000E
    RSPAGE4=0x00000000
    REPAGE4=0x0000000E
    RSPAGE5=0x00000000
    REPAGE5=0x0000000E
    RSPAGE6=0x00000000
    REPAGE6=0x0000000E
    MPBAC =0x0000000E
    設定成功
    正常にリターンしました.
    Ok
    上記表示はprintfで表示させております
    9.OR #00100000h,R1のコードを有効にして、"T"コマンド
    T
    RSPAGE0=0x00000000
    REPAGE0=0x0000000E
    RSPAGE1=0x00000000
    REPAGE1=0x0000000E
    RSPAGE2=0x00000000
    REPAGE3=0x0000000E
    RSPAGE3=0x00000000
    REPAGE3=0x0000000E
    RSPAGE4=0x00000000
    REPAGE4=0x0000000E
    RSPAGE5=0x00000000
    REPAGE5=0x0000000E
    RSPAGE6=0x00000000
    REPAGE6=0x0000000E
    MPBAC =0x0000000E
    設定成功←関数の最後まで到達しています
    ←関数がリターンしておりません(メインループ停滞)
    デバッグ用の処理
    int cmd_test(char *str)
    {
    mpu_init();
    printf("正常にリターンしました.\r");
    return CMD_OK;
    }
    10.MPU.MPBAC.BIT.UBAC=0;に変更して、"T"コマンド
    T
    RSPAGE0=0x00000000
    REPAGE0=0x0000000E
    RSPAGE1=0x00000000
    REPAGE1=0x0000000E
    RSPAGE2=0x00000000
    REPAGE3=0x0000000E
    RSPAGE3=0x00000000
    REPAGE3=0x0000000E
    RSPAGE4=0x00000000
    REPAGE4=0x0000000E
    RSPAGE5=0x00000000
    REPAGE5=0x0000000E
    RSPAGE6=0x00000000
    REPAGE6=0x0000000E
    MPBAC =0x00000000
    *******************************←Access_Inst(void)アクセス例外処理を何度も呼び出します
    アクセス例外の処理
    uint32_t g_mpu_err_instruction_adrs;
    void Access_Inst(void)
    {
    sci2_put('*');
    MPU.MPECLR.BIT.CLR=1;
    }
    質問:
    9. の段階でのリターンしない原因(例外要因は無し)
    10.例外処理を何度も呼び出す原因(スパーバイザーになるので1度のみのはず)
    よろしくお願いいたします。
  • この折にE1エミュレータ [R0E000010KCE00]の見積もりを販売店にお願いしました。