STM32H7 的 L1 Cache(I-Cache+D-Cache)是提升系统性能的关键,但错误使用会导致外设异常、数据错乱等问题。核心结论:L1 Cache 需满足 “MPU 分区定义 + Cache 策略匹配 + 数据一致性维护”,三者缺一不可 —— 仅启用 Cache 不配置 MPU,或忽略 DMA 场景的一致性处理,必然引发功能故障。
资料获取:开发经验 | LAT1572 STM32H7的Cache Level1配置相关话题
1. Cache 核心认知:先搞懂 3 个关键概念
1.1 L1 Cache 基础架构
- I-Cache(指令缓存):存储 CPU 预取的指令,加速代码执行,独立于 D-Cache;
- D-Cache(数据缓存):存储数据读写内容,利用时间 / 空间局部性减少内存访问延迟;
- Cache Line:数据交换最小单位(Cortex-M7 为 32 字节),操作需 32 字节对齐,否则影响维护效率。
1.2 关键读写策略
| 策略类型 | 核心逻辑 | 适用场景 |
|---|---|---|
| 写通(WT) | 写数据时同时更新 Cache 和内存,无 Dirty 标记,数据一致性好但总线开销大 | 对一致性要求高的共享数据 |
| 写回(WB) | 写数据仅更新 Cache,标记为 Dirty,替换时才写回内存,总线开销小、速度快 | 独立访问的大数据块(如缓冲区) |
| 读分配(RA) | Cache 缺失时,将内存数据加载到 Cache Line,默认启用 | 多数读密集场景 |
| 写分配(WA) | 写缺失时,先加载内存数据到 Cache 再写入,仅配合 WB 使用 | 重复写同一数据的场景 |
1.3 命中与缺失
- 命中(Hit):CPU 直接从 Cache 读取数据 / 指令,无延迟;
- 缺失(Miss):需从内存加载数据到 Cache,产生延迟,需通过 MPU 配置优化命中率。
2. MPU 与 Cache 的绑定:内存类型决定 Cache 策略
STM32H7 的 Cache 策略由MPU 定义的内存类型决定,不同内存类型的 Cache 配置不可混淆,否则直接失效或出错:
2.1 内存类型与 Cache 策略对应关系
| 内存类型 | 特点 | Cache 策略 |
|---|---|---|
| Normal(Flash/AXI SRAM) | 存储代码 / 数据,无副作用访问 | 可 Cache(WT/WB 可选) |
| Device(外设寄存器) | 访问可能产生副作用(如寄存器状态变化) | 禁止 Cache(Non-Cacheable) |
| Strongly Ordered(系统外设) | 严格按程序顺序访问,不可重排 | 禁止 Cache + 强顺序执行 |
2.2 MPU 配置核心原则
- 必须通过 MPU 划分内存区域,明确每个区域的 “内存类型 + Cache 属性 + 共享性”;
- 未配置 MPU 时,默认按地址映射的 Cache 策略执行(如 SRAM 默认 WB+WA),但自定义场景需手动配置。
3. 数据一致性维护:尤其是 DMA 场景必做
Cache 的 “缓存特性” 会导致 CPU 与 DMA(或多核)访问同一内存时出现数据不一致,这是最常见的踩坑点,需针对性处理。
3.1 一致性问题触发场景
- CPU 写数据到 D-Cache,但未写回内存,DMA 读取内存时拿到旧数据;
- DMA 写数据到内存,但 D-Cache 中仍缓存旧数据,CPU 读取时命中旧数据。
3.2 核心维护方法(基于 CMSIS 函数)
| 操作类型 | 函数作用 | 适用场景 |
|---|---|---|
| Invalidate(无效化) | 标记 Cache Line 为无效,CPU 下次访问直接读内存,不影响内存数据 | DMA 读内存→CPU 读(如 DMA 接收数据) |
| Clean(清理) | 将 Dirty 的 Cache Line 写回内存,不删除 Cache 内容 | CPU 写数据→DMA 读(如 DMA 发送数据) |
| Clean+Invalidate | 先写回内存再无效化,兼顾一致性与缓存刷新 | 双向数据交互(如 DMA 收发缓冲) |
3.3 DMA 场景维护流程
- DMA 接收(内存→CPU):DMA 传输前,对接收缓冲区执行
SCB_InvalidateDCache_by_Addr()(32 字节对齐); - DMA 发送(CPU→内存):CPU 写缓冲后,DMA 传输前执行
SCB_CleanDCache_by_Addr(); - 关键要求:缓冲区地址和大小必须是 32 字节(Cache Line)的整数倍。
4. 实战配置示例:不同内存区域的 MPU+Cache 配置
以下配置基于 HAL 库,直接适配 STM32H743/750 等型号,兼顾性能与稳定性:
4.1 Flash(Normal 内存,高性能配置)
4.2 AXI SRAM(Normal 内存,Cache+WB 策略)
4.3 外设(Device 内存,禁止 Cache)
5. 常见坑与规避方法
5.1 坑 1:Cache Line 未对齐,维护函数失效
- 表现:调用
SCB_CleanDCache_by_Addr()后,数据仍未写回内存; - 规避:缓冲区地址和大小必须是 32 字节(Cortex-M7 Cache Line)的整数倍。
5.2 坑 2:DMA 未维护一致性,数据错乱
- 表现:DMA 发送旧数据,或接收后 CPU 读不到新数据;
- 规避:按 DMA 传输方向执行对应 Cache 操作(接收→Invalidate,发送→Clean)。
5.3 坑 3:MPU 配置错误,Cache 策略失效
- 表现:启用 Cache 后性能无提升,或外设配置不生效;
- 规避:Device/Strongly Ordered 内存必须设为
MPU_ACCESS_NOT_CACHEABLE,Normal 内存需匹配TEX/C/B组合。
5.4 坑 4:写回(WB)模式未 Clean,断电丢失数据
- 表现:CPU 写数据后未执行 Clean,断电后内存数据未更新;
- 规避:关键数据写入后,调用
SCB_CleanDCache()强制写回内存。
6. 核心总结
STM32H7 L1 Cache 的正确使用,本质是 “内存类型定义(MPU)→ Cache 策略匹配 → 一致性维护” 的闭环:
- 用 MPU 划分内存区域,明确 Normal/Device/Strongly Ordered 类型;
- 按内存用途匹配 Cache 策略(Flash/AXI SRAM 启用 Cache,外设禁用);
- 多主控(CPU+DMA)访问时,必做 Cache 一致性操作。
阅读全文
47