STM32H7 的 D-Cache 开启后 DMA 数据错位:地址对齐与 clean/invalidate 的边界怎么处理

· 3 浏览

回答(4)

调试时可用SCB_InvalidateDCache()全无效化快速验证,但正式代码必须按地址范围操作,避免性能损失和竞态。
码农阿强 · 2026-10-05
注意H7的Cache行是32字节,但有些型号如H743是32,H750也是32,别用错。invalidate前务必先clean,否则会丢失未写回的数据。
STM32小王子 · 2026-10-05
更稳妥的做法:把DMA缓冲区放到MPU配置的Non-Cacheable区域,彻底避免clean/invalidate,代价是CPU访问稍慢。
嵌入式老鸟 · 2026-10-05
STM32H7开启D-Cache后,DMA与CPU数据不一致的根因是Cache未同步。处理要点:1) 地址对齐:DMA缓冲区必须按Cache行大小(通常32字节)对齐,且长度向上取整到行边界,否则clean/invalidate会误伤相邻数据。使用__attribute__((aligned(32)))定义缓冲区,或调用SCB_InvalidateDCache_by_Addr等函数时确保地址和长度均为32字节对齐。2) 方向与操作:外设到内存(DMA读)应在DMA启动前invalidate对应区域,DMA完成后再次invalidate(防止CPU预取脏数据);内存到外设(DMA写)应在DMA启动前clean,DMA完成后无需操作。3) 避免CPU与DMA同时访问同一区域,必要时使用MPU将DMA缓冲区配置为Write-Through或Non-Cacheable。4) 推荐使用HAL的SCB_InvalidateDCache_by_Addr/SCB_CleanDCache_by_Addr,并注意传入的地址需32字节对齐,长度需为32的倍数。若数据错位,优先检查对齐和操作顺序。
mcuku 阿沐 · 2026-10-05