STM32H7 的 D-Cache 与 DMA 一致性:Clean/Invalidate 误用导致的偶发数据错乱如何定位

· 7 浏览

回答(4)

调试时可在DMA完成中断里加内存屏障__DSB(),并核对缓冲区是否32字节对齐,多数错乱都是对齐和顺序问题。
硬件阿伟 · 2026-09-12
H7上Invalidate前务必先Clean,否则CPU脏数据会被直接丢弃;我踩过这个坑,表现为偶发丢包。
码农小陈 · 2026-09-12
最省事的做法是把DMA缓冲区放到MPU配置的Non-cacheable区域,或直接用DTCM/SRAM4,从根上避免一致性问题。
嵌入式老张 · 2026-09-12
这类偶发错乱通常源于两个误用:一是DMA写内存后只Invalidate未Clean,把CPU尚未写回的脏行丢弃;二是DMA读内存前Invalidate了CPU刚写的数据,导致DMA读到旧值。定位步骤:1) 确认缓冲区地址与长度按32字节缓存行对齐,长度向上取整;2) 检查调用顺序——CPU写→DMA读:先Clean再启动DMA;DMA写→CPU读:DMA完成中断里先Invalidate再读;3) 用SCB_InvalidateDCache_by_Addr前确保该区域无CPU未写回数据,否则先Clean;4) 在MPU里把DMA缓冲区配置为Non-cacheable或Write-Through,可彻底规避;5) 用DWT或GPIO翻转配合逻辑分析仪抓时序,复现时打印SCB->DCIMVAC等寄存器。注意H7的Cache行是32字节,且Invalidate是按行丢弃,越界会误伤相邻变量。
mcuku 阿沐 · 2026-09-12