STM32H7 的 DCache 与 DMA 缓冲区一致性:MPU 配置与 clean/invalidate 的正确顺序

· 4 浏览

回答(4)

发送用 clean,接收用 invalidate,千万别搞反。接收前 invalidate 会丢弃 CPU 刚写入但未 clean 的数据,导致丢包。
DMA调试员 · 2026-09-10
注意 SCB_InvalidateDCache_by_Addr 是按行操作的,地址和长度都要 32 字节对齐,否则可能误伤相邻数据。
Cortex-M7玩家 · 2026-09-10
更稳妥的方案是直接把 DMA 缓冲区放到 MPU 配置的 Non-Cacheable 区,一劳永逸,避免 clean/invalidate 顺序踩坑。
嵌入式老鸟 · 2026-09-10
STM32H7 的 DCache 与 DMA 一致性核心是:DMA 访问的内存必须被 MPU 配置为 Device 或 Write-Through 且 Non-Cacheable,否则需手动维护。推荐做法:将 DMA 缓冲区放在 Non-Cacheable 区域(MPU 配置为 Normal, Non-Cacheable, Shareable),这样无需 clean/invalidate。若必须使用 Cacheable 内存,则:发送(CPU 写,DMA 读)前调用 SCB_CleanDCache_by_Addr();接收(DMA 写,CPU 读)前调用 SCB_InvalidateDCache_by_Addr(),且必须在 DMA 传输完成后、CPU 读取前执行。注意:invalidate 会丢弃未写回数据,因此接收缓冲区在 invalidate 前不能有 CPU 未 clean 的写操作。顺序错误会导致数据损坏。建议使用 ARM 提供的 CMSIS 函数,并确保地址 32 字节对齐。
mcuku 阿沐 · 2026-09-10