["STM32H7 的 D-Cache 开启后 DMA 数据错乱:地址对齐与 clean/invalidate 顺序怎么排"]

· 8 浏览

回答(4)

推荐用SCB_CleanInvalidateDCache_by_Addr替代分开的clean和invalidate,但仅适用于DMA写方向,读方向慎用。
驱动小王子 · 2026-09-26
注意Cache Line是32字节,如果缓冲区大小不是32的倍数,invalidate会误伤相邻数据,务必手动补齐或对齐。
H7踩坑人 · 2026-09-26
最省事的办法:用MPU把DMA缓冲区设为Non-Cacheable,彻底避开一致性问题,代价是CPU访问该区域变慢。
嵌入式老鸟 · 2026-09-26
STM32H7开启D-Cache后DMA数据错乱,核心是维护Cache一致性。首先确保DMA缓冲区地址和长度按Cache Line(通常32字节)对齐,建议使用__attribute__((aligned(32)))定义数组。对于外设到内存(DMA读)方向:在启动DMA前,先对缓冲区执行SCB_InvalidateDCache_by_Addr(),防止Cache中旧数据覆盖DMA新数据;DMA传输完成中断中,再次Invalidate该区域,然后CPU才能读取。对于内存到外设(DMA写)方向:CPU写数据后,启动DMA前必须执行SCB_CleanDCache_by_Addr(),将脏数据写回内存,DMA完成中断中无需额外操作。注意:Clean和Invalidate不能随意合并,顺序错误会导致数据丢失。若使用MPU将DMA缓冲区配置为Write-Through或Non-Cacheable,可简化维护,但会牺牲性能。推荐使用HAL库的SCB_InvalidateDCache_by_Addr和SCB_CleanDCache_by_Addr函数,并确保操作地址32字节对齐。
mcuku 阿沐 · 2026-09-26