DMA 缓存一致性问题:从花屏到数据错乱的定位与修复
DMA 缓存一致性问题:从花屏到数据错乱的定位与修复DMA 是嵌入式系统中搬运数据的主力——视频帧、音频采样、网络包、存储数据,无一不经 DMA。但 DMA 和 CPU Cache 之间的一致性问题,是嵌入式开发中最隐蔽的 bug 类型之一:症状间歇性出现、复现环境不稳定、排查工具匮乏。这篇文章不讲 cache 基础概念(那属于计算机体系结构第一节课),直接上实战案例的定位思路和修复手段。一、一致性问题的根源:两条独立的数据通路问题的本质:CPU 写数据 → 写 cache → cache line 标记为 dirty数据在 cache 中,还没有写回 DDRDMA 从同一地址读数据 → 读 DDRDMA 绕过 cache,直接读到的是 DDR 中的旧数据CPU 读 DMA 写入的数据 → 读 cacheDMA 已经把新数据写入 DDR,但 CPU 的 cache 里还是旧数据这就是DMA 与 cache 的一致性(coherency)问题——CPU 和 DMA 看到的是两个不同的内存视图。二、实战案例一:视频采集花屏场景一块 IPC 方案(Cortex-A55 + 内置 ISP),使用 V4L2 采集视频帧。现象:播放视频时,画面不定时出现水平条纹花屏,出现频率约 1-2 次/分钟,不固定位置。排查过程第一步:确认花屏的帧模式抓取一帧花屏的 raw YUV 数据:# 在驱动层 dump 一帧完整的 YUVechodump/sys/video/frame_dumpcat/sys/video/last_frame.raw|hexdump-C|head-20花屏帧的典型特征:前 90% 数据正确,后 10% 数据是上一帧的内容或者全零。模式判断:不是编码器的问题(编码器有错误掩盖),是编码器输入数据就有问题。问题出在 ISP → DDR → V4L2 buffer 这条路径上。第二步:确认 DMA 方向和 cache 操作检查驱动中 V4L2 buffer 的处理:// 驱动中 capture 部分的 buffer 处理staticintisp_capture_buffer(structisp_device*isp,structvb2_buffer*vb){dma_addr_tbuf_phys=vb2_dma_contig_plane_dma_addr(vb,0);void*buf_virt=