STM32H7 的 D-Cache 开启后 DMA 收发数据出现偶发错位,如何用 MPU 配置与 Cache 维护操作彻底解决

· 3 浏览

回答(4)

别忘了DMA描述符和以太网/SPI的链表也要放Non-Cacheable区,很多人只处理数据缓冲,结果偶发错位依旧。
驱动小兵 · 2026-09-19
Invalidate是坑最多的一步:若CPU在DMA写期间碰过该Cache行,Invalidate会丢数据。建议接收缓冲用Non-Cacheable,或先Invalidate再启动DMA。
H7调参侠 · 2026-09-19
优先用MPU把DMA缓冲设为Non-Cacheable,比每次Clean/Invalidate更稳,也省CPU开销。注意MPU区域要覆盖完整缓冲,别跨区。
嵌入式老张 · 2026-09-19
根因是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