STM32H7 的 D-Cache 与 DMA 数据一致性:按行清理和无效化的边界条件怎么处理

· 7 浏览

回答(4)

对齐是硬要求,32 字节。缓冲区首地址和长度都按 32 对齐后,clean/invalidate 就不会误伤邻居数据,调试时用 SCB_GetDCacheSize 确认行大小。
Cortex小工 · 2026-09-13
记住口诀:CPU 写、DMA 读,先 clean;DMA 写、CPU 读,先 invalidate。invalidate 前务必确认 CPU 没碰过这块内存。
嵌入式老张 · 2026-09-13
最省心的做法:给 DMA 缓冲区单独划一段 MPU 区域设为 Non-Cacheable,代码里就不用到处插 clean/invalidate,也不会踩边界坑。
深夜调板子 · 2026-09-13
STM32H7 的 D-Cache 行大小为 32 字节,Cache 维护操作必须按 32 字节对齐的整行进行,这是所有边界问题的根源。发送方向(内存→外设):DMA 启动前对缓冲区执行 clean(SCB_CleanDCache_by_Addr),若缓冲区首尾未对齐到 32 字节边界,clean 会连带写回相邻数据,虽不破坏正确性但会引入额外带宽开销,建议把 DMA 缓冲区用 __attribute__((aligned(32))) 对齐,长度补齐到 32 的整数倍。接收方向(外设→内存):DMA 完成中断里先 invalidate(SCB_InvalidateDCache_by_Addr)再读数据,且必须在 DMA 传输期间保证 CPU 不访问该缓冲区,否则 invalidate 会丢弃 CPU 刚写入但未回写的脏数据。若缓冲区首地址未对齐,invalidate 会把相邻字节的修改也丢掉,此时应改用 clean+invalidate 组合,或把缓冲区对齐。另外注意 MPU 配置:可将 DMA 缓冲区所在区域配成 Non-Cacheable 或 Write-Through,从根上规避一致性问题,代价是访问变慢。
mcuku 阿沐 · 2026-09-13