Cortex-M Cache、MPU 与 DMA 一致性实战:把 STM32H7 这类高性能 MCU 跑稳跑快

前言:高性能 MCU 最隐蔽的坑,不是算力不够,而是数据“不一致” 很多人第一次从 Cortex-M3 / Cortex-M4 迁移到 Cortex-M7,感受非常直接:主频更高了,FPU 更强了,片上 SRAM 更大了,外设带宽也上来了。以 STM32H7、NXP i.MX RT、部分国产高性能 MCU 为例,系统里开始出现 I-Cache、D-Cache、AXI SRAM、多级总线矩阵、MDMA、ETH、SDMMC、DCMI、LTDC 这类过去在小 MCU 上不太需要认真处理的模块。代码还是 C,外设还是 DMA,调试器还是能单步,但一旦项目进入图像采集、以太网、文件系统、音频流或者屏幕刷新,问题会变得很诡异: DMA 明明已经写完了缓冲区,CPU 读到的还是旧数据; CPU 明明把发送包填好了,以太网 DMA 发出去的却是上一帧; 关掉 D-Cache 后系统稳定了,但吞吐掉了一大截; 加了一句 SCB_CleanDCache_by_Addr() 后偶尔好、偶尔坏; 同样的代码 Debug 版本正常,Release 版本或者换了优化等级就出错; 缓冲区长度不是 32 字节倍数时,旁边的变量被“莫名其妙”污染。 这些现象的根源通常不是外设驱动写错,也不是编译器“玄学”,而是 CPU、Cache、MPU、DMA 对同一段内存的理解不一致。Cortex-M7 的 D-Cache 提升了 CPU 访问速度,但 DMA 控制器通常不会经过 D-Cache,它直接从 SRAM 或外部 RAM 读写。于是同一个地址,在 CPU 看来可能是 Cache Line 里的新数据,在 DMA 看来却是内存里的旧数据;反过来,DMA 已经把新数据写入内存,CPU 仍然命中旧的 Cache Line。...

June 8, 2026 · 8 min · 👁️ 0 · Tech Snippets