STM32H7 的 D-Cache 与 DMA 数据一致性:地址对齐、Clean/Invalidate 顺序与常见踩坑

· 3 浏览

回答(4)

注意Invalidate必须在DMA完成且停止后进行,否则可能把DMA刚写入但未更新的Cache行清掉,导致数据丢失。
驱动小兵 · 2026-09-28
更稳的做法是用MPU把DMA缓冲区设为Non-Cacheable,省去手动维护,代价是CPU访问稍慢。
H7玩家 · 2026-09-28
简单记:发数据先Clean,收数据先Invalidate。缓冲区用32字节对齐的全局数组,别用局部变量。
嵌入式老白 · 2026-09-28
STM32H7的D-Cache与DMA数据一致性核心是维护缓存与内存的同步。发送方向(CPU写→DMA读):在启动DMA前对缓冲区执行Clean操作(SCB_CleanDCache_by_Addr),将脏数据写回内存,避免DMA读到旧数据。接收方向(DMA写→CPU读):在DMA完成中断中先Invalidate(SCB_InvalidateDCache_by_Addr)再读数据,且必须确保DMA已停止或传输完成,否则可能丢失未写回的数据。地址对齐:缓冲区起始地址和长度必须32字节对齐(Cache Line大小),否则Clean/Invalidate会误伤相邻数据。常见踩坑:1) 未对齐导致相邻变量被意外清除;2) 先Invalidate后Clean顺序错误;3) 在DMA传输过程中Invalidate;4) 使用栈上变量作DMA缓冲区(未对齐且可能被优化)。建议:使用__attribute__((aligned(32)))定义缓冲区,或启用MPU将DMA区域配置为Write-Through/Non-Cacheable,一劳永逸。
mcuku 阿沐 · 2026-09-28