STM32 使用 DMA 传输时,如何精确计算并规避 Cache 一致性问题(以 DCache 为例)

· 1 浏览

回答(4)

若使用双缓冲DMA(如音频流),可交替Clean/Invalidate两个缓冲区,利用DMA传输时间隐藏Cache操作延迟,实现零拷贝且无阻塞。
硬件控阿强 · 2026-08-27
计算长度时务必用((len + 31) & ~31)向上对齐,且地址也要对齐,否则SCB函数会断言失败。建议在调试时开启Cache的ECC或错误检测,快速定位未对齐访问。
码农小飞 · 2026-08-27
除了手动Clean/Invalidate,可配置MPU将DMA缓冲区设为非Cacheable(如Normal, Non-Cacheable),彻底规避一致性问题,但会牺牲该区域的CPU缓存性能,适合低频大数据传输。
嵌入式老周 · 2026-08-27
在STM32(如H7系列)使用DMA且启用DCache时,Cache一致性问题的核心是:CPU通过Cache读写数据,而DMA直接访问内存,两者可能看到不一致的数据。精确计算需基于传输方向和缓冲区地址对齐。规避策略:1)若DMA外设到内存(读),在DMA启动前调用SCB_InvalidateDCache_by_Addr(地址需32字节对齐,长度向上取整到32的倍数),传输完成后再次Invalidate,确保CPU读到最新数据;2)若内存到外设(写),在DMA启动前调用SCB_CleanDCache_by_Addr,将Cache内容写回内存,传输期间避免CPU修改该缓冲区;3)若双向,则先Clean再Invalidate。实操建议:将DMA缓冲区定义为__ALIGNED(32)且大小按32字节对齐,减少操作开销;使用DMA的Half-Transfer和Transfer Complete中断,在回调中按需Clean/Invalidate,避免全程禁用Cache导致性能下降。注意:若缓冲区未对齐,需手动处理首尾非对齐部分,否则可能引发总线错误或数据错乱。
mcuku 阿沐 · 2026-08-27