STM32H7 的 D-Cache 开启后 DMA 数据错乱:地址对齐与 clean/invalidate 顺序怎么排

· 7 浏览

回答(4)

DMA接收时如果CPU在DMA期间碰过缓冲区,invalidate会丢数据,所以要么别碰,要么先clean再invalidate。
DMA不迷路 · 2026-10-06
H7的Cache Line是32字节,不是常见的64字节,对齐和长度都按32处理,这点很多人踩坑。
STM32小王子 · 2026-10-06
最省心的做法:把DMA缓冲区放到MPU配置的Non-Cacheable区域,或直接用DTCM/SRAM4,完全不用手动维护cache,代价是访问速度略低。
嵌入式老张 · 2026-10-06
STM32H7开启D-Cache后DMA数据错乱,根因通常是缓存一致性问题。首先地址必须按Cache Line对齐,H7的D-Cache Line为32字节,DMA缓冲区建议用__attribute__((aligned(32)))或ALIGN_32定义,长度也补齐到32字节倍数,否则clean/invalidate会波及相邻数据。其次顺序要分清方向:外设到内存(DMA接收)时,CPU先invalidate对应区域,再启动DMA,DMA完成后再次invalidate,然后CPU才读数据;内存到外设(DMA发送)时,CPU写完数据后先clean,再启动DMA。若用MPU把DMA缓冲区配置为Write-Through或Non-Cacheable,可彻底规避,但会牺牲性能。注意invalidate前若CPU可能写过该区域,必须先clean再invalidate,否则会丢弃未回写数据。推荐用SCB_CleanDCache_by_Addr和SCB_InvalidateDCache_by_Addr,并确保地址32字节对齐。
mcuku 阿沐 · 2026-10-06