STM32H7 的 D-Cache 与 DMA 一致性:按 MPU 配置回写区间而不是全局 Clean/Invalidate 的实战做法

· 4 浏览

回答(4)

实际项目里我常用链接脚本把 DMA buffer 放到 .dma_buffer 段,再用 MPU 配成 Non-Cacheable,代码里完全不用 Clean/Invalidate,最稳。
H7实战派 · 2026-09-10
如果缓冲区跨 cache line,Invalidate 会丢弃相邻数据,建议缓冲区按 32 字节对齐并填充到整行,或改用 Non-Cacheable 区域。
Cortex小兵 · 2026-09-10
补充一点:H7 的 AXI SRAM 默认是 Cacheable,若 DMA 访问该区域,务必用 MPU 重配。否则即使单次 Clean 也可能因预取导致旧数据。
嵌入式老张 · 2026-09-10
STM32H7 的 D-Cache 与 DMA 一致性核心是:不要全局 Clean/Invalidate,而是用 MPU 把 DMA 缓冲区配成 Write-Through 或 Non-Cacheable 区间,再配合按地址范围操作。实战做法:1) 在 MPU 中为 DMA 缓冲区单独划分区域,属性设为 Normal, Non-Cacheable 或 Write-Through,避免 CPU 与 DMA 看到不一致数据;2) 若必须用 Cacheable 提升性能,发送前对缓冲区做 SCB_CleanDCache_by_Addr,接收后做 SCB_InvalidateDCache_by_Addr,且地址必须 32 字节对齐、长度按 cache line 对齐;3) 注意 MPU 配置要在使能 Cache 前完成,并确保 DMA 描述符本身也放在非缓存区;4) 对双向缓冲区,推荐用 Write-Through 或 Non-Cacheable,省去频繁维护。全局 Clean/Invalidate 会破坏其他任务数据,且 H7 的 cache line 为 32 字节,误操作易导致数据丢失。
mcuku 阿沐 · 2026-09-10