1. Camera驱动全景概览:从硬件接口到软件栈,理解Camera子系统全貌

做Camera驱动开发这些年,我最大的感触是——很多人一上来就扎进代码里,结果越调越懵。其实,搞懂Camera子系统,你得先看清它长什么样。说白了,就是硬件怎么连、数据怎么流、软件怎么管这三件事。

今天这一章,我带你把Camera子系统的全貌捋一遍。不追求一次全记住,但求脑子里有个清晰的地图。

1.1 硬件接口:Camera是怎么连上SoC的?

Camera模组和SoC之间,靠的是硬件接口。目前主流的接口就几种,我列个表,你一看就明白。

接口类型 数据通道 典型带宽 常见场景
MIPI CSI-2 1-4 Lane 每Lane ~1.5Gbps 手机、平板、车载
Parallel 8-16 bit并行 ~100Mbps 低端摄像头、监控
USB UVC协议 USB 3.0 ~5Gbps 外接摄像头、PC
LVDS 串行差分 ~1Gbps 工业相机、车载

我个人习惯,拿到一个新平台,第一件事就是确认MIPI CSI的Lane配置。为什么?因为带宽不够,后面所有优化都是白搭。我曾经在一个项目里,Sensor输出4K@60fps,结果只配了2 Lane MIPI,数据根本传不过来。嗯,这种坑踩过一次就记住了。

1.2 软件栈:从Sensor到应用,数据经历了什么?

Camera软件栈,我习惯把它分成三层:底层驱动、中间件、上层应用。每一层都有自己的活,也都有自己的坑。

1.2.1 底层驱动层

这一层直接跟硬件打交道。主要包含:

  • Sensor驱动:初始化Sensor、配置分辨率/帧率、控制曝光和增益。说白了,就是让Sensor开始干活。
  • CSI/ISP驱动:负责接收MIPI数据,做初步的RAW数据预处理。比如坏点校正、黑电平校正。
  • V4L2框架:Linux下Camera驱动的标准接口。你写驱动,最终都是要注册到V4L2里的。

你想想看,底层驱动如果没写好,上层再怎么调也是白费力气。我见过一个团队,花了两周调ISP效果,结果发现Sensor的PCLK配置错了,数据全是乱的。所以,底层一定要稳。

1.2.2 中间件层

中间件是承上启下的关键。常见的有:

  • HAL层:Android的Camera HAL,封装底层接口,提供统一API给上层。
  • ISP算法库:3A算法(AE/AWB/AF)、降噪、锐化、HDR等。这部分最吃算力,也最影响画质。
  • Buffer管理:分配和回收图像Buffer,避免内存抖动。我习惯用ION或DMA-BUF,效率高。

重点提醒:中间件的延迟往往是整个Camera pipeline的瓶颈。尤其是Buffer分配和3A算法,稍不注意就会引入几帧的延迟。

1.2.3 上层应用层

这一层就是用户能看到的了。比如相机App、视频通话、扫码等。应用层通过Framework调用底层,拿到图像数据后做显示、编码或分析。

嗯,这里要注意:应用层对延迟最敏感。用户按下快门,到看到照片,中间超过200ms,就会觉得卡。所以,优化最终要落到应用层的体验上。

1.3 数据流:一帧图像是怎么走完的?

我画个简单的数据流,你跟着走一遍:

  1. Sensor曝光:Sensor开始采集光线,生成RAW数据。
  2. MIPI传输:RAW数据通过MIPI CSI接口,传到SoC的ISP模块。
  3. ISP处理:ISP做RAW域处理,输出YUV或RGB数据。
  4. Buffer排队:处理完的数据放入Buffer队列,等待上层取走。
  5. 应用消费:应用从Buffer队列拿到数据,显示或编码。

整个过程,从Sensor曝光到应用拿到数据,就是Camera pipeline的延迟。我做过一个项目,从Sensor曝光到屏幕显示,延迟控制在30ms以内。怎么做到的?后面章节我会详细讲。

我的经验:优化延迟,核心就是减少Buffer拷贝和等待。能走零拷贝就走零拷贝,能用硬件加速就别用CPU。

1.4 关键概念:你必须要懂的几个术语

做Camera驱动,有几个术语你绕不开。我挑最重要的说:

  • 帧率(FPS):每秒输出多少帧。30fps是基础,60fps算流畅,120fps以上是高刷。
  • 延迟(Latency):从Sensor曝光到应用拿到数据的时间。单位是毫秒。
  • Pipeline深度:数据流中同时处理的帧数。深度越大,延迟越高,但吞吐量也大。
  • 3A算法:自动曝光(AE)、自动白平衡(AWB)、自动对焦(AF)。这三个算法直接影响画质。

我曾经在一个项目中,为了降低延迟,把Pipeline深度从4降到2。结果延迟降了,但帧率也掉了。后来发现是Buffer分配没跟上。所以,深度和延迟之间要找到平衡点。

1.5 常见问题与避坑指南

避坑1:MIPI信号完整性

我曾经遇到一个项目,Sensor输出图像偶尔出现条纹。查了两天,最后发现是MIPI走线太长,信号衰减了。解决办法:缩短走线,或者加Repeater。

避坑2:Buffer饥饿

高帧率场景下,如果Buffer分配不够快,会导致Pipeline空转。我建议预留至少3个Buffer做乒乓操作,避免饥饿。

避坑3:ISP参数配置

ISP的寄存器配置,一定要按照Sensor的datasheet来。我见过有人把黑电平校正值配反了,结果图像整体偏色。嗯,这种低级错误,犯一次就够了。

1.6 本章小结

这一章,我们走了一遍Camera子系统的全貌。从硬件接口(MIPI、Parallel、USB),到软件栈(驱动、中间件、应用),再到数据流和关键概念。说白了,就是让你脑子里有个地图,知道Camera系统长什么样。

下一章,我会带你深入V4L2框架,看看驱动是怎么注册、怎么控制Sensor的。到时候,我们手写一个简单的Sensor驱动,你就能真正理解底层是怎么工作的了。

好,今天就到这儿。有问题随时交流。