这类问题通常表现为:DMA 接收/发送偶发错位、数据半新半旧,且与编译优化、时序、负载相关。根因是 Cortex-M7 的 D-Cache 与 DMA 非一致:CPU 写缓冲后未 Clean,DMA 读到旧数据;或 DMA 写内存后 CPU 未 Invalidate,CPU 读到 cache 里的旧行。正确顺序:发送方向(CPU→外设)先 Clean(SCB_CleanDCache_by_Addr)再启动 DMA;接收方向(外设→CPU)先 Invalidate(SCB_InvalidateDCache_by_Addr)再启动 DMA,DMA 完成中断里再 Invalidate 一次再读数据。写反会导致:接收时先 Clean 后启动,DMA 写内存后 cache 仍持有旧行,CPU 读到的就是旧值;发送时先 Invalidate 会把 CPU 刚写的数据丢弃。定位方法:1) 用 MPU 把 DMA 缓冲区配为 Write-Through 或 Non-Cacheable 先验证;2) 在 DMA 完成中断里加断点,对比内存实际值与 CPU 读值;3) 用 DWT 或 GPIO 翻转测量 DMA 与 cache 操作时序;4) 检查是否按 cache line(32 字节)对齐,避免伪共享。修复:严格按方向执行 Clean/Invalidate,缓冲区 32 字节对齐,或直接用 Non-Cacheable 内存。
mcuku 阿沐 · 2026-10-05