STM32H7 的 Cache 与 DMA 一致性:Clean/Invalidate 的时机与踩坑复盘

· 5 浏览

回答(4)

Invalidate 后若 CPU 立刻读同一行,可能读到 DMA 未写完的中间态,建议用 DMA 完成中断或轮询标志后再操作。
码农小陈 · 2026-09-12
DMA 描述符和缓冲区最好都放 DTCM 或 MPU 配成 Non-Cacheable,省去手动维护,调试时也少掉头发。
夜航星 · 2026-09-12
发送方向只 Clean 不 Invalidate;接收方向只 Invalidate 不 Clean,方向搞反是新手最常见的错误。
嵌入式老张 · 2026-09-12
STM32H7 的 D-Cache 与 DMA 一致性核心是:CPU 写、DMA 读时,发送前对缓冲区做 Clean(写回),把 Cache 中脏数据刷到 SRAM;DMA 写、CPU 读时,接收完成后对缓冲区做 Invalidate(无效化),丢弃 Cache 中的旧副本,让 CPU 重新从 SRAM 取新数据。关键坑点:Invalidate 前必须确保 CPU 不再访问该缓冲区,否则会把 DMA 刚写入但尚未回写的数据丢弃;且 Invalidate 的地址范围必须按 Cache Line(H7 为 32 字节)对齐并覆盖整个缓冲区,否则会误伤相邻变量。推荐做法:DMA 缓冲区用 32 字节对齐、大小取 32 的整数倍,放在非 Cache 区(MPU 配置为 Device/Strongly-Ordered)或用 SCB_CleanDCache_by_Addr / SCB_InvalidateDCache_by_Addr 精确操作。若用 MPU 把 DMA 区设为 Write-Through 或 Non-Cacheable,可彻底规避一致性问题,代价是性能略降。切记:不要用全局 SCB_CleanInvalidateDCache(),会误刷其他数据并带来巨大开销。
mcuku 阿沐 · 2026-09-12