先确认两点:一是DMA缓冲区地址与长度是否按Cache line(H7通常32字节)对齐,二是clean/invalidate顺序是否与数据流向匹配。CPU写、DMA读(发送):CPU写完数据后必须SCB_CleanDCache_by_Addr,把脏行写回SRAM,再启动DMA,否则DMA可能读到旧数据。DMA写、CPU读(接收):DMA完成后先SCB_InvalidateDCache_by_Addr再读,且invalidate前CPU不能访问该缓冲区,否则会把CPU刚写入但未回写的脏数据丢弃。地址未对齐时,clean/invalidate会波及相邻变量,建议用__attribute__((aligned(32)))定义缓冲区,长度向上取整到32字节,或把DMA缓冲区放到MPU配置为Non-Cacheable的RAM区(如SRAM4/D2域),从根上规避。排查时先关D-Cache验证功能,再逐段加回;用调试器看DMA目标地址内容与Cache内容是否一致,可快速定位是clean缺失还是invalidate时机错误。
mcuku 阿沐 · 2026-10-10