CUBE_MX_ MPU内存保护——+避雷
STM32H743+CubeMX-梳理MPU的设置_background region privileged accesses only-CSDN博客

其中MPU的保护模式有4种:
Background Region Background Region Access Not Allowed + MPU Disable during hard fault , NMI and FAULTMASK handlers (PRIVDEFENA = 0 + HFNMIENA = 0)
Background Region Access Not Allowed + MPU Enable during hard fault , NMI and FAULTMASK handers (PRIVDEFENA = 0 + HFNMIENA = 1)
Background Region Privileged access only + MPU Disable during hard fault , NMI and FAULTMASK handlers (PRIVDEFENA = 1 + HFNMIENA = 0)
Background Region Privileged access only + MPU Enable during hard fault , NMI and FAULTMASK handers (PRIVDEFENA = 1 + HFNMIENA = 1)
MPU 的控制模式由MPU_CTRL(MPU 控制寄存器)的两个关键位定义,这是判断的核心:
这个模式切换就是控制这两个寄存位
| 控制位 | 作用说明 |
|---|---|
| PRIVDEFENA | 决定 “背景区域”(未被 MPU 配置覆盖的内存)的访问权限: - 0 = 背景区域禁止访问; - 1 = 背景区域仅特权模式可访问。 |
| HFNMIENA | 决定 “硬 fault、NMI、FAULTMASK 激活期间”MPU 是否使能: - 0 = 这些异常期间 MPU禁用; - 1 = 这些异常期间 MPU启用。 |
这里避雷一点 一起用,配置MPU后,Keil软件默认会配置RAM内存0x24000000,当我们使用MPU管理RAM内存0x24000000时就会发生冲突了在Keil上的程序卡死问题原因是keil中
1.如果一定要管理0x24000000的内存区域,则修改启动默认地址
2.否则修改管理的内存区

CubeMX-配置MPU后,在Keil上的程序卡死 - ST MCU
正点原子保护代码举例分析:
/**
* @brief 设置需要保护的存储块
* @param 无
* @note 必须对部分存储区域进行MPU保护,否则可能导致程序运行异常
* 比如MCU屏不显示,摄像头采集数据出错等等问题...
*/
void mpu_memory_protection(void)
{
/* 保护MCU LCD屏所在的FMC区域,共64M字节 */
mpu_set_protection( 0x60000000, /* 基地址 */
MPU_REGION_SIZE_64MB, /* 长度 */
MPU_REGION_NUMBER0, /* NUMER2 */
MPU_REGION_FULL_ACCESS, /* 全访问 */
MPU_ACCESS_NOT_SHAREABLE, /* 禁止共享 */
MPU_ACCESS_NOT_CACHEABLE, /* 允许cache */
MPU_ACCESS_BUFFERABLE); /* 允许缓冲 */
/* 保护整个D1 SRAM 512KB */
mpu_set_protection( 0x20000000, /* 基地址 */
MPU_REGION_SIZE_512KB, /* 长度 */
MPU_REGION_NUMBER1, /* NUMER1 */
MPU_REGION_FULL_ACCESS, /* 全访问 */
MPU_ACCESS_NOT_SHAREABLE, /* 允许共享 */
MPU_ACCESS_NOT_CACHEABLE, /* 允许cache */
MPU_ACCESS_BUFFERABLE); /* 允许缓冲 */
/* 保护SDRAM区域,共32M字节 */
mpu_set_protection( 0XC0000000, /* 基地址 */
MPU_REGION_SIZE_32MB, /* 长度 */
MPU_REGION_NUMBER2, /* NUMER2 */
MPU_REGION_FULL_ACCESS, /* 全访问 */
MPU_ACCESS_NOT_SHAREABLE, /* 禁止共享 */
MPU_ACCESS_NOT_CACHEABLE, /* 允许cache */
MPU_ACCESS_BUFFERABLE); /* 允许缓冲 */
/* 保护NAND FLASH区域,共256M字节 */
mpu_set_protection( 0X80000000, /* 基地址 */
MPU_REGION_SIZE_256MB, /* 长度 */
MPU_REGION_NUMBER3, /* NUMER2 */
MPU_REGION_FULL_ACCESS, /* 全访问 */
MPU_ACCESS_NOT_SHAREABLE, /* 禁止共享 */
MPU_ACCESS_NOT_CACHEABLE, /* 允许cache */
MPU_ACCESS_BUFFERABLE); /* 允许缓冲 */
}
.背景区域访问权限(PRIVDEFENA = 0)
代码注释明确目的是 “保护特定内存区域”(FMC、SRAM、SDRAM、NAND FLASH),且仅给这些区域配置了 “全访问权限”。
若要实现严格的 “保护”,需禁止访问未被配置的背景区域(避免越界访问未知内存),因此必然设置 PRIVDEFENA = 0(背景区域禁止访问)。
若设置为 1(仅特权可访问),则特权模式仍能访问背景区域,与 “保护” 的核心意图矛盾。
异常期间 MPU 使能状态(HFNMIENA = 1)
硬 fault、NMI 等是系统高优先级异常,通常由内存访问错误(如越界)触发。若此时禁用 MPU(HFNMIENA=0),异常处理程序可能不受限制地访问内存,进一步扩大错误风险。
常规安全配置会选择 HFNMIENA = 1(异常期间 MPU 仍启用),确保异常处理程序也需遵守 MPU 的内存保护规则,避免二次错误。
最终结论
这段代码对应的 MPU 控制模式是:
Background Region Access Not Allowed + MPU Enable during hard fault, NMI and FAULTMASK handlers(第二个选项)。

下面这些选款则是设置保护区域的,也和正点原子的代码部分一个作用,这里方便起见,使现成代码,对保护区域分区

主函数初始化调用这句话便可以 实现区域保护
更多推荐


所有评论(0)