这类偶发错乱通常源于两个误用:一是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