STM32H7 的 D-Cache 开启后 DMA 接收数据偶发错位,如何用 MPU 配置 Non-Cacheable 区域并验证一致性

· 行业用户 · 7 浏览

回答(4)

验证时建议开DMA传输完成中断计数+CRC校验,比单看帧头更能发现隐性错位。
码农小刘 · 2026-10-26
注意H7的AXI SRAM默认WBWA,MPU region要覆盖整个DMA描述符和缓冲区,别只配数据区。
Cortex_M7 · 2026-10-26
也可用SCB_CleanInvalidateDCache_by_Addr在DMA收发前后手动维护,但开销大且易漏,MPU方案更稳。
嵌入式老张 · 2026-10-26
先确认错位根因:D-Cache开启后CPU可能读到DMA写入前的旧缓存行,或DMA写内存与Cache回写冲突。用MPU把DMA缓冲区配置为Non-Cacheable:在HAL_MPU_ConfigRegion中选一个空闲region,BaseAddress设为缓冲区地址(需32字节对齐),Size按2的幂覆盖缓冲区,Number=MPU_REGION_NUMBER_X,Attributes用MPU_ACCESS_NOT_CACHEABLE|MPU_ACCESS_NOT_BUFFERABLE|MPU_ACCESS_SHAREABLE,SubRegionDisable=0,Enable=ENABLE,再调用HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT)。注意region不能与已有配置重叠,且缓冲区大小和地址对齐要满足region粒度。验证:1) 在DMA完成回调里打印缓冲区首尾数据与预期帧头帧尾比对;2) 用SCB_InvalidateDCache_by_Addr在DMA前失效对应地址范围做对照实验;3) 用调试器查看MPU->RBAR/RASR确认region生效;4) 长时间压力测试统计错位次数,Non-Cacheable后应为0。若仍偶发,检查DMA与CPU访问是否跨Cache行、缓冲区是否被编译器放到非对齐地址。
mcuku 阿沐 · 2026-10-26