文章目录
-
- [MPU 内存保护单元](#MPU 内存保护单元)
-
- M7内核上的数据缓存(D-Cache)结构
- [缓存不一致(Cache Coherency)](#缓存不一致(Cache Coherency))
- 一致性作
- STM32CubeMX配置
-
- [CPU Cache 开启](#CPU Cache 开启)
- MPU配置
-
- 多个Region
- [TEX Field Level: TEX + C + B](#TEX Field Level: TEX + C + B)
- [Access Permission: ALL ACCESS PERMITTED](#Access Permission: ALL ACCESS PERMITTED)
- [Instruction Access: ENABLE](#Instruction Access: ENABLE)
- [Shareability Permission: DISABLE](#Shareability Permission: DISABLE)
- [Cacheable Permission: C部分](#Cacheable Permission: C部分)
- [Bufferable Permission: B部分](#Bufferable Permission: B部分)
- 其他:地址对齐要求
- CG
MPU 内存保护单元
-
MPU 是 Memory Protection Unit (内存保护单元)是现代微控制器(如 STM32H7 的 Cortex-M7 内核)中内置的一个硬件模块,主要作用是监控和管理 CPU 对内存的访问行为 :
- 防止程序"越界" (Access Violation):CPU 尝试写入的瞬间,MPU 发现地址越界,立即阻断操作 并触发
MemManage Fault。程序立刻停在出错的那一行,开发者可以马上知道哪里错了。 - 隔离用户模式与特权模式 (Privilege Levels):操作系统内核(特权模式)和应用程序任务(用户模式)。MPU 可以配置某些关键区域(如内核堆栈、外设寄存器)只允许特权模式访问。如果用户模式的代码试图修改这些区域,MPU 会直接报错。这防止了劣质应用搞崩整个系统。
- 控制缓存策略 (Cache Control) :DMA 控制器直接向内存写数据(如 ADC 采样值),而 CPU 开启了 Cache。CPU 可能从 Cache 里读到旧数据,因为 DMA 绕过了 Cache 直接改了内存。通过配置 MPU,可以将 DMA 使用的缓冲区标记为 "不可缓存 (Non-Cachable)"。这样 CPU 访问该区域时会强制绕过 Cache,直接读物理内存,保证数据一致性,无需软件手动刷新 Cache。
- 定义内存属性 (Memory Attributes):MPU 可以告诉 CPU 某块内存是什么类型的: Normal Memory 、 Device Memory 、 Strongly Ordered。
- 防止程序"越界" (Access Violation):CPU 尝试写入的瞬间,MPU 发现地址越界,立即阻断操作 并触发
| 特性 | MPU (Memory Protection Unit) | MMU (Memory Management Unit) |
|---|---|---|
| 主要代表 | Cortex-M3/M4/M7/M33 (嵌入式 MCU) | Cortex-A 系列 (手机/电脑,如 Linux/Android) |
| 虚拟内存 | 不支持 (物理地址 = 逻辑地址) | 支持 (可以进行地址映射/翻译) |
| 主要功能 | 保护 (防越界) + 属性配置 (缓存/权限) | 虚拟化 + 保护 + 大内存管理 |
| 复杂度 | 低,实时性高,确定性高 | 高,有页表查找开销,实时性稍差 |
| 适用场景 | 实时控制系统 (RTOS, 裸机) | 通用操作系统 (Linux, Windows, Android) |
M7内核上的数据缓存(D-Cache)结构
- DMA与DTCM总线拓扑隔离(物理上连不上):
- 哈佛架构的极致化:Cortex-M7 采用改进的哈佛架构。ITCM 和 DTCM 是通过 CPU 内部的专用端口(Private Ports)直接连接的,不经过片上总线矩阵(Bus Matrix)。
- 零等待周期(0 Wait State):为了让 CPU 在每个时钟周期都能确定性地读写数据,TCM 必须避开总线仲裁、冲突和延迟。如果允许 DMA 访问,就需要引入复杂的仲裁机制,这会破坏 TCM 的"确定性"和"高速"特性。
- DMA 的路径 :DMA 控制器是挂在 AXI 或 AHB 总线上的主设备(Master)。它只能看到挂载在这些总线上的从设备(Slave),比如 SRAM1/2/3、AXI SRAM、Flash 等。TCM 不在这些总线的地址映射范围内。

DMA 写不了 DTCM 是因为路不通 (硬件架构限制);需要维护 Cache 是因为信息不同步 (DMA 绕过了 Cache 直接改内存,得通知 CPU 刷新认知)。

缓存不一致(Cache Coherency)
- Cache 的本质 :Cache 是 SRAM 中数据的副本。CPU 优先读写 Cache,而不是直接读写 SRAM。
- DMA 的绕过行为 :DMA 传输数据时,是直接通过总线写入物理 SRAM 的。DMA 不知道也不关心 CPU 的 Cache 里有没有这份数据的副本,它不会自动更新 CPU 的记事本。
- 后果:物理内存(SRAM)里的数据更新了,但 Cache 里的旧数据还在。如果 CPU 此时去读,就会读到脏数据(Stale Data)。
一致性作
-
操作 A: Invalidate Cache(使缓存失效)
- 何时用 :DMA 写完数据后,CPU 要读取之前。告诉 CPU,"这块内存区域的记事本内容作废了,下次读的时候必须去SRAM重新看最新的"。
- 代码示例 :SCB_InvalidateDCache_by_Addr(...)
-
操作 B: Clean Cache(清洗缓存)
- 何时用 :CPU 修改完数据后,DMA 要读取并发出去之前(例如发送网络包),如果某个 Cache Line 被标记为 Dirty (脏)(即:CPU 修改过数据,但还没写入物理 RAM),CPU 会立即将该行的数据 强制写入物理 RAM。
- 代码示例 :SCB_CleanDCache_by_Addr(...) 字面意思是"按地址清理数据缓存"。但在硬件层面,它的动作是 Write-Back (写回)。
-
操作 C: 用 MPU 避免手动维护
- 将 DMA 使用的缓冲区所在的 SRAM 区域,通过 MPU 配置为 Non-Cachable(不可缓存)。
- CPU 访问这块区域时,强制不走 Cache,直接读写 SRAM。
- 既然不走 Cache,就不存在"副本不一致"的问题了。
- 代价:CPU 读取这块数据的速度会变慢一点点(失去了 Cache 加速),但对于 DMA 缓冲区来说,通常是可以接受的,因为主要瓶颈往往在 DMA 传输速度或外设速度上。
STM32CubeMX配置
CPU Cache 开启

MPU配置

多个Region
- 界面分为多个独立区域:
- Region 0 Settings → 配置第一个内存保护区域
- Region 1 Settings → 配置第二个内存保护区域

- 每个区域都包含以下核心参数:
- 是否启用(Enabled/Disabled)
- 基地址(Base Address)
- 区域大小(Size)
- 子区域禁用掩码(SubRegion Disable)
- TEX 字段级别(TEX field level)→ 决定内存类型
- 访问权限(Access Permission)
- 指令访问权限(Instruction Access)
- 可共享性(Shareability)
- 可缓存性(Cacheable)
- 可缓冲性(Bufferable)
TEX Field Level: TEX + C + B
-
TEX + C + B 组合决定内存类型: Normal Memory 、 Device Memory 、 Strongly Ordered

-
Technical Reference Manual(图片截取M4的MPU,但原理类似):

-
level 0通常对应:- Normal Memory(非设备内存)
- 可被缓存/缓冲(取决于后续标志位)
这张表格总结了 Cortex-M7(及大多数 ARM Cortex 内核)中三种主要内存类型的特性、执行顺序要求及适用场景。这是配置 MPU TEX/C/B 位时的核心依据。
| 特性 | Normal Memory (普通内存) | Device Memory (设备内存) | Strongly Ordered Memory (强序内存) |
|---|---|---|---|
| 性能效率 | 最高 | 中等 | 最低 |
| 执行/访问顺序 | 可重排序 (Reorderable) CPU 可以乱序执行加载/存储,只要最终结果看起来是按顺序的即可。 | 严格次序 (Ordering Preserved) 必须严格按照程序代码的顺序访问,不可重排序。 | 绝对严格 (Strictly Ordered) 不仅顺序严格,且必须等待当前指令完成后才执行下一条。 |
| 合并操作 (Merging) | 允许CPU 可以将多次小的读写合并为一次大的总线事务(如两次半字写合并为一次字写)。 | 禁止每次访问必须独立进行,严禁合并,防止误触相邻寄存器。 | 禁止严禁合并。 |
| 推测访问 (Speculative) | 允许CPU 可以预取数据或提前发起写操作。 | 禁止严禁预取或推测执行,防止产生副作用(如意外触发硬件动作)。 | 禁止严禁预取。 |
| 典型应用场景 | SRAM (DTCM, ITCM, AXI SRAM); Flash 代码区; 普通变量、堆栈 | 外设寄存器 (APB/AHB 总线) ; 帧缓冲区 (Frame Buffer);需要精确时序控制的硬件接口 | 系统启动初期 (Boot ROM) 某些特殊的同步区域;极少在现代 OS/MCU 应用中直接使用 |
| MPU 配置建议 | Cacheable (通常)Bufferable (可选) | Non-Cachable****Non-Bufferable (通常)(必须防止缓存导致读写不同步) | Non-Cachable****Non-Bufferable |
| 错误配置后果 | 若将外设配为 Normal:CPU 可能乱序写寄存器,或合并写操作,导致外设工作异常或硬件锁死。 | 若将 RAM 配为 Device:性能大幅下降,CPU 无法利用总线带宽,系统变慢。 | 若将 RAM 配为 Strongly Ordered:CPU 每条指令都停顿等待,性能灾难性下降。 |
Access Permission: ALL ACCESS PERMITTED
- 特权模式(Privileged)和用户模式(User)均可读写执行。
- 无只读或禁止访问限制。
"Access Permission: ALL ACCESS PERMITTED " 通常出现在 ARM MPU (Memory Protection Unit) 或一些 MCU 的 MPU 配置工具(如 STM32CubeMX) 中,对应的是 AP 位 = Full access。下面给你权威来源和对应解释。
| AP值 | Privileged | Unprivileged | 含义 |
|---|---|---|---|
| 000 | No access | No access | 无访问 |
| 001 | RW | No access | 仅特权 |
| 010 | RW | RO | 用户只读 |
| 011 | RW | RW | Full access(ALL ACCESS PERMITTED) |
Instruction Access: ENABLE
- 允许从该区域取指执行代码。
Shareability Permission: DISABLE
- DISABLE 意味着这块内存不被其他处理器核心或 DMA 控制器"共享"。

Cacheable Permission: C部分
- 不可缓存 → CPU 访问此区域时绕过 Data Cache,直接读写物理内存。
- 这是正确的做法,如果该区域用于 DMA 通信(如 ADC 缓冲区、UART RX/TX 缓冲等),必须设为 Non-Cachable,避免脏数据问题。
Bufferable Permission: B部分
- 允许写操作进入写缓冲区(Write Buffer),提高写入性能。
- 对于 DMA 缓冲区,即使不可缓存,也可以允许缓冲,因为最终还是要写到物理内存。
其他:地址对齐要求
- MPU 区域的基地址和大小必须符合对齐规则:基地址必须是单元的倍数。