2. Sensor选型与驱动适配

Sensor选型,说白了就是给整个摄像头系统挑“眼睛”。眼睛好不好,直接决定了后面ISP、算法、结构设计能不能玩得转。我这些年经手过不下三十款Sensor,从手机模组到车载环视,踩过的坑能写满一本笔记本。今天咱们就聊聊选型时那些绕不开的门道。

2.1 主流Sensor厂商参数对比

目前市面上能打的Sensor厂商,基本就是Sony、OV(OmniVision)和Samsung这三家。每家都有自己的脾气和绝活。

对比维度 Sony OmniVision Samsung
像素工艺 Exmor RS(堆叠式) PureCel Plus(背照+堆叠) ISOCELL(像素隔离)
典型分辨率 12MP ~ 48MP 2MP ~ 64MP 12MP ~ 108MP
动态范围 高(典型72dB+) 中(典型66dB+) 中高(典型70dB+)
低光性能 优秀(DOL HDR) 良好(LFM支持) 良好(Smart-ISO)
驱动生态 成熟,文档规范 寄存器手册较杂 三星平台集成度高
价格区间 偏高 中等 中等偏低
典型应用 旗舰手机、安防 车载、IoT、中低端手机 三星手机、安防

我个人习惯,做项目选型时先看三个硬指标:帧率、功耗、接口兼容性。举个例子,车载环视项目要求60fps输出,Sony的IMX390系列确实稳,但OV的OV2311在LED闪烁抑制(LFM)上反而更胜一筹。选谁?得看你的场景优先级。

我的经验: 别只看Datasheet上的参数。我建议你直接找FAE要一份“实际功耗曲线”,很多Sensor标称功耗是在特定帧率和温度下测的,实际跑起来可能差30%以上。

2.2 MIPI CSI-2接口协议详解

Sensor和SoC之间怎么传数据?靠的就是MIPI CSI-2。这个接口协议,说白了就是一套“谁在什么时候说什么话”的规矩。

2.2.1 物理层:D-PHY vs C-PHY

目前主流还是D-PHY,C-PHY在高端平台开始普及。我简单对比一下:

  • D-PHY: 差分信号,一对线传一个bit。1 Lane最高2.5Gbps(D-PHY v1.2),4 Lane就是10Gbps。布线要求严格,等长、阻抗控制不能马虎。
  • C-PHY: 三线差分,一对线传2.28bit。同样3根线,C-PHY带宽比D-PHY高约30%。但协议复杂,调试工具少。

嗯,这里要注意:不是Lane越多越好。Lane多了,PCB走线难度翻倍,功耗也上去了。我做过一个项目,为了省事选了8 Lane的Sensor,结果板子画了四版才把等长调好。后来学乖了,能用4 Lane绝不用8 Lane。

2.2.2 协议层:帧结构

CSI-2的帧结构,其实就三部分:

  1. 帧起始包(FS): 告诉接收端“我要开始传一帧了”。
  2. 行数据包: 每行图像数据,包含行起始、像素数据、行结束。
  3. 帧结束包(FE): 告诉接收端“这一帧传完了”。

你想想看,如果FS丢了或者FE丢了,SoC就会一直等数据,最后超时报错。我在调试OV的一款Sensor时,就遇到过帧结束包偶尔丢失的问题,查了三天,最后发现是Sensor的VSYNC信号抖动太大,导致SoC误判了帧边界。

核心要点: MIPI调试时,先抓FS/FE包,确认帧结构完整。这是所有图像异常排查的第一步。

2.2.3 数据格式

CSI-2支持多种RAW格式,常见的有:

  • RAW8: 每个像素8bit,适合低端Sensor。
  • RAW10: 每个像素10bit,主流选择,带宽和画质平衡。
  • RAW12: 每个像素12bit,高动态场景用得多。
  • RAW14/16: 专业相机或工业场景,带宽压力大。

我建议,移动端项目优先选RAW10。为什么?因为RAW12虽然画质好一点,但带宽增加20%,功耗和发热可能hold不住。车载项目可以上RAW12,毕竟对动态范围要求高。

2.3 驱动移植与初始化时序调试

驱动移植,说白了就是让SoC能“听懂”Sensor说的话。这个过程,我把它拆成三步:

2.3.1 驱动框架适配

Linux内核下,Sensor驱动通常走V4L2框架。你需要实现的核心回调函数包括:

  • s_power:控制Sensor上电/下电。
  • s_fmt:设置输出格式(分辨率、帧率、数据格式)。
  • g_fmt:获取当前格式。
  • enum_fmt:枚举支持的格式。
  • s_stream:启动/停止数据流。

我记得第一次移植Sony IMX335时,照着参考代码抄了一遍,结果s_stream死活不生效。后来发现是I2C地址写错了——Sony的Sensor默认地址是0x1A,但有些模组厂会改成0x20。嗯,这种低级错误,犯过一次就记住了。

2.3.2 初始化序列配置

Sensor上电后,需要写一串寄存器才能正常工作。这个序列通常包括:

  1. 软件复位: 让Sensor回到已知状态。
  2. PLL配置: 设置主时钟、帧率、像素时钟。
  3. 模拟电路配置: 增益、偏置、ADC参考电压。
  4. 数字电路配置: 数据格式、输出接口、测试模式。
  5. 输出使能: 开启MIPI输出。

下面是一个典型的初始化序列示例(伪代码):

// 1. 软件复位
sensor_write(0x0103, 0x01);  // 软件复位寄存器
mdelay(10);                   // 等待复位完成

// 2. 配置PLL
sensor_write(0x0301, 0x05);  // PLL倍频系数
sensor_write(0x0303, 0x01);  // PLL分频系数
sensor_write(0x0305, 0x02);  // 像素时钟分频

// 3. 配置输出格式
sensor_write(0x0112, 0x0A);  // 输出RAW10
sensor_write(0x0340, 0x04);  // 帧高(高字节)
sensor_write(0x0341, 0x38);  // 帧高(低字节)

// 4. 使能MIPI输出
sensor_write(0x0100, 0x01);  // 启动流
避坑指南: 我曾经在调试Samsung的一款Sensor时,发现初始化序列写完后,Sensor输出全是黑屏。查了两天,最后发现是PLL配置中的“锁定等待时间”不够。Sensor的PLL需要几百微秒才能稳定,如果不等它锁定就直接使能输出,数据全是乱的。解决方案很简单:在写PLL配置后加一个1ms的延时。

2.3.3 时序调试实战

时序调试,是驱动移植中最磨人的环节。我总结了一套“三板斧”:

  1. 抓MIPI波形: 用示波器看D0P/D0N、CLKP/CLKN。确认时钟频率、摆幅、共模电压是否在规格内。
  2. 看帧同步信号: 用逻辑分析仪抓VSYNC和HSYNC。确认帧率、行周期、消隐区是否正常。
  3. 读Sensor状态寄存器: 很多Sensor有“错误状态寄存器”,比如Sony的0x0105(错误状态1)、0x0106(错误状态2)。读一下,能快速定位问题。

举个例子,有一次我调试OV的一款Sensor,图像一直有横条纹。用示波器一看,MIPI时钟抖动很大。再查,发现Sensor的MCLK(主时钟)来自SoC的GPIO,那个GPIO的时钟精度只有±5%。换了一个专用的晶振时钟,问题解决。

我的习惯: 调试时,先让Sensor输出“测试图案”(很多Sensor内置了彩条或棋盘格测试模式)。如果测试图案正常,说明Sensor本身没问题,问题出在SoC的接收端或ISP配置。如果测试图案都不正常,那就老老实实查Sensor的初始化序列和硬件连接。

2.4 Sensor选型与驱动适配知识体系

下面这张图,是我自己总结的Sensor选型与驱动适配的完整知识体系。你可以把它当作一个检查清单,做项目时对着看,不容易漏项。

Sensor选型与驱动适配知识体系 Sensor选型与驱动适配知识体系 1. Sensor选型对比 2. MIPI CSI-2协议 3. 驱动移植与调试 Sony OmniVision Samsung D-PHY C-PHY 帧结构(FS/FE/行数据) 数据格式(RAW8/10/12) V4L2框架 初始化序列 时序调试 状态寄存器 核心原则:选型看场景,协议抓帧结构,调试先测测试图案

这张图把Sensor选型、MIPI协议、驱动调试串在了一起。你想想看,做项目时是不是经常在这三个模块之间来回跳?选型没选好,后面协议适配就难受;协议没吃透,驱动调试就抓瞎。所以,我建议你每次做项目前,先把这张图过一遍,心里有个谱。