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(第二个选项)。

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

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

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐