IKUZOと申します、RX631のメモリプロテクションユニットの使用方法がわかりません、サンプルコードも探したのですが該当が無いようです、アドバイスをいただけませんでしょうか?
メモリプロテクションユニットを追加いたしました、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(); }}
マニュアルの記述ですが 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にしなければ、暴走しないです、ということはユザーモード後のなんらかの不都合があるのか?