STM32H7 的 D-Cache 与 DMA 一致性:Clean/Invalidate 时机与 MPU 配置的实战避坑

· 3 浏览

回答(4)

感谢分享,学到了。新手建议先把原理吃透再上手,少走弯路。
嵌入式新人 · 2026-10-21
这个方法我在实际项目里用过,挺稳的,注意边界条件处理好就行。
电工小张 · 2026-10-21
补充一点:记得用示波器实测波形,结合现场调试往往更容易定位问题。
电工小张 · 2026-10-21
{"answer":"核心原则:DMA写内存(外设→内存)前Invalidate对应cache行,DMA读内存(内存→外设)前Clean对应cache行;DMA完成后再次Invalidate接收缓冲区。顺序不能反:先Clean再启动DMA发送,先Invalidate再启动DMA接收,否则CPU脏数据会覆盖DMA写入或DMA读到旧数据。缓冲区必须32字节对齐且大小为32字节整数倍,否则Clean/Invalidate会波及相邻数据(尤其Invalidate会丢弃未回写数据)。MPU配置:将DMA缓冲区所在区域设为Non-cacheable(TEX=1,C=0,B=0)或Device/Strongly-ordered,可彻底免除维护操作,代价是CPU访问变慢;若追求性能则保持Cacheable并用SCB_CleanDCache_by_Addr/SCB_InvalidateDCache_by_Addr精确维护。注意H7的AXI SRAM默认Cacheable,DTCM不可Cache且不能被DMA1/2访问(仅MDMA可),别把DMA缓冲放DTCM。调试时关Cache会掩盖问题,务必在开Cache下验证。","extras":[{"content":"用SCB_InvalidateDCache_by_Addr而非整Cache Invalidate,避免误伤其他变量;传地址需32字节对齐,长度向上取整到32倍数。","author":"嵌入式老张"},{"content":"双缓冲+半传输中断时,只对刚完成的半区做Invalidate,别整块操作,否则会丢掉另一正在DMA写的半区数据。","author":"DMA搬砖人"},{"content":"MPU区域要按最小粒度对齐并注意与默认内存属性映射重叠,优先级编号小的region生效,配置完记得开SCB_EnableDCache前先设好MPU。","author":"Cortex-M7笔记"}],"}
mcuku 阿沐 · 2026-10-21