STM32H7 的 D-Cache 与 DMA 一致性坑:Clean/Invalidate 顺序错在哪,如何用 MPU 配置 Write-Through 规避

· 5 浏览

回答(4)

注意Cache行大小是32字节,Clean/Invalidate地址和长度都要按32字节对齐,否则会误伤相邻数据。
硬件攻城狮 · 2026-10-05
MPU配Write-Through后,DMA缓冲区的读写性能会下降,但省去手动维护,适合对实时性要求不极端的场景。
STM32小王子 · 2026-10-05
补充:Invalidate前必须确保没有脏数据,否则会丢失。建议接收用Invalidate,发送用Clean,别搞反。
嵌入式老鸟 · 2026-10-05
STM32H7的D-Cache与DMA一致性坑,核心在于Clean/Invalidate的顺序和范围。常见错误:DMA发送前只Invalidate不Clean,导致Cache中脏数据未写回,DMA读到旧值;DMA接收后先Invalidate再读,若Cache中有脏数据,Invalidate会丢弃未写回的数据。正确顺序:发送前对缓冲区执行Clean(写回),接收前先Invalidate(丢弃),接收后若CPU要读则再Invalidate。更稳妥的方案是用MPU将DMA缓冲区配置为Write-Through模式,并设置Non-Cacheable或Write-Through属性。具体:在MPU中为该区域设置TEX=0, C=0, B=0(Strongly ordered)或TEX=1, C=0, B=1(Write-Through, no write allocate)。这样CPU写操作直接透传到SRAM,DMA可见,无需手动Clean;读操作也不缓存,无需Invalidate。注意:Write-Through仍会缓存读,但写直达保证一致性,适合DMA双向缓冲。配置后需调用SCB_EnableDCache()并确保MPU区域对齐(32字节)。实操建议:用HAL库时,在DMA传输前后调用SCB_CleanDCache_by_Addr和SCB_InvalidateDCache_by_Addr,地址按32字节对齐。
mcuku 阿沐 · 2026-10-05