瑞芯微RK平台Sensor驱动框架与多Camera切换实战 - 第1节
1.1 RK平台Camera硬件架构
瑞芯微RK平台Camera子系统采用多通路并行+ISP级联的硬件架构,支持同时接入多路Sensor并进行实时图像处理。典型的硬件链路包含以下关键模块:
硬件链路速览: Sensor → MIPI/LVDS → CSI Host → VIPP → ISP → DMA → DDR
1.1.1 核心硬件模块
| 模块 | 功能描述 | 典型数量 |
|---|---|---|
| Sensor | 图像传感器,输出RAW/Bayer/YUV数据 | 1~4路 |
| MIPI CSI/LVDS | 物理层接收,支持D-PHY/C-PHY | 2~4组 |
| CSI Host | 协议解析、数据打包、虚拟通道分离 | 2~4个 |
| VIPP | 视频输入预处理,支持裁剪/缩放/格式转换 | 4~8个 |
| ISP | 图像信号处理,含3A、降噪、锐化、HDR | 1~2个 |
| DMA | 直接内存访问,将图像数据写入DDR | 多通道 |
1.1.2 多Camera物理连接拓扑
以RK3588为例,其Camera硬件拓扑支持4路MIPI CSI同时输入,通过虚拟通道(VC)和物理通道(PC)实现多路复用:
硬件要点: RK3588的4路MIPI CSI可同时工作,但ISP只有2个,因此多Camera切换时需通过VIPP进行时分复用或通路切换。
1.2 软件栈层次
RK平台Camera软件栈采用分层解耦设计,从上到下依次为:
1.2.1 各层职责
| 层次 | 关键组件 | 职责说明 |
|---|---|---|
| 应用层 | Camera HAL、Android CameraService、App | 提供统一API,管理Camera设备生命周期,实现多Camera切换策略 |
| 框架层 | V4L2核心、Media Controller、Video Device | 提供标准设备接口,管理媒体拓扑,实现数据流控制 |
| 驱动层 | Sensor驱动、ISP驱动、VIPP驱动、MIPI DPHY驱动 | 直接操作硬件寄存器,完成图像采集、格式转换、ISP处理 |
| 硬件层 | Sensor模组、MIPI CSI、ISP核心、DMA控制器 | 物理执行图像采集、传输、处理和存储 |
驱动开发重点: Sensor驱动位于驱动层最底层,需要实现V4L2子设备接口,并通过Media Controller与ISP、VIPP建立pipeline连接。多Camera切换的核心逻辑也在此层实现。
1.3 V4L2框架简介
V4L2(Video for Linux 2)是Linux内核中标准的视频设备驱动框架,RK平台Camera子系统完全基于V4L2构建。其核心概念包括:
1.3.1 V4L2核心对象
- Video Device:
/dev/videoX,用户空间通过open/ioctl/mmap操作 - V4L2 Subdev:子设备,用于Sensor、ISP等内部模块
- Media Controller:管理设备拓扑,建立pipeline
- Buffer:视频数据缓冲区,支持MMAP/DMABUF/USERPTR
1.3.2 V4L2驱动框架结构
1.3.3 V4L2关键ioctl命令
| ioctl命令 | 功能 | 使用场景 |
|---|---|---|
VIDIOC_QUERYCAP |
查询设备能力 | 初始化时检查是否支持视频捕获 |
VIDIOC_ENUM_FMT |
枚举支持的像素格式 | 确定Sensor输出格式(如YUYV、MJPEG) |
VIDIOC_S_FMT |
设置数据格式 | 配置分辨率、帧率、像素格式 |
VIDIOC_REQBUFS |
请求缓冲区 | 分配视频缓冲区内存 |
VIDIOC_QBUF |
入队缓冲区 | 将空缓冲区放入驱动队列 |
VIDIOC_DQBUF |
出队缓冲区 | 从驱动队列取出已填充数据的缓冲区 |
VIDIOC_STREAMON |
启动视频流 | 开始采集图像数据 |
VIDIOC_STREAMOFF |
停止视频流 | 停止采集,释放资源 |
1.3.4 Sensor驱动中的V4L2 Subdev接口
Sensor驱动作为V4L2 Subdev,需要实现以下核心回调函数:
// Sensor驱动核心回调结构
static const struct v4l2_subdev_core_ops sensor_core_ops = {
.s_power = sensor_s_power, // 电源管理
.ioctl = sensor_ioctl, // 自定义ioctl
};
static const struct v4l2_subdev_video_ops sensor_video_ops = {
.s_stream = sensor_s_stream, // 启动/停止视频流
.g_frame_interval = sensor_g_frame_interval, // 获取帧率
.s_frame_interval = sensor_s_frame_interval, // 设置帧率
};
static const struct v4l2_subdev_pad_ops sensor_pad_ops = {
.enum_mbus_code = sensor_enum_mbus_code, // 枚举媒体总线格式
.get_fmt = sensor_get_fmt, // 获取当前格式
.set_fmt = sensor_set_fmt, // 设置格式
};
static const struct v4l2_subdev_ops sensor_ops = {
.core = &sensor_core_ops,
.video = &sensor_video_ops,
.pad = &sensor_pad_ops,
};
关键点:
s_stream是Sensor驱动的核心入口,调用时驱动需要配置MIPI时序、启动Sensor输出、并使能CSI接收。多Camera切换时,通过s_stream(0)停止当前Sensor,再s_stream(1)启动目标Sensor。
1.4 本章小结
本章介绍了RK平台Camera子系统的三大核心内容:
- 硬件架构:Sensor → MIPI CSI → VIPP → ISP → DMA的流水线结构,支持多路Camera同时接入
- 软件栈层次:应用层 → 框架层(V4L2) → 驱动层 → 硬件层的分层设计
- V4L2框架:Video Device、Subdev、Media Controller三大核心对象,以及关键ioctl命令