2. 基于Linux V4L2的MIPI摄像头驱动加载与设备树配置
任务说明
在嵌入式 Linux 上,MIPI 摄像头能否被识别,取决于三件事是否对齐:设备树里 CSI-2 接收端(SoC 侧)与摄像头(Sensor 侧)的节点、I2C 地址、时钟/电源/复位引脚,以及内核中对应的 Sensor 驱动是否被编译并匹配。本案例以一颗典型 I2C 接口 MIPI Sensor(示例用 ov5647,可替换为实际型号)为例,给出最小可用的设备树节点与驱动加载流程,最终目标是生成 /dev/videoX 节点。
环境与依赖
- 内核已开启
CONFIG_VIDEO_V4L2、CONFIG_MEDIA_CONTROLLER、CONFIG_VIDEO_DEV,以及对应 Sensor 驱动(如CONFIG_VIDEO_OV5647)。 - SoC 侧 CSI-2 接收控制器驱动已启用(如 Rockchip
CONFIG_VIDEO_ROCKCHIP_ISP/ 通用CONFIG_VIDEO_CSI2)。 - 交叉编译工具链、内核源码树、
dtc工具。
设备树配置
下面给出 Sensor 节点与 CSI-2 接收端的关键片段。I2C 地址、reg、时钟频率、data-lanes 必须与硬件原理图一致,否则驱动 probe 会失败。
/* 1. Sensor 节点:挂在 I2C 总线上 */
&i2c4 {
status = "okay";
clock-frequency = <100000>;
ov5647: camera@36 {
compatible = "ovti,ov5647";
reg = <0x36>;
clocks = <&clk_cam0>;
clock-names = "xclk";
powerdown-gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
status = "okay";
port {
ov5647_out: endpoint {
remote-endpoint = <&csi2_in>;
clock-lanes = <0>;
data-lanes = <1 2>; /* 2-lane,按硬件填写 */
};
};
};
};
/* 2. SoC 侧 CSI-2 接收端 */
&csi2 {
status = "okay";
port {
csi2_in: endpoint {
remote-endpoint = <&ov5647_out>;
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
};
/* 3. 摄像头时钟源 */
&clk_cam0 {
clock-frequency = <24000000>;
};
驱动加载与设备节点生成
Sensor 驱动通常以模块或内建方式存在。若为模块,加载后内核通过 compatible 匹配设备树节点,probe 成功即注册 V4L2 subdev,并触发 CSI-2 接收端创建 video 设备。
# 编译设备树(以 Rockchip 为例,按实际平台替换)
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- dtbs
# 加载 Sensor 驱动模块(若为内建则跳过)
modprobe ov5647
# 查看内核是否匹配成功
dmesg | grep -i -E "ov5647|csi2|v4l2"
# 列出 video 设备节点
ls -l /dev/video*
# 查看设备能力,确认是采集设备
v4l2-ctl -d /dev/video0 --all
验证方法与通过条件
dmesg中出现 Sensor 驱动 probe 成功日志,且无-EPROBE_DEFER持续重试或-ENODEV。ls /dev/video*出现新的/dev/videoX节点。v4l2-ctl -d /dev/videoX --all能正常输出驱动名、总线信息与支持的格式,说明 V4L2 设备已注册。- 若 probe 失败,优先检查:I2C 地址是否与原理图一致、
data-lanes两端是否匹配、时钟与 GPIO 是否被其他节点占用、Sensor 驱动是否已编译进内核。
常见问题
remote-endpoint两端必须互相指向,否则 media controller 无法建立链路。data-lanes在 Sensor 端与 CSI-2 端必须一致,否则链路协商失败。- 若使用
media-ctl验证链路,可执行media-ctl -p查看 entity 与 pad 连接关系。