在Atmel SAMD51上配置内存保护单元

时间:2019-02-26 15:39:04

标签: arm cortex-m

我正在尝试配置SAMD51(Cortex-M4)的MPU,以保护一个1k的FLASH不受任何访问的影响,而1k的SRAM不受写访问的影响,该写访问将包含不应被访问或损坏的敏感信息(来自SW)错误或其他任何方式。

即使在特权环境中,我也希望保护这些部分(软件没有RTOS,并且将始终处于特权模式)。

由于代码将以特权模式运行,因此我使用MPU_CTRL_PRIVDEFENA_Msk标志,并希望仅覆盖我的两个区域的访问权限。

我已经检查了这些部分的对齐要求:

  • 区域0(以FLASH格式)@ 0x0001d400(对齐1k)
  • 区域1(在SRAM中)@ 0x20000000(1k对齐)

在我的代码下面找到配置MPU:

__disable_irq();

//
// Region0
//
__DSB();
__ISB();
MPU->RNR = 0;
MPU->RBAR = (0x0001d400 << MPU_RBAR_ADDR_Pos);
// 1k size - log2(1k) = 10
MPU->RASR  = ((10 - 1) << MPU_RASR_SIZE_Pos); 
// Normal; Not shareable; Cacheable; Inner Write back; no write allocate
MPU->RASR |= ((0x4 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos)); 
// No priviledged or unpriviledge access
MPU->RASR |= (0UL << MPU_RASR_AP_Pos);
// Enable
MPU->RASR |= 1UL;

//
// Section 1
//
__DSB();
__ISB();
MPU->RNR = 1;
MPU->RBAR = (0x20000000 << MPU_RBAR_ADDR_Pos);
// 1k size - log2(1k) = 10
MPU->RASR  = ((10 - 1) << MPU_RASR_SIZE_Pos); 
// Normal; Not shareable; Cacheable; Inner Write back; no write allocate
MPU->RASR |= ((0x4 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos)); 
// Read-Only Priviledged or unpriviledge access
MPU->RASR |= (6UL << MPU_RASR_AP_Pos);
// Enable
MPU->RASR |= 1UL;

// Enable MPU
MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_HFNMIENA_Msk | MPU_CTRL_PRIVDEFENA_Msk;
// Enable MemFault handler
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
__DSB();
__ISB();
__enable_irq();

似乎配置被忽略,并且在访问配置的区域时从不产生故障。

我已经阅读了ARM文档很多次,看不到有什么问题...

  • 我的代码有错误吗?
  • SAMD51的缓存/内存配置是否错误?
  • 保持特权模式是我无法实现的吗?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

在您的代码中有一些明显的问题。 请参考以下位字段:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/BIHHGADD.html

从一开始: 1:为什么要在这里转移基址

MPU->RBAR = (0x0001d400 << MPU_RBAR_ADDR_Pos);

它必须像这样。请参阅此寄存器的位字段。

MPU->RBAR = (0x0001d400);

2:此行无效。由于在设置尺寸时该字段已被设置为零,因此也不正确。为了清除该位,我们使用&操作而不是|。

MPU->RASR |= (0UL << MPU_RASR_AP_Pos);

3:出于测试目的,请尝试关闭缓存。即tex = 1,b = 0,c = 0,s = 0。同时将指令获取位XN设置为禁用指令获取访问权限。