STM32H7 的 D-Cache 与 DMA 协同:地址对齐、Cache 维护和一致性踩坑清单

· 4 浏览

回答(4)

DMA 传输完成中断里再 Invalidate 就晚了,必须在启动 DMA 前就处理好 Cache,顺序不能错。
驱动开发笔记 · 2026-09-15
注意 SCB_CleanDCache_by_Addr 的地址参数需 32 字节对齐,长度也要是 32 的倍数,否则行为未定义。
STM32小王子 · 2026-09-15
MPU 配置为 Non-Cacheable 最省心,但会降低 CPU 访问性能。若缓冲区小且访问频繁,可接受。
嵌入式老鸟 · 2026-09-15
STM32H7 的 D-Cache 与 DMA 协同核心是维护一致性。首先,地址对齐:DMA 缓冲区必须按 Cache 行大小(32 字节)对齐,否则维护操作会误伤相邻数据。建议使用 `__attribute__((aligned(32)))` 或 `ALIGN_32BYTES` 宏。其次,Cache 维护:DMA 写内存(外设到内存)前,需对目标区域执行 `SCB_InvalidateDCache_by_Addr`,避免 Cache 中旧数据覆盖新数据;DMA 读内存(内存到外设)前,需执行 `SCB_CleanDCache_by_Addr`,确保数据写入物理内存。注意:Invalidate 前若缓冲区有未写回数据,会丢失,因此常先 Clean 再 Invalidate。第三,踩坑清单:1) 缓冲区跨 Cache 行导致维护不完整;2) 使用 `SCB_InvalidateDCache` 全局操作影响其他数据;3) DMA 传输中 CPU 访问同一缓冲区导致数据竞争;4) 未考虑写缓冲和乱序执行,需加内存屏障 `__DSB()`。推荐将 DMA 缓冲区放在非缓存区域(如通过 MPU 配置为 Write-Through 或 Non-Cacheable),可一劳永逸。
mcuku 阿沐 · 2026-09-15