资讯动态

4.STM32H743内存保护单元(MPU)

发布时间:2026/10/1 8:27:15 来源:尧图企业网站定制
一、MPU简介STM32H743的MPUMemory Protection Unit内存保护单元是内核级的硬件安全机制核心作用是划分内存区域、限制访问权限比如只读/只写/可执行、校验访问主体CPU特权/非特权模式防止程序错误如数组越界、野指针或恶意代码破坏关键内存如内核数据、外设寄存器是提升系统稳定性和安全性的核心组件。MPU是内核级外设所以在STM32的参考手册中没有相关介绍。需要去看ARM内核手册。MPU的目的是让CPU高效且可靠的访问。1.MPU基础概念STM32H743基于ARM Cortex-M7内核MPU是Cortex-M7内核的标配模块主要能力划分最多8个主区域Region 支持子区域Subregion细分每个主区域可拆分为8个子区域对每个区域设置访问权限特权/非特权、读/写/执行检测非法访问如非特权代码写内核数据、执行RAM中的数据触发硬件故障中断HardFault支持不同内存类型Normal/Device/Strongly Ordered的属性配置匹配总线访问特性。术语通俗解释特权模式Privileged内核的“管理员模式”能访问所有内存/外设通常是操作系统内核、中断服务程序运行的模式非特权模式Unprivileged内核的“普通用户模式”只能访问MPU允许的内存通常是应用任务运行的模式主区域RegionMPU划分的最小独立内存块最小粒度32字节且地址必须是“区域大小的整数倍”子区域Subregion把1个主区域拆成8个相等的小块可单独禁用某几个子区域灵活适配不规则内存内存类型Normal普通内存如SRAM、Device外设寄存器、Strongly Ordered严格有序XNExecute Never“禁止执行”标记该区域不能作为代码运行防止RAM中注入恶意代码执行2.STM32H743的内存布局H743的核心内存区域MPU保护的对象就是这些区域内存类型地址范围核心用途保护需求示例ITCM RAM0x00000000 - 0x0007FFFF指令缓存RAM可执行禁止非特权写、允许执行DTCM RAM0x20000000 - 0x2007FFFF数据缓存RAM禁止执行XN、特权可写AXI SRAM0x24000000 - 0x240FFFFF高速数据RAM非特权只读、禁止执行SRAM1/2/30x30000000 - 0x300FFFFF通用数据RAM按任务划分访问权限外设寄存器0x40000000 - 0x5FFFFFFF外设控制/状态寄存器仅特权可写、禁止执行Flash0x08000000 - 0x08FFFFFF程序存储禁止非特权写、允许执行3.MPU的配置步骤MPU配置的核心是“定义区域→设置权限→使能MPU”以下是基于HAL库的极简示例核心逻辑步骤1禁用MPU配置前必须MPU_Disable(); // 内核函数禁用MPU步骤2配置一个内存区域示例保护AXI SRAMMPU_Region_InitTypeDef MPU_InitStruct {0}; // 1. 配置区域基本信息 MPU_InitStruct.Enable MPU_REGION_ENABLE; // 使能该区域 MPU_InitStruct.Number MPU_REGION_NUMBER0; // 选择第0个主区域 MPU_InitStruct.BaseAddress 0x24000000; // 区域起始地址AXI SRAM起始 MPU_InitStruct.Size MPU_REGION_SIZE_1MB; // 区域大小1MB匹配AXI SRAM MPU_InitStruct.SubRegionDisable 0x00; // 不禁用任何子区域8个子区域都启用 MPU_InitStruct.TypeExtField MPU_TEX_LEVEL0; // 内存类型扩展字段Normal内存 // 2. 配置访问权限 MPU_InitStruct.AccessPermission MPU_REGION_PRIV_RW_UNPRIV_RO; // 特权可读写、非特权只读 MPU_InitStruct.DisableExec MPU_INSTRUCTION_ACCESS_DISABLE; // 禁止执行XN1 MPU_InitStruct.IsShareable MPU_ACCESS_NOT_SHAREABLE; // 非共享SRAM独占 MPU_InitStruct.IsCacheable MPU_ACCESS_CACHEABLE; // 可缓存提升性能 MPU_InitStruct.IsBufferable MPU_ACCESS_BUFFERABLE; // 可缓冲 // 3. 应用配置 HAL_MPU_ConfigRegion(MPU_InitStruct);步骤3使能MPU配置完成后// 使能MPU同时允许特权模式访问默认区域未配置的区域 MPU_Enable(MPU_PRIVILEGED_DEFAULT);4.注意点1. 区域地址/大小必须对齐起始地址必须是“区域大小的整数倍”比如配置1MB区域地址必须是0x24000000、0x24100000等不能是0x24000001区域大小只能选内核支持的固定值32B、64B、128B、256B、512B、1KB、2KB…最大4GB不能自定义。2. 禁用MPU后所有保护失效调试阶段如果触发HardFault可先禁用MPU排查是否是MPU权限配置错误产品发布前必须确保MPU使能且权限配置严谨。3. 中断服务程序ISR运行在特权模式ISR默认是特权模式所以MPU对ISR的限制仅看“特权权限”需确保ISR访问的内存有特权权限如果ISR需要写某块RAM该区域的特权权限必须设为RW读写。4. XN位禁止执行必须开启数据区所有数据RAMDTCM、AXI SRAM、SRAM1/2/3都要设置DisableExec 1防止黑客将代码注入RAM并执行Flash区域通常开启执行DisableExec0但要禁止非特权写。5. 触发HardFault先查MPU如果程序跑飞触发HardFault优先检查是否访问了MPU禁止的区域如非特权写只读区域区域地址/大小是否对齐权限配置是否与访问行为冲突如执行RAM中的数据。5.使用场景简单场景配置“保护Flash禁止非特权写”“保护RAM禁止执行”这是最基础且必要的配置用调试器如ST-Link查看HardFault的栈信息定位MPU违规的具体地址。结合RTOS使用如果用FreeRTOS等RTOS可给不同任务分配非特权模式通过MPU隔离任务内存防止一个任务崩溃影响整个系统RTOS的内核部分运行在特权模式仅开放必要的内存区域给非特权任务。二、MPU使用举例STM32H743的MPU内存保护单元不是“所有场景都必须用”而是针对需要提升系统稳定性、安全性、可靠性的场景设计的硬件机制。一、场景1防止程序错误导致的系统崩溃适用场景程序中有数组越界、野指针、栈溢出等常见bug复杂项目如多任务、大代码量中难以通过纯软件排查所有内存错误产品要求“不能因为局部代码错误导致整机死机”如工业控制、智能家居。具体例子保护关键数据区比如把存储系统参数的SRAM区域配置为“仅特权模式可写”非特权的应用代码即使出错也无法篡改关键参数如校准值、设备ID禁止RAM执行代码所有数据RAMDTCM、AXI SRAM开启XN禁止执行即使野指针把数据覆盖成指令CPU也无法执行避免程序跑飞成随机指令限制栈大小给任务栈分配独立的MPU区域一旦栈溢出访问到区域外内存立即触发HardFault提前定位问题而非系统静默崩溃。配置思路// 示例保护系统参数区0x30000000-0x30000FFF4KB MPU_InitStruct.BaseAddress 0x30000000; MPU_InitStruct.Size MPU_REGION_SIZE_4KB; MPU_InitStruct.AccessPermission MPU_REGION_PRIV_RW_UNPRIV_RO; // 非特权只读 MPU_InitStruct.DisableExec MPU_INSTRUCTION_ACCESS_DISABLE;二、核心场景2隔离特权/非特权代码适用场景使用FreeRTOS、RT-Thread等RTOS需要“任务隔离”一个任务崩溃不影响其他任务/内核系统分为“内核层特权”和“应用层非特权”需限制应用层的访问范围 第三方代码/用户自定义代码运行在非特权模式防止其破坏系统内核。具体例子RTOS任务隔离给每个应用任务分配独立的MPU区域如任务栈、任务私有数据仅开放该任务需要的内存/外设即使任务出错也只能触发自身的HardFault内核和其他任务仍能正常运行内核保护把RTOS内核代码/数据所在的Flash/SRAM配置为“仅特权模式访问”非特权任务无法修改内核的TCB任务控制块、调度器等关键数据外设隔离比如让“电机控制任务”仅能访问TIM/PWM外设寄存器“通信任务”仅能访问UART/SPI外设寄存器防止越权操作外设。配置思路// 示例非特权任务仅能访问UART4外设寄存器0x40004C00-0x40004FFF16KB MPU_InitStruct.BaseAddress 0x40004C00; MPU_InitStruct.Size MPU_REGION_SIZE_16KB; MPU_InitStruct.AccessPermission MPU_REGION_PRIV_RW_UNPRIV_RW; // 非特权可读写 MPU_InitStruct.DisableExec MPU_INSTRUCTION_ACCESS_DISABLE; MPU_InitStruct.TypeExtField MPU_TEX_LEVEL1; // Device内存外设寄存器三、核心场景3提升系统安全性防篡改/防注入适用场景产品面向商用/工业场景需要防止恶意代码注入、关键代码/数据被篡改符合功能安全要求如IEC 61508需通过硬件机制降低故障风险存储敏感数据如密钥、密码的内存区域需要严格保护。具体例子Flash写保护把存储程序的Flash区域配置为“仅特权模式可写烧录/升级时日常运行时设为只读”防止非特权代码篡改程序敏感数据区只读把存储密钥的RAM区域配置为“仅特权模式可写初始化时运行时设为只读”非特权代码只能读取、无法修改禁止外设寄存器非特权写所有外设寄存器默认设为“仅特权可写”仅开放必要外设给非特权代码防止恶意修改外设配置如关闭看门狗。配置思路// 示例Flash程序区0x08000000-0x080FFFFF1MB日常只读 MPU_InitStruct.BaseAddress 0x08000000; MPU_InitStruct.Size MPU_REGION_SIZE_1MB; MPU_InitStruct.AccessPermission MPU_REGION_PRIV_RO_UNPRIV_RO; // 全只读 MPU_InitStruct.DisableExec MPU_INSTRUCTION_ACCESS_ENABLE; // 允许执行程序区四、核心场景4适配不同内存类型的访问规则适用场景系统中混合使用NormalSRAM、Device外设、Strongly Ordered特殊外设内存需要优化内存访问性能如开启缓存同时保证外设访问的正确性禁止缓存。具体例子SRAM开启缓存Normal类型的SRAM配置为“可缓存、可缓冲”提升访问速度外设寄存器禁止缓存Device类型的外设寄存器配置为“不可缓存、不可缓冲”确保读写操作立即生效避免缓存导致的外设控制延迟严格有序内存保护对DMA、以太网等高速外设的内存区域配置为“共享、不可缓存”防止数据一致性问题。配置思路// 示例外设寄存器区0x40000000-0x400FFFFF16MB禁止缓存 MPU_InitStruct.BaseAddress 0x40000000; MPU_InitStruct.Size MPU_REGION_SIZE_16MB; MPU_InitStruct.TypeExtField MPU_TEX_LEVEL1; // Device内存 MPU_InitStruct.IsCacheable MPU_ACCESS_NOT_CACHEABLE; // 禁止缓存 MPU_InitStruct.IsBufferable MPU_ACCESS_NOT_BUFFERABLE; // 禁止缓冲 MPU_InitStruct.AccessPermission MPU_REGION_PRIV_RW_UNPRIV_RO;五、什么时候可以不用MPU简单的裸机项目如LED闪烁、串口打印代码量小、无内存安全风险纯调试阶段优先排查代码逻辑bug再考虑MPU保护对性能要求极致且无安全需求如纯算法运算MPU的少量开销可忽略但建议至少开启“禁止RAM执行”。三、寄存器MPU的寄存器说明截取自《STM32H7编程手册》列名注解Address这个寄存器在处理器里的“地址”你要操作这个寄存器就得通过这个地址找到它Name寄存器的名字比如MPU_TYPE就是“MPU类型寄存器”Type寄存器的操作类型-RO只读只能看不能改-RW读写能看也能改Required privilege操作这个寄存器需要的权限这里都是“Privileged特权级”——只有系统级代码比如内核能操作普通应用程序没权限Reset value处理器刚上电复位时这个寄存器里默认的值Description这个寄存器是干嘛用的MPU的作用是给内存划分“区域”给每个区域设置权限比如哪些代码能读/写/执行这块内存下面是实现这个功能的核心寄存器MPU_TYPE地址0xE000ED90类型是“只读”复位值是0x00000800作用处理器的MPU有啥功能比如支持多少个内存区域是“MPU的身份信息”MPU_CTRL地址0xE000ED94类型是“读写”复位值是0x00000000默认是0代表MPU没开启作用控制MPU的开关比如写1开启MPU写0关闭MPU_RNR地址0xE000ED98类型是“读写”作用选择配置的“内存区域编号”比如你要配置第1个区域就往这里写1MPU_RBAR地址0xE000ED9C类型是“读写”作用设置选中的那个内存区域的起始地址比如你要保护0x20000000开始的内存就把这个地址写进来MPU_RASR地址0xE000EDA0类型是“读写”作用设置这个内存区域的大小和权限比如这块内存是1KB还是只能读不能写剩下的MPU_RBAR_A1、MPU_RASR_A1这些是前面MPU_RBAR/MPU_RASR的“别名寄存器”——功能和对应的主寄存器一样只是地址不同方便快速配置多个区域。比较重要的两个寄存器是MPU_RASR 和控制寄存器。MPU_RASR控制寄存器

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑