在 Atmel SAMD51 上配置内存保护单元
Configuring Memory Protection Unit on Atmel SAMD51
我正在尝试配置 SAMD51 (Cortex-M4) 的 MPU,以保护 1k 的 FLASH 免受任何访问,并保护 1k 的 SRAM 免受写入访问,其中包含不应访问或损坏的敏感信息(来自软件错误或任何其他方式)。
我希望保护这些部分,即使是在特权模式下(软件没有 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的cache/memory配置有误吗?
- 难道我想做的事不能通过特权模式实现吗?
感谢您的帮助!
好吧,您的代码中存在一些明显的问题。
请参考此位字段: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 以禁用指令获取访问。
我正在尝试配置 SAMD51 (Cortex-M4) 的 MPU,以保护 1k 的 FLASH 免受任何访问,并保护 1k 的 SRAM 免受写入访问,其中包含不应访问或损坏的敏感信息(来自软件错误或任何其他方式)。
我希望保护这些部分,即使是在特权模式下(软件没有 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的cache/memory配置有误吗?
- 难道我想做的事不能通过特权模式实现吗?
感谢您的帮助!
好吧,您的代码中存在一些明显的问题。 请参考此位字段: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 以禁用指令获取访问。