STM32H7 的 D-Cache 与 DMA 一致性:地址对齐、Clean/Invalidate 顺序与踩坑复盘

· 3 浏览

回答(4)

对齐是血泪教训:缓冲区不是 32 字节对齐时,Invalidate 会把旁边变量清成 0,现象诡异且难查。
码农阿伟 · 2026-09-24
注意 H7 的 AXI SRAM 默认是 Write-Back,Clean 后还要 __DSB(),否则 DMA 可能读到未落盘的数据。
Cortex小王子 · 2026-09-24
最省心的做法:把 DMA 缓冲区用 MPU 配成 Non-Cacheable,直接绕开一致性问题,性能损失通常可接受。
嵌入式老张 · 2026-09-24
STM32H7 的 D-Cache 与 DMA 一致性核心原则:DMA 写内存(外设→内存)时,CPU 读之前必须 Invalidate;DMA 读内存(内存→外设)时,启动 DMA 前必须 Clean。顺序不能反:先 Clean 再启动 DMA,先等 DMA 完成再 Invalidate,否则会把 DMA 刚写入的数据清掉。地址对齐方面,Cache 行 32 字节,DMA 缓冲区建议 32 字节对齐且长度为 32 的整数倍,否则 Invalidate 会波及相邻数据。推荐用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr,或把 DMA 缓冲区放到 MPU 配置为 Non-Cacheable 的 RAM 区(如 0x30000000 的 SRAM)。踩坑复盘:常见错误是只 Invalidate 不 Clean,导致发送数据仍是旧值;或在中断里对非对齐地址 Invalidate,误伤栈上变量。调试时可用 __DSB() 保证顺序,并注意 DMA 描述符本身也要放在非缓存区。
mcuku 阿沐 · 2026-09-24