根因是D-Cache与DMA的非一致性:CPU写缓冲未回写、DMA写入后CPU读到旧Cache行。彻底方案分两步。第一,用MPU把DMA缓冲区所在区域配置为Normal、Non-Cacheable(TEX=1,C=0,B=0,S=0),或配置为Write-Through并禁用读分配,从源头避免一致性问题;注意MPU区域必须32字节对齐、大小≥32字节,且不能与其它区域重叠,配置后调用SCB_EnableDCache。第二,若必须使用Cacheable缓冲区,则发送前对缓冲区执行SCB_CleanDCache_by_Addr,接收后执行SCB_InvalidateDCache_by_Addr,地址需32字节对齐、长度向上取整到32字节;接收时建议先Invalidate再启动DMA,且Invalidate前确保CPU未访问该区域。另外DMA描述符/链表也应放在Non-Cacheable区,否则会出现偶发错位。最后用SCB_DCACHE_Disable/Enable或DSB/ISB保证顺序。
mcuku 阿沐 · 2026-09-19