可以用片上MPU单元开辟一块存储区域,通过指令读-写该区域,实现数据的自定义存储-读取。该操作对片上RAM和FLASH同样有效。该操作是动态的,根据需求建立MPU内存区域,用完之后可以释放内存。
除了LM3S101和LM3S102之外,Stellaris M3都有片上MPU单元,有无片上ROM并不影响MPU的使用。1、定义MPU控制区域,使用MPURegionSet函数
// // Configure an executable, read-only MPU region for flash. It is an 8 KB // region with the last 1 KB disabled to result in a 7 KB executable // region. This region is needed so that the program can execute from // flash. // MPURegionSet(0, FLASH_BASE, MPU_RGN_SIZE_8K | MPU_RGN_PERM_EXEC | MPU_RGN_PERM_PRV_RO_USR_RO | MPU_SUB_RGN_DISABLE_7 | MPU_RGN_ENABLE); // // Configure a read-write MPU region for RAM. It is a 64 KB region. There // is a 8 KB sub-region in the middle that is disabled in order to open up // a hole in which different permissions can be applied. // MPURegionSet(1, SRAM_BASE, MPU_RGN_SIZE_64K | MPU_RGN_PERM_NOEXEC | MPU_RGN_PERM_PRV_RW_USR_RW | MPU_SUB_RGN_DISABLE_4 | MPU_RGN_ENABLE);
MPURegionSet的宏定义为:
#define ROM_MPURegionSet \ ((void (*)(unsigned long ulRegion, \ unsigned long ulAddr, \ unsigned long ulFlags))ROM_MPUTABLE[5])
void MPUFaultHandler(void) { // // Preserve the value of the MMAR (the address causing the fault). // Preserve the fault status register value, then clear it. // g_ulMMAR = HWREG(NVIC_MM_ADDR); g_ulFaultStatus = HWREG(NVIC_FAULT_STAT); HWREG(NVIC_FAULT_STAT) = g_ulFaultStatus; // // Increment a counter to indicate the fault occurred. // g_ulMPUFaultCount++; // // Disable the MPU so that this handler can return and cause no more // faults. The actual instruction that faulted will be re-executed. // MPUDisable(); }3、使能MPU出错中断和MPU控制
// // Enable the MPU fault. // IntEnable(FAULT_MPU); // // Enable the MPU. This will begin to enforce the memory protection // regions. The MPU is configured so that when in the hard fault or NMI // exceptions, a default map will be used. // MPUEnable(MPU_CONFIG_HARDFLT_NMI);可用如下程序来核查是否错误
// // Verify that the fault occurred, at the expected address. // if((g_ulMPUFaultCount == 1) && (g_ulFaultStatus == 0x82) && (g_ulMMAR == 0x100)) { RIT128x96x4StringDraw(" OK", 108, 16, 15); } else { bFail = 1; RIT128x96x4StringDraw("NOK", 108, 16, 15); }4、对MPU保护的区域进行读写
// // Disable the MPU, so there are no lingering side effects if another // program is run. // MPUDisable();