Linux内核摄像头驱动开发实战 - 第1节

1.1 摄像头硬件接口概述

摄像头传感器与主控 SoC 之间的物理连接方式决定了数据传输带宽、控制复杂度以及适用场景。当前嵌入式 Linux 系统中最常见的三种接口为 MIPI CSI、USB 和 Parallel(并行接口)。

1.1.1 MIPI CSI(Camera Serial Interface)

MIPI CSI 是移动和嵌入式领域的主流串行接口,采用差分信号对(D-PHY)传输数据,具备高速、低功耗、抗干扰强的特点。CSI-2 支持 1~4 Lane 配置,单 Lane 速率可达 1.5 Gbps 以上。

参数 MIPI CSI-2 Parallel USB
信号类型 差分串行(D-PHY) 并行 CMOS 电平 差分串行(USB 2.0/3.0)
最大带宽 4 Lane 约 6 Gbps 约 800 Mbps USB 3.0 约 5 Gbps
线缆长度 短(< 30 cm) 极短(< 15 cm) 长(可达 5 m)
典型应用 手机、平板、车载摄像头 低端 MCU、老式传感器 PC 摄像头、工业相机
驱动开发提示: MIPI CSI 驱动需要处理 D-PHY 初始化、Lane 映射、时钟连续/非连续模式切换,以及 SoC 端 CSI 控制器与 sensor 端的一致性配置。这是摄像头驱动中最复杂、最易出错的环节。
MIPI CSI-2 物理连接拓扑 摄像头传感器 OV5640 / IMX219 主控 SoC CSI 控制器 数据 Lane 0~3(差分对) I²C 控制总线(寄存器读写) MCLK 主时钟(24 MHz) 说明:MIPI CSI 使用差分信号对,每个 Lane 包含 D-P 和 D-N 两根线。实际 PCB 走线需等长,阻抗控制 100Ω。

1.1.2 USB 摄像头

USB 摄像头通过 UVC(USB Video Class)协议实现即插即用,Linux 内核已内置 uvcvideo 驱动。开发者通常不需要修改内核驱动,但需要理解 V4L2 与 UVC 的映射关系。

  • USB 2.0:理论带宽 480 Mbps,实际传输 720p@30fps 无压缩时接近极限。
  • USB 3.0:理论带宽 5 Gbps,可支持 1080p@60fps 或 4K@30fps 的 MJPEG 流。
  • 缺点:CPU 占用高(需 USB 控制器中断处理),延迟比 MIPI CSI 大。

1.1.3 Parallel(并行接口)

并行接口使用 8/10/12 位数据线 + VSYNC/HSYNC/PCLK 控制信号,常见于低分辨率或老式传感器。驱动开发相对简单,但 PCB 布线拥挤,高速场景下信号串扰严重,已逐渐被 MIPI CSI 取代。

避坑提醒: 并行接口的 GPIO 管脚分配极易与其它外设冲突。在移植 BSP 时,务必核对 SoC 数据手册中的管脚复用表,避免 VSYNC/HSYNC 被误配为 PWM 或 UART 功能。

1.2 V4L2 框架简介

V4L2(Video for Linux 2)是 Linux 内核中视频设备驱动的标准框架,位于 drivers/media/v4l2-core/。它为摄像头、视频采集卡、TV 调谐器等设备提供了统一的字符设备接口(/dev/videoX)和 IOCTL 控制协议。

1.2.1 V4L2 核心架构

V4L2 采用分层设计,从上到下依次为:

  1. 应用层:用户空间程序通过 open()、ioctl()、mmap()、poll() 操作 /dev/videoX。
  2. V4L2 核心层:videodev.ko 提供设备注册、IOCTL 分发、buffer 管理框架。
  3. Bridge 驱动:SoC 端摄像头控制器驱动(如 exynos-fimc、omap3isp)。
  4. Sensor 驱动:摄像头传感器驱动(如 ov5640.c、imx219.c),通过 I²C 控制寄存器。
V4L2 软件架构分层 用户空间应用(GStreamer / FFmpeg / OpenCV) 系统调用:open / ioctl / mmap / poll V4L2 核心层(videodev.ko) 设备注册 / IOCTL 分发 / Buffer 管理 Bridge 驱动(SoC CSI 控制器) Sensor 驱动(I²C 控制 + MIPI 配置)

1.2.2 V4L2 关键数据结构

数据结构 作用 所在头文件
struct video_device 注册为 /dev/videoX,关联 file_operations media/v4l2-dev.h
struct v4l2_device 顶层 V4L2 设备实例,管理子设备 media/v4l2-device.h
struct v4l2_subdev 子设备抽象,用于 sensor、flash、scaler media/v4l2-subdev.h
struct vb2_queue videobuf2 缓冲区队列,管理 DMA 内存 media/videobuf2-core.h
struct v4l2_pix_format 描述图像格式、分辨率、像素编码 uapi/linux/videodev2.h
核心概念: V4L2 将摄像头硬件抽象为 video_device(主设备)和 v4l2_subdev(子设备)。Sensor 驱动通常只实现 subdev 接口,Bridge 驱动负责将 subdev 的数据流送入 vb2 队列。这种分离使得更换 sensor 时只需替换 subdev 驱动,Bridge 驱动可复用。

1.3 摄像头驱动在 Linux 系统中的位置与作用

摄像头驱动位于内核的 drivers/media/ 目录下,按功能分为三个子目录:

  • drivers/media/i2c/:存放 sensor 驱动(如 ov5640.c、imx219.c),通过 I²C 总线与 sensor 通信。
  • drivers/media/platform/:存放 SoC 平台 Bridge 驱动(如 rockchip、amphion、exynos4-is)。
  • drivers/media/usb/:存放 USB 摄像头驱动(主要是 uvcvideo)。

1.3.1 驱动在系统中的角色

摄像头驱动承担以下核心职责:

  1. 硬件初始化:上电时序、时钟配置、GPIO 复位、I²C 寄存器写入。
  2. 格式协商:响应应用层的 VIDIOC_S_FMT,设置分辨率、像素格式(YUYV / MJPEG / RAW10)。
  3. 流控制:启动/停止视频流(VIDIOC_STREAMON/OFF),控制 sensor 输出帧率。
  4. 缓冲区管理:通过 videobuf2 分配 DMA 缓冲区,处理帧完成中断,将数据投递到用户空间。
  5. 控制接口:实现亮度、对比度、曝光、白平衡等 V4L2 控制(VIDIOC_S_CTRL)。
摄像头驱动在 Linux 系统中的位置 用户空间应用 V4L2 核心 + 摄像头驱动 摄像头硬件(Sensor + CSI) 驱动作用说明 1. 提供 /dev/videoX 字符设备 2. 实现 IOCTL 命令处理 3. 管理 DMA 缓冲区队列 4. 处理硬件中断与帧完成回调 5. 通过 I²C 配置 sensor 寄存器 6. 控制 MIPI CSI D-PHY 初始化 7. 实现电源管理(suspend/resume)

1.3.2 驱动开发者的工作边界

在实际项目中,摄像头驱动开发通常涉及以下任务:

任务 涉及模块 难度
移植新 sensor 驱动 I²C 读写、寄存器序列、V4L2 subdev 接口 中等
适配 SoC CSI 控制器 DMA 引擎、中断处理、vb2 队列 高
调试 MIPI 信号完整性 D-PHY 配置、Lane 交换、时钟恢复 高
添加 V4L2 控制(AE/AWB) sensor 寄存器 + V4L2 ctrl 框架 低
优化帧率与延迟 vb2 缓冲区策略、中断合并、DMA 双缓冲 中等
学习路径建议: 初学者应从 drivers/media/i2c/ov5640.c 或 imx219.c 入手,先理解 subdev 驱动的 probe、s_power、s_fmt 和 s_stream 回调。再结合 SoC 的 Bridge 驱动(如 Rockchip 的 rkisp1)理解整个数据流路径。