- MPU通过对存储空间设置区域属性,控制各个区域的读/写/执行等权限;
- MPU0_Handle结构体存储了对MPU存储区域设置参数,包括NMI是否使能,只读,是否可执行,以及区域的基址和顶端地址,
- 此段代码设定区域0x20001000~0x20002000存储空间不可执行的属性,然后在MPU设置前后执行同一段指令,可见在设定了MPU之后,执行触发内存管理中断:
voidAPP_MPU_Test(void) { uint32_tlu32_TempValue; /* 写入汇编指令, 功能->两数相加 */ *(uint32_t*)(0x20001000)=0x9001B082; *(uint32_t*)(0x20001004)=0x98019100; *(uint32_t*)(0x20001008)=0x44089900; *(uint32_t*)(0x2000100C)=0x4770B002; lu32_TempValue=MATH_ADD(111,222); printfS("Math Result: %d \n",lu32_TempValue); MPU0_Handle.u32_HFNMIENA=MPU_HF_NMI_ENABLE; MPU0_Handle.u32_ReadWritePermission=MPU_READ_ONLY; MPU0_Handle.u32_ExecutePermission=MPU_EXECUTE_DISABLE; MPU0_Handle.u32_BaseAddr=0x20001000; MPU0_Handle.u32_LimitAddr=0x20002000; MPU_Config(MPU_REGION_0,&MPU0_Handle); lu32_TempValue=MATH_ADD(111,222);// execute permission disabled, should go to MemManage_Handler }
注:例程(ModulesDemo_Rev2.0.2)中的MPU例程代码,main.c有一个bug,板载CMSIS-DAP调试器连接的串口是UART2,而例程使用的是UART1输出,需要稍微改动 Uart1_Init() 函数:
voidUart1_Init(uint32_tfu32_Baudrate) { Uart1_Handle.Instance=UART2;
- 执行效果如图:
* 可以通过在Keil的Peripherals –> Core Peripherals –> Memory Protection Unit(MPU),在图形化设置界面,直观地设定各个区域的属性,如图:
* 在反汇编可以看到写入的汇编指令,并在寄存器窗口可以看到执行结果:
代码按照EFlash的擦除、写(编程)、读取进行比较,验证擦除以及写入后的EFlash数据内容的正确性。 可以通过Keil的Memory窗口观察EFlash内容:
串口输出内容:
更多回帖