摄像头 Camera 驱
本文档介绍 RK3588 MIPI-CSI / ISP / V4L2 子系统在 Linux 6.1 内核中的驱动结构、设备树配置和用户态调试。
适用范围: RK3588 Linux 6.1 Debian 12 / Ubuntu 22.04 系统,C-3588LQ V1.0 + SHIMETAPI-M5-R2A V1.0 底板。
1. 概念基础
1.1 Camera 子系统架构
先解释图中几个词:Sensor 是摄像头里的感光芯片(如 IMX415);MIPI-CSI 是摄像头行业通用的高速差分总线,图像数据就沿着它传进主控;CIF(Camera Interface)在主控一侧负责把数据收进来;ISP(Image Signal Processor,图像信号处理器)对原始图像做去噪、自动曝光等处理;V4L2(Video for Linux 2)则是 Linux 内核的统一视频接口,应用程序统一通过 /dev/videoXX 这类节点取画面。
数据从镜头到应用的完整路径如下:
Sensor (e.g. IMX415)
↓ MIPI-CSI 2/4 lanes
rk_cif (Camera Interface)
↓
rk_isp (Image Signal Processor)
↓
V4L2 video node (/dev/videoXX)
↓
应用(libcamera / gst-launch / OpenCV)RK3588 内置双路 ISP,最高 48MP @ 30fps。
1.2 支持的像素格式
- RAW8 / RAW10 / RAW12 / RAW14
- YUV422(UYVY / YUYV)
- RGB888
- MJPEG / H.264(编码后)
1.3 模块组合
| 组件 | 作用 |
|---|---|
| Camera Sensor | 图像采集(OV5648 / IMX415 等) |
| MIPI-CSI PHY | 物理层差分传输 |
| CIF(Camera IF) | 数据接收 |
| ISP | 图像处理(去噪、自动曝光等) |
| V4L2 / Media | 内核标准接口 |
2. 准备工作
2.1 硬件清单
| 组件 | 型号/规格 | 数量 | 备注 |
|---|---|---|---|
| 主控板 | C-3588LQ 核心板 + SHIMETAPI-M5-R2A 底板 | 1 | |
| 调试串口线 | USB 转 TTL(3.3V) | 1 | 波特率 1500000 |
| MIPI-CSI 摄像头 | OV5648 / IMX415 / SC3338 | 1 | 2-lane / 4-lane |
| FPC 排线 | 24 pin / 30 pin | 1 | 连接摄像头模块 |
2.2 引脚
摄像头经 FPC 排线接入底板,关键信号对应关系如下:
| 主控板引脚 | 摄像头引脚 | 功能说明 |
|---|---|---|
| CSI_CLK_P / CSI_CLK_N | CLK_P/N | MIPI 时钟 |
| CSI_D0_P / D0_N | D0_P/N | Lane 0 |
| CSI_D1_P / D1_N | D1_P/N | Lane 1 |
| I2C3_SDA / SCL | SDA / SCL | Sensor SCCB / I2C 控制 |
| RESET / PWDN | RESET / PWDN | GPIO 控制 |
3. 软件准备
3.1 内核配置
摄像头要跑起来,内核里得有 V4L2 框架、Rockchip 的 ISP/CIF 驱动,以及所用 Sensor 的驱动:
CONFIG_MEDIA_SUPPORT=y
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_VIDEO_V4L2=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEO_ROCKCHIP_ISP1=y /* RK3588 ISP */
CONFIG_VIDEO_ROCKCHIP_CIF=y /* CIF(Camera IF) */
CONFIG_VIDEO_OV5648=y /* 示例 sensor */
CONFIG_VIDEO_IMX415=y
CONFIG_VIDEO_GC2093=y
CONFIG_OF=y3.2 设备树
设备树里把 Sensor、CIF、ISP 三段连成一条数据通路:Sensor 挂在 I2C3 下,两侧各有一个 endpoint,用 remote-endpoint 互相指过去;data-lanes 声明用了几条数据 lane:
/* MIPI CSI 接收 */
cif_mipi0: cif-mipi-lvds2@fd580000 {
compatible = "rockchip,rk3588-cif-mipi-lvds2";
reg = <0x0 0xfd580000 0x0 0x10000>;
interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru CLK_CIF1>, <&cru HCLK_CIF1>;
clock-names = "cif_clk", "hclk";
status = "okay";
};
/* ISP 主路径 */
rkisp0: rkisp@fd910000 {
compatible = "rockchip,rk3588-rkisp1";
reg = <0x0 0xfd910000 0x0 0x8000>;
...
status = "okay";
};
/* 示例 Sensor 子节点(在 cif_mipi0 下挂载) */
&cif_mipi0 {
status = "okay";
port {
cif_mipi0_in: endpoint {
remote-endpoint = <&imx415_0_out>;
data-lanes = <1 2 3 4>;
clock-lanes = <0>;
};
};
};
/* Sensor 端点(与 cif_mipi0 的 in 端口绑定) */
&i2c3 {
status = "okay";
imx415_0: imx415@1a {
compatible = "sony,imx415";
reg = <0x1a>;
clocks = <&cru CLK_CAM1_OUT>;
clock-names = "xvclk";
reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
pwdn-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>;
port {
imx415_0_out: endpoint {
remote-endpoint = <&cif_mipi0_in>;
data-lanes = <1 2 3 4>;
clock-lanes = <0>;
};
};
};
};4. 设备端 V4L2
以下命令在板子上执行,先确认视频节点齐全,再实际抓一帧验证。
4.1 查看视频节点
v4l2-ctl --list-devices实机输出(节选):
rkisp_mainpath (platform:rkisp0-vir0):
/dev/video11
/dev/video12
/dev/video13
/dev/video14
/dev/video15
/dev/video16
/dev/video17
rkisp-statistics (platform: rkisp):
/dev/video18
/dev/video19
rkcif-mipi-lvds2 (platform:rkcif-mipi-lvds2):
/dev/media0本机的 /dev/video11~17 是 ISP 主路径输出(多路流),18~19 是 ISP 统计流。如果没接摄像头,可能只看到占位节点。
4.2 查看节点能力
v4l2-ctl -d /dev/video11 --all输出里重点看这几项:
- Driver / Card
- Bus info
- Capabilities(V4L2_CAP_VIDEO_CAPTURE 等)
- Format(分辨率 + pixelformat)
- Frame rates
4.3 采集测试
# 5 帧采集到当前目录(output.ppm)
v4l2-ctl -d /dev/video11 --set-fmt-video=width=1920,height=1080,pixelformat=NV12
v4l2-ctl -d /dev/video11 --stream-mmap=3 --stream-count=5 --stream-save=output.ppm命令跑完后当前目录生成 output.ppm,用图片查看器打开能看到画面,就说明采集链路正常。
4.4 安装工具
如果提示找不到 v4l2-ctl 命令,先安装工具包:
apt install -y v4l-utils4.5 通过 gst-launch 抓流(GStreamer)
GStreamer 是一个多媒体流水线框架,适合直接把摄像头画面录成视频文件:
apt install -y gstreamer1.0-tools gstreamer1.0-plugins-good
# 采集 5 秒到 MP4 文件
gst-launch-1.0 v4l2src device=/dev/video11 num-buffers=300 \
! 'video/x-raw,format=NV12,width=1920,height=1080' \
! videoconvert ! x264enc ! h264parse ! mp4mux \
! filesink location=test.mp45. 设备树添加 Sensor(PC 端流程)
如需添加新 sensor(例如 IMX415),按下面的流程改设备树。
[电脑端] 编辑板级 .dts:
&cif_mipi0 {
status = "okay";
/* 数据通路绑定 */
};
&i2c3 {
status = "okay";
clock-frequency = <400000>;
imx415_0: imx415@1a {
compatible = "sony,imx415";
reg = <0x1a>;
clocks = <&cru CLK_CAM1_OUT>;
clock-names = "xvclk";
reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
pwdn-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>;
port {
imx415_0_out: endpoint {
remote-endpoint = <&cif_mipi0_in>;
data-lanes = <1 2 3 4>;
clock-lanes = <0>;
};
};
};
};
&cif_mipi0 {
port {
cif_mipi0_in: endpoint {
remote-endpoint = <&imx415_0_out>;
data-lanes = <1 2 3 4>;
clock-lanes = <0>;
};
};
};电脑端 重编译烧录后,设备端应出现 imx415 4-001a 子设备节点,用 dmesg | grep -i imx415 能看到探测成功的日志。
6. 代码解读
6.1 内核驱动注册(ISP)
ISP 驱动同样是标准的 platform driver,靠 of_match_table 里的 compatible 与设备树节点配对:
// drivers/media/platform/rockchip/isp/rkisp1.c(简化)
static struct platform_driver rkisp1_plat_drv = {
.probe = rkisp1_plat_probe,
.remove = rkisp1_plat_remove,
.driver = {
.name = "rkisp1",
.of_match_table = rkisp1_plat_of_match,
},
};6.2 调用链
应用从打开节点到拿到一帧数据,中间经过这些步骤:
用户空间: gst-launch-1.0 v4l2src ...
→ open(/dev/video11) /* V4L2 */
→ VIDIOC_S_FMT / VIDIOC_REQBUFS /* 设置格式 / 请求 buffer */
→ DQBUF /* 出队,拿到一帧 */
→ rkisp1_isr() /* 中断中填 buffer */
→ DMA 搬运 ISP → memory
→ 应用拿到 NV12 / YUV 数据7. 故障排除
7.1 没有 video 节点
dmesg | grep -i isp
dmesg | grep -i cif
dmesg | grep -i mipi可能原因:ISP / CIF / MIPI PHY 节点未 enable。
7.2 节点存在但采集失败
v4l2-ctl -d /dev/video11 --all看 capabilities 中是否有 V4L2_CAP_VIDEO_CAPTURE;没有的话,说明该节点不是采集设备。
7.3 Sensor 探测失败
- 检查 I2C 地址
- 检查 RESET / PWDN GPIO 拉高拉低顺序
- 检查
xvclk频率(24 MHz)
