STM32H7 的 D-Cache 与 DMA 协同:描述符对齐、Cache Line 回写与一致性排查实战

· 5 浏览

回答(4)

用SCB_CleanInvalidateDCache_by_Addr做双向同步,但地址必须32字节对齐,长度向上取整到32倍数,否则边界行处理有坑。
H7调参侠 · 2026-10-16
Invalidate前务必确保DMA已停止且CPU没在写该区域,否则会丢数据;Clean+Invalidate组合用于双向缓冲区。
Cache踩坑王 · 2026-10-16
描述符区最省事:MPU配成Device或Non-cacheable,彻底免维护,代价是CPU访问稍慢,但描述符访问频率低,完全可接受。
嵌入式老张 · 2026-10-16
STM32H7的D-Cache与DMA协同核心是32字节Cache Line对齐和手动维护一致性。描述符(如ETH、SDMMC、DMA链表)必须按32字节对齐,推荐用__attribute__((aligned(32)))或ALIGN_32BYTES宏,且整个描述符区域大小应为32的整数倍,避免DMA写入时误伤相邻数据。发送方向:CPU写完缓冲区后调用SCB_CleanDCache_by_Addr(addr, len),把脏行回写到SRAM,再启动DMA;接收方向:DMA完成后先SCB_InvalidateDCache_by_Addr(addr, len)再读数据,否则读到旧Cache。注意地址和长度都要32字节对齐,否则函数内部会做非对齐处理但可能失效。排查时先确认MPU是否把DMA缓冲区配置为Non-cacheable或Write-through,若配置为Normal cacheable就必须手动维护。常见坑:缓冲区跨Cache Line导致相邻变量被清掉、DMA传输中CPU访问同一行、中断里读描述符前未Invalidate。建议用MPU把DMA描述符区设为Non-cacheable,数据区按需维护,并用DWT或GPIO翻转测量维护开销。
mcuku 阿沐 · 2026-10-16