摄像头的帧数据是怎么"进内存"的:硬件 DMA(不经过 CPU)

gc2145 传感器(MIPI 接口)
   │  像素数据流(PCLK 时钟驱动的信号)
   ▼
rkcif 控制器(SoC 里的 MIPI 接收器)
   │  ← 内核驱动提前告诉它:"把数据写到内存地址 0xXXXXXX,写 960KB"
   ▼
内存(内核分配的物理内存)gc2145 传感器(MIPI 接口)
  • 从传感器到内存,全程没有 CPU 参与。

  • 传感器把像素信号发给 rkcif 硬件,rkcif 硬件按驱动配置的地址,自己把数据写到内存里——这叫 DMA(Direct Memory Access,直接内存访问)。

队列

  • 帧队列,有4个帧在队列中,REQBUFS(4)。

  • 内核驱动分配了4块内存。DMA填充一块,我们处理一块,等待入队一块,空闲一块。

  • 填充帧需要时间,程序处理帧需要时间,如果只有1帧,那么填充完,然后程序处理,帧率直接减半。

  • DQBUF把队列里最新一帧的"所有权"转给你——内核在 vb.index 里告诉你"第 2 块缓冲填好了,归你了。数据原地没动(还在那块物理内存里),只是"现在轮到你看它了"。你通过 mmap 映射的虚拟地址(bufs[2].start)可以直接读它。

  • select,select(fd) 是"等货架上有货"的通知——内核有帧入队完成时会让 fd 可读,select 返回。没有 select 直接 DQBUF 也行,但会阻塞等;select 给你"有货再取"的效率。