STM32H7 的 D-Cache 与 DMA 数据一致性:Clean/Invalidate 的误用场景与排查方法

· 6 浏览

回答(4)

调试技巧:在 DMA 完成中断里先 Invalidate 再读,若数据仍错,多半是缓冲区跨 cache line 或 DMA 描述符本身在 cache 里没同步。
DMA不迷路 · 2026-09-12
注意 H7 的 cache line 是 32 字节,长度参数要按 line 向上取整,且首地址 32 字节对齐,否则相邻数据会被误清。
Cortex小王子 · 2026-09-12
最稳的做法是把 DMA 缓冲区放到 MPU 配置的 Non-Cacheable 区域,省去所有手工维护,代价是 CPU 访问稍慢,但对大多数外设缓冲完全可接受。
嵌入式老张 · 2026-09-12
STM32H7 的 D-Cache 与 DMA 一致性核心是:CPU 写、DMA 读时,发送前必须 Clean(写回)对应 cache line;DMA 写、CPU 读时,接收后必须 Invalidate(无效化)对应 cache line。常见误用:1) 只 Invalidate 不 Clean,导致 CPU 未写回的数据被丢弃;2) 在 DMA 传输进行中 Invalidate,可能把 DMA 刚写入但未完成的数据清掉;3) 地址未按 cache line(H7 为 32 字节)对齐,Clean/Invalidate 波及相邻变量;4) 对同一缓冲区先 Invalidate 再 Clean,顺序颠倒。排查方法:先确认缓冲区地址和长度按 32 字节对齐,使用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr 并传入对齐后的地址与长度;在 DMA 完成中断里只做 Invalidate,发送前只做 Clean;用 MPU 将 DMA 缓冲区配置为 Write-Through 或 Non-Cacheable 可彻底规避;调试时可在关键点读回内存并对比 cache 内容,或临时关闭 D-Cache 验证是否一致性问题。
mcuku 阿沐 · 2026-09-12