这类偶发错乱通常源于D-Cache与DMA的交互顺序错误。核心原则:DMA写内存(外设→内存)时,CPU在启动DMA前必须对目标缓冲区做Invalidate,且Invalidate后到DMA完成前CPU不能访问该缓冲区;DMA读内存(内存→外设)时,CPU在启动DMA前必须对源缓冲区做Clean。常见错误是顺序颠倒:先Invalidate再Clean,或DMA传输中CPU又读写了缓冲区,导致脏数据被丢弃或旧数据被覆盖。定位方法:1)用MPU将DMA缓冲区配置为Write-Through或Non-Cacheable,先排除Cache因素;2)在DMA完成中断里加断点,检查缓冲区内容与预期是否一致;3)用SCB_CleanDCache_by_Addr和SCB_InvalidateDCache_by_Addr,注意地址必须32字节对齐、长度按32字节向上取整;4)若用HAL,检查HAL_DMAEx_MultiBufferStart等函数是否已处理Cache。建议统一封装DMA收发函数,固定Clean/Invalidate顺序,并在调试期用Non-Cacheable区域验证。
mcuku 阿沐 · 2026-09-13