4. Sensor驱动与配置
Sensor驱动,说白了就是让主控芯片和图像传感器能“对上话”。
我刚开始调RK平台时,总觉得驱动是驱动工程师的事,我调ISP就好。结果有一次,Sensor死活不出图,查了三天,最后发现是驱动里一个寄存器地址写错了。嗯,从那以后,我再也不敢跳过驱动这一层了。
4.1 Sensor驱动加载流程
Sensor上电后,驱动加载大致分这么几步:
- 设备树解析:内核读取dts,拿到Sensor的I2C地址、复位引脚、电源时序等信息。
- I2C通信建立:驱动通过I2C总线与Sensor握手,确认设备存在。
- 寄存器初始化:写入Sensor的初始化序列,包括输出格式、帧率、MIPI配置等。
- V4L2设备注册:将Sensor注册为一个V4L2子设备,供上层调用。
- Media Controller绑定:将Sensor的实体(Entity)连接到ISP或CSI接收器。
关键点:驱动加载失败,90%的问题出在电源时序和I2C地址上。我建议你在调试初期,先用i2c-tools手动读一下Sensor的ID寄存器,确认通信正常。
4.2 V4L2与Media Controller框架
V4L2是Linux下视频设备的标准接口。Media Controller则是用来描述硬件内部数据通路的。
你想想看,一个摄像头模组里,Sensor、ISP、MIPI接收器、DMA引擎……它们之间怎么连接?Media Controller就是干这个的。
4.2.1 V4L2核心概念
| 概念 | 说明 |
|---|---|
| Video Device | 用户空间看到的设备节点,如 /dev/video0 |
| Sub-device | 硬件模块的抽象,如Sensor、ISP |
| Format | 图像格式、分辨率、像素编码 |
| Buffer | 存放图像数据的内存区域 |
| Stream | 数据流开启/关闭的控制 |
4.2.2 Media Controller管道
Media Controller把每个硬件模块看作一个实体(Entity),实体之间通过Pad连接。数据从Sensor的source pad流出,经过ISP的sink pad,再到DMA的source pad,最终写入内存。
调试技巧:用 media-ctl -p 命令可以打印出完整的管道拓扑。我曾经在一个项目中,发现ISP的sink pad没有正确连接到Sensor的source pad,导致数据流中断。用这个命令一眼就看出来了。
4.2.3 数据流配置流程
- 通过Media Controller设置各实体的格式和连接。
- 通过V4L2的
VIDIOC_S_FMT设置最终输出格式。 - 通过
VIDIOC_REQBUFS申请缓冲区。 - 通过
VIDIOC_QBUF和VIDIOC_DQBUF进行帧处理循环。
4.3 Sensor寄存器配置实战
这部分是硬功夫。每个Sensor的寄存器手册都不一样,但套路是相通的。
4.3.1 常用寄存器类型
| 寄存器类型 | 作用 | 示例 |
|---|---|---|
| 芯片ID | 验证通信是否正常 | 0x3000 = 0x58 |
| 模式选择 | 设置分辨率、帧率 | 0x0100 = 0x01(开启流) |
| 曝光控制 | 设置曝光时间 | 0x3500-0x3502 |
| 增益控制 | 设置模拟/数字增益 | 0x3508-0x3509 |
| 输出格式 | 设置RAW10/RAW12等 | 0x5E00 = 0x0A |
| MIPI配置 | 设置Lane数、速率 | 0x4800 = 0x24 |
4.3.2 实战:初始化序列示例
下面是一个典型的Sensor初始化序列(伪代码):
static struct regval_list sensor_init_regs[] = {
{0x0103, 0x01}, // 软件复位
{0x0100, 0x00}, // 关闭流
{0x3000, 0x58}, // 验证芯片ID(可选)
{0x5E00, 0x0A}, // 设置输出格式为RAW10
{0x4800, 0x24}, // 设置MIPI 2-lane
{0x3501, 0x00}, // 设置曝光高字节
{0x3502, 0x64}, // 设置曝光低字节
{0x3508, 0x00}, // 设置增益
{0x0100, 0x01}, // 开启流
};
注意:写寄存器时,一定要确认I2C地址是否正确。我曾经遇到过Sensor的I2C地址是0x6C,但驱动里写成了0x36,结果怎么都读不到ID。后来用示波器抓I2C波形才发现问题。
4.3.3 调试方法
- i2cget/i2cset:手动读写寄存器,验证配置是否正确。
- 示波器抓MIPI:确认Sensor是否输出正确的MIPI信号。
- v4l2-ctl:查看V4L2设备状态,确认格式设置是否生效。
4.4 知识结构图:Sensor驱动与配置核心流程
下面这张图,把整个Sensor驱动加载到数据流建立的过程串起来了。
4.5 常见问题与避坑
- Sensor不出图:先查I2C通信,再查MIPI信号,最后查驱动配置。
- 帧率不对:检查Sensor的PLL配置和MIPI速率是否匹配。
- 图像花屏:多半是MIPI Lane数或速率配置错误。
- 曝光异常:检查曝光寄存器的写入顺序和范围。
我的习惯:每次拿到新Sensor,我会先写一个最小驱动,只做三件事:读ID、写初始化序列、开流。确认能出图后,再逐步添加曝光、增益等控制。这样定位问题快很多。
Sensor驱动这块,说白了就是“让硬件动起来”。只要I2C通了,寄存器写对了,数据流就能跑起来。剩下的,就是ISP调优的事了。