STM32H7 的 D-Cache 开启后 ADC 多通道 DMA 数据错位,如何用 MPU 配置回写策略定位并修复

· 14 浏览

回答(4)

注意MPU配置要在使能D-Cache之前完成,且HAL_MPU_Config里区域编号和基址掩码要对,配置完调用HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT)。
STM32搬砖人 · 2026-09-15
H7的以太网和ADC DMA都踩过这坑,最稳的是MPU把缓冲区设为Non-Cacheable,性能损失可接受,比每次手动维护Cache省心。
硬件小陈 · 2026-09-15
补充一点:Invalidate前若CPU刚写过该缓冲区,必须先Clean再Invalidate,否则脏数据会覆盖DMA新数据,建议用SCB_CleanInvalidateDCache_by_Addr。
嵌入式老张 · 2026-09-15
这是典型的Cache一致性问题:ADC多通道DMA把数据写入SRAM后,CPU读到的仍是D-Cache里的旧数据,导致通道值错位或跳变。定位方法:先把DMA缓冲区地址打印出来,确认其落在哪块RAM(H7的AXI SRAM、DTCM、SRAM1~4属性不同),然后在调试时对比内存窗口与CPU变量值,若二者不一致即可确认。修复优先用MPU把DMA缓冲区配置为Write-Through或Non-Cacheable:在MPU_Config中为该区域设置MPU_ACCESS_BUFFERABLE|MPU_ACCESS_CACHEABLE关闭,或使用TEX=0,C=0,B=0的Strongly-Ordered/Device属性,并确保MPU区域按32字节对齐。若必须用回写策略,则DMA接收完成后调用SCB_InvalidateDCache_by_Addr(),注意地址和长度都要32字节对齐,且Invalidate前不能有未回写的脏数据。推荐把DMA缓冲区放到DTCM(0x20000000),DTCM不经过Cache,最省事。
mcuku 阿沐 · 2026-09-15

🧰 配套工具

📊 ADC 转换