摄像头 Camera 驱动
1. 概述
1.1 功能简介
Camera 驱动负责管理摄像头传感器的初始化、数据采集和图像输出。RK3576 内置 ISP(Image Signal Processor)图像处理引擎,支持 MIPI-CSI 接口连接摄像头传感器,可实现高分辨率图像采集和视频录制,适用于视觉检测、视频监控、人脸识别等场景。M4-R2 底板具体的摄像头接口(MIPI-CSI FPC 座)以实际物料为准(待板上验证)。
1.2 应用场景
- 视频监控:IP 摄像头、NVR 录像
- 人脸识别:门禁、考勤、支付
- 工业视觉:产品检测、缺陷识别
- 智能安防:智能门铃、巡检机器人
- 视频会议:USB / MIPI 摄像头接入
1.3 工作原理
RK3576 的 Camera 接口支持以下特性:
| 特性 | 说明 |
|---|---|
| MIPI-CSI | 支持 MIPI-CSI 接口 |
| 数据 lanes | 单接口最多 4 lanes |
| ISP | 内置 ISP 图像处理引擎 |
| 分辨率 | 最高支持 4K 图像采集 |
| 像素格式 | RAW8/10/12、YUV422、RGB888 |
| 帧率 | 最高 60fps(1080p) |
详见 RK 官方文档:[《Rockchip_Developer_Guide_Linux_Software_CN.pdf》]
2. 硬件准备
2.1 硬件清单
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | C-3576BQ 核心板 + M4-R2 底板 | 1 | |
| 调试串口线 | USB 转 TTL(3.3V) | 1 | 波特率 1500000 |
| MIPI CSI 摄像头模块 | OV5648 / IMX415 / SC3338 | 1 | MIPI-CSI 2-lane / 4-lane |
| FPC 排线 | 24pin / 30pin | 1 | 用于连接摄像头模块 |
2.2 引脚连接
以 MIPI-CSI 摄像头为例:
| 主控板引脚 | 摄像头引脚 | 功能说明 |
|---|---|---|
| CSI_CLK_P / CSI_CLK_N | CLK_P / CLK_N | MIPI 时钟差分对 |
| CSI_D0_P / CSI_D0_N | D0_P / D0_N | MIPI 数据 lane 0 |
| CSI_D1_P / CSI_D1_N | D1_P / D1_N | MIPI 数据 lane 1 |
| I2C_SDA | SDA | SCCB/I2C 控制 |
| I2C_SCL | SCL | SCCB/I2C 控制 |
| 3.3V / 1.8V | VCC | 传感器电源 |
| GND | GND | 共地 |
| GPIO / RESET | RESET | 传感器复位 |
| GPIO / PWDN | PWDN | 传感器掉电控制 |
M4-R2 底板具体是否引出 MIPI-CSI 摄像头接口及 FPC 座位置,以实际原理图与 SDK 配置为准(待板上验证)。实际操作时应确认引脚连接正确。
2.3 硬件确认
# 查看 V4L2 设备
v4l2-ctl --list-devices
# 输出示例:
# rkvdec2 (platform):
# /dev/video0
# /dev/video1
# 查看摄像头信息
v4l2-ctl -d /dev/video0 --all3. 软件准备
3.1 内核配置
确认以下内核配置已启用:
CONFIG_VIDEO=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_VIDEO_ROCKCHIP_ISP1=y
CONFIG_VIDEO_ROCKCHIP_ISP=y
CONFIG_VIDEO_OV5648=y
CONFIG_VIDEO_IMX415=y
CONFIG_OF=y3.2 设备树
RK3576 的 MIPI-CSI 控制器在设备树中定义(以下为 RK 平台通用结构示例):
csi2_dphy0: csi2-dphy@fe0e0000 {
compatible = "rockchip,rk3576-csi2-dphy";
reg = <0x0 0xfe0e0000 0x0 0x10000>;
clocks = <&cru PCLK_MIPICSIPHY>, <&cru CLK_REF_MIPI0>;
clock-names = "pclk", "ref";
resets = <&cru SRST_P_MIPICSIPHY>;
reset-names = "dphy";
status = "disabled";
};
rkisp: isp@fe720000 {
compatible = "rockchip,rk3576-rkisp";
reg = <0x0 0xfe720000 0x0 0x10000>;
interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru ACLK_ISP0>, <&cru HCLK_ISP0>,
<&cru CLK_ISP0>, <&cru PCLK_ISP0>;
clock-names = "aclk", "hclk", "clk_isp", "pclk";
resets = <&cru SRST_A_ISP0>, <&cru SRST_H_ISP0>;
reset-names = "aclk", "hclk";
status = "disabled";
};以上寄存器基地址、中断号与时钟标识为 RK 平台通用结构示例,具体数值以实际发布的 RK3576 SDK 设备树为准(待板上确认)。
4. 操作步骤
4.1 查看摄像头设备
# 查看 V4L2 设备
v4l2-ctl --list-devices
# 查看摄像头支持的格式
v4l2-ctl -d /dev/video0 --list-formats-ext
# 查看摄像头当前参数
v4l2-ctl -d /dev/video0 --list-ctrls4.2 使用 v4l2-ctl 测试摄像头
# 抓取一帧图像(BMP 格式)
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=NV12 --stream-mmap --stream-count=1 --stream-to=frame.raw
# 使用 ffmpeg 转换格式
ffmpeg -f rawvideo -pix_fmt nv12 -s 1920x1080 -i frame.raw -frames:v 1 output.bmp
# 使用 fswebcam 抓图(需安装)
fswebcam -d /dev/video0 -r 1920x1080 --no-banner snapshot.jpg4.3 使用 GStreamer 测试视频流
# 预览视频流(需安装 gstreamer)
gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! videoconvert ! autovideosink
# 录制视频
gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,format=NV12,width=1920,height=1080,framerate=30/1 ! videoconvert ! avimux ! filesink location=capture.avi4.4 设备树中配置摄像头
&csi2_dphy0 {
status = "okay";
ports {
port@0 {
csi2_dphy0_in: endpoint {
remote-endpoint = <&ov5648_out>;
data-lanes = <1 2>;
};
};
};
};
&i2c3 {
status = "okay";
ov5648: camera-sensor@3c {
compatible = "ovti,ov5648";
reg = <0x3c>;
clocks = <&cru CLK_MIPI_CAMARAOUT_M3>;
clock-names = "xclk";
reset-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_LOW>;
powerdown-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_HIGH>;
port {
ov5648_out: endpoint {
remote-endpoint = <&csi2_dphy0_in>;
data-lanes = <1 2>;
clock-lanes = <0>;
};
};
};
};以上 I2C 编号、GPIO 与时钟标识为 RK 平台通用示例,具体以实际 SDK 设备树为准。
5. 代码详解
5.1 内核中 Camera 驱动的注册
// OV5648 摄像头传感器驱动(简化)
// drivers/media/i2c/ov5648.c
static struct i2c_driver ov5648_driver = {
.probe = ov5648_probe,
.remove = ov5648_remove,
.driver = {
.name = "ov5648",
.of_match_table = ov5648_of_match,
},
};
static const struct of_device_id ov5648_of_match[] = {
{ .compatible = "ovti,ov5648" },
{ /* sentinel */ }
};5.2 用户空间 Camera 操作的内核调用链
用户空间 v4l2-ctl --stream-mmap
→ open(/dev/video0)
→ v4l2_ioctl(VIDIOC_QUERYCAP)
→ v4l2_ioctl(VIDIOC_S_FMT)
→ v4l2_ioctl(VIDIOC_REQBUFS)
→ v4l2_ioctl(VIDIOC_QBUF)
→ v4l2_ioctl(VIDIOC_STREAMON)
→ rkisp_start_streaming()
→ csi2_dphy_start()
→ MIPI-CSI 接收传感器数据
→ ISP 处理图像数据6. 常见问题
6.1 摄像头无法识别
现象: v4l2-ctl --list-devices 无摄像头设备
解决方案:
# 检查 I2C 设备(传感器)
i2cdetect -y 3
# 检查 MIPI-CSI PHY 时钟
cat /sys/kernel/debug/clk/clk_ref_mipi0/clk_rate
# 检查设备树中 Camera 节点状态
# 具体节点路径以实际 DTB 反编译结果为准
dtc -I dtb -O dts /sys/firmware/fdt | grep -A3 "csi2-dphy@"确认设备树中 CSI2、ISP 节点 status = "okay",检查摄像头模块 FPC 排线连接。
6.2 图像花屏
现象: 抓取的图像有条纹或花屏
解决方案:
# 检查 MIPI 时钟配置
cat /sys/kernel/debug/clk/clk_mipi_camaraout_m3/clk_rate
# 检查 MIPI lane 配置
dmesg | grep -i csi检查 MIPI 数据 lane 连接是否正确,确认像素时钟和 MIPI 时钟匹配。
6.3 ISP 处理错误
现象: 图像色彩异常或 ISP 报错
解决方案:
# 查看 ISP 错误日志
dmesg | grep -i isp
# 检查 ISP 时钟
cat /sys/kernel/debug/clk/clk_isp0/clk_rate检查 ISP 时钟配置,确认像素格式与传感器输出格式匹配。
