2. Sensor 选型与驱动调试:从接口到 Raw 图

Sensor 选型,说白了就是给 ISP 系统挑一双「眼睛」。眼睛好不好,直接决定了后面所有图像处理的天花板。我见过不少项目,算法团队花了几个月调参,最后发现是 Sensor 本身信噪比不够,怎么调都救不回来。所以这一步,咱们得认真走。

2.1 Sensor 接口类型:你该选哪种「数据通道」?

Sensor 和 SoC 之间怎么传数据?目前主流接口就几种。我列个表,你一看就明白。

接口类型 带宽 传输距离 典型应用 我踩过的坑
DVP ~720Mbps 短(<10cm) 低分辨率、老平台 信号容易受干扰,布线要小心
MIPI CSI-2 单 Lane ~1Gbps,可扩展 中(<30cm) 手机、安防、车载 Lane 数不够时,降帧率很痛苦
LVDS ~1.8Gbps 长(>1m) 工业相机、医疗 功耗高,调试麻烦
SLVS-EC ~2.5Gbps 中 高端工业、科学级 协议复杂,驱动不好写

我个人习惯,优先选 MIPI CSI-2。它生态好,SoC 支持最全。但要注意,MIPI 的 Clock Lane 和 Data Lane 必须等长布线,否则信号歪了,图像会出现条纹。我曾经在一个项目里,PCB 走线差了 5mm,Raw 图直接花掉,查了三天才找到原因。

小提示: 选型时,除了看接口类型,还要关注 Sensor 的 像素时钟(PCLK) 和 帧率(FPS) 是否匹配 SoC 的 MIPI 接收端能力。别选了个 4K@60fps 的 Sensor,结果 SoC 只能解 4K@30fps,那就尴尬了。

2.2 驱动框架:Linux 下怎么「管」Sensor?

驱动框架,说白了就是操作系统怎么和 Sensor 对话。Linux 下最常用的是 V4L2(Video for Linux 2) 框架。我画个图,帮你理清结构。

Sensor 驱动框架结构图 Sensor 驱动框架(V4L2) 应用层(App / ISP Pipeline) V4L2 核心层(Video Device / Subdev) Sensor 驱动层(I2C 控制 + MIPI 配置) 初始化 / 曝光 / 增益 / 帧率 / 输出格式 硬件层(Sensor 芯片 + 电源 + 时钟) 关键:驱动通过 I2C 写寄存器控制 Sensor,通过 MIPI CSI-2 接收图像数据 V4L2 Subdev 负责 Sensor 控制,Video Node 负责数据流

驱动开发的核心,就是实现 V4L2 Subdev 的回调函数。你需要写这些:

  • s_power:控制 Sensor 上电/下电。注意上电时序,我见过因为 Reset 和 MCLK 顺序反了,Sensor 死活不工作的。
  • s_stream:启动/停止数据流。启动时,要配置好 MIPI 的 Lane 数和时钟。
  • enum_frame_size / enum_frame_interval:告诉 V4L2 核心,Sensor 支持哪些分辨率和帧率。
  • set_fmt:设置输出格式,比如 Raw10、Raw12。
核心要点: 驱动调试时,先用 i2cdetect 确认 I2C 地址对不对。我遇到过 Sensor 地址是 0x6C,但 datasheet 写的是 0x36(7位地址),折腾了半天才发现是地址表示方式不同。

2.3 点亮 Sensor:从黑屏到出图

点亮 Sensor,是 ISP 项目里最激动人心的一步。但也是最容易出问题的一步。我总结了一套「三板斧」流程:

  1. 硬件检查:用万用表量电源(AVDD、DVDD、IOVDD)是否正常。用示波器看 MCLK 时钟波形,频率对不对,幅值够不够。
  2. I2C 通信:写一个简单的 I2C 读写工具,读 Sensor 的 Chip ID 寄存器。如果能读到预期的值,说明通信通了。
  3. 初始化序列:按照 datasheet 的初始化步骤,依次写入寄存器。注意有些 Sensor 需要等待几毫秒才能写下一步。
  4. 配置输出:设置输出分辨率、帧率、MIPI Lane 数、数据格式(Raw10/Raw12)。
  5. 启动流:调用 s_stream(1),然后看 SoC 端能不能收到 MIPI 数据。

嗯,这里要注意。很多新手在第二步就卡住了。为什么?因为 I2C 的时序不对。Sensor 的 I2C 速度通常支持 400kHz,但有些 SoC 默认是 100kHz。如果 Sensor 要求 400kHz,你跑 100kHz 也能通,但速度慢。反过来,如果 Sensor 只支持 100kHz,你跑 400kHz,通信就会出错。

避坑指南: 我曾经在一个项目里,Sensor 的 I2C 地址是 0x20,但 SoC 的 I2C 控制器地址是 7 位,而 Sensor 的 datasheet 写的是 8 位地址。结果我写 0x40(左移一位),读出来的 Chip ID 全是 0xFF。后来发现,驱动里应该用 7 位地址 0x20,而不是 0x40。这个坑,我记了三年。

2.4 获取 Raw 图:验证 Sensor 是否「看」对了

Sensor 点亮后,第一件事就是抓一张 Raw 图。Raw 图是未经任何 ISP 处理的原始数据,它直接反映了 Sensor 的感光情况。

怎么抓?我一般用 media-ctl 和 yavta 这两个工具:

# 设置 pipeline
media-ctl -d /dev/media0 -l '"sensor 0-0036":0->"csi2":0[1]'
media-ctl -d /dev/media0 -V '"sensor 0-0036":0 [fmt:SRGGB10/1920x1080]'

# 抓图
yavta -f SRGGB10 -s 1920x1080 -n 4 --capture=1 -F /tmp/raw.raw /dev/video0

抓到的 Raw 图,用 RawTherapee 或 dcraw 打开看看。正常的 Raw 图,应该能看到物体的轮廓,但颜色是偏绿的(因为 Bayer 模式)。如果全黑,可能是曝光时间太短或增益太低。如果全白,可能是曝光过度或 Sensor 坏了。

我教你一个快速判断的方法:看 Raw 图的直方图。如果直方图集中在左侧(暗部),说明曝光不足。如果集中在右侧(亮部),说明过曝。正常的 Raw 图,直方图应该像一座小山,中间高两边低。

小技巧: 调试阶段,我习惯把曝光时间设长一点(比如 100ms),增益设低一点。这样能保证画面不会太暗,方便观察 Sensor 是否正常工作。等确认没问题了,再调回正常参数。

2.5 常见问题与排查思路

调试 Sensor 时,你肯定会遇到各种问题。我把最常见的几个列出来,你遇到时可以对照排查。

现象 可能原因 排查方法
Raw 图全黑 曝光时间太短、增益太低、Sensor 未启动 检查曝光寄存器、用示波器看 MIPI 是否有数据
Raw 图全白 曝光过度、Sensor 损坏、复位引脚电平不对 降低曝光时间、检查复位时序
图像有条纹 MIPI 信号干扰、电源纹波大、时钟抖动 检查 MIPI 走线、加电容滤波、用示波器看时钟
图像有坏点 Sensor 本身缺陷、镜头灰尘、Bayer 模式配置错误 用遮光罩拍一张暗场图,看坏点是否固定
帧率不对 MIPI Lane 数配置错误、PCLK 频率不对 检查寄存器配置、用示波器量 PCLK

说实话,调试 Sensor 最考验耐心。我见过一个同事,因为 Raw 图有条纹,查了整整一周,最后发现是 Sensor 的电源滤波电容焊错了位置。所以,硬件基础一定要扎实。

总结一下: Sensor 选型看接口和性能,驱动开发用 V4L2 框架,点亮 Sensor 靠 I2C 和初始化序列,获取 Raw 图用 yavta。每一步都有坑,但只要你按流程走,问题总能定位到。