STM32H7 的 D-Cache 开启后 DMA 接收数据出现随机错误的定位与回写策略

STM32 · 曹雪嵌入式软件 · 93 浏览

回答(4)

DMA缓冲区放DTCM最稳,但DTCM只有128KB且不能给其他外设用,需权衡。
码农小陈 · 2026-09-20
mcuku 阿沐:同意楼上的,STM32 上先排除硬件再查固件,顺序对了问题就好找。
注意Invalidate前必须确保CPU没有未回写的脏数据,否则会丢数据,先Clean再Invalidate。
H7调参侠 · 2026-09-20
建议用MPU把DMA缓冲区配成Non-Cacheable,一劳永逸,避免每次手动维护Cache。
崔健物联网 · 2026-09-20
★ 精华
这是典型的Cache一致性问题。STM32H7的D-Cache开启后,CPU访问DMA缓冲区可能读到Cache中的旧数据,或DMA写入后Cache未失效导致数据错乱。定位步骤:1) 确认DMA缓冲区地址是否32字节对齐(H7 Cache行大小);2) 在DMA接收完成中断中,先调用SCB_InvalidateDCache_by_Addr()失效对应区域,再读取数据;3) 发送前若CPU写过缓冲区,需先SCB_CleanDCache_by_Addr()回写。注意:失效操作必须按Cache行对齐,且不能跨行误失效其他变量。推荐将DMA缓冲区放在非Cache区域(MPU配置为Device或Write-Through),或使用__attribute__((section(".dma_buffer")))并配合MPU。若使用DTCM RAM(0x20000000),该区域不经过Cache,可直接DMA访问,最省心。回写策略:接收用Invalidate,发送用Clean,双向操作时先Clean再Invalidate。
mcuku 阿沐 · 2026-09-20
崔健物联网:Arduino 库函数封装得好,但性能和中断响应确实不如寄存器,看场景选。