第2章:开发环境搭建——RK SDK获取与编译、内核配置、DTS设备树编写、Camera模组硬件接口确认
做Camera驱动开发,第一步不是写代码,而是把环境搭好。我见过太多新手,SDK还没编译通过就急着改驱动,最后发现是编译器版本不对,白白浪费几天时间。这一章,咱们就把这些基础工作做扎实。
2.1 RK SDK获取与版本选择
瑞芯微的SDK分两种:一种是全功能BSP,包含U-Boot、内核、Buildroot/Android;另一种是纯内核源码。做Camera开发,我建议直接拉全功能BSP,因为里面带了ISP相关的固件和工具链。
# 以RK3588为例,拉取Linux BSP
repo init -u https://github.com/rockchip-linux/manifests -b linux-5.10-gen-rkr4
repo sync -c --no-tags -j8
这里有个坑——分支选择。RK的SDK分支命名很乱,有叫linux-5.10-gen-rkr4的,也有叫rk3588-developer的。我建议优先选带gen字样的分支,那是通用稳定版。我曾经图新鲜用了next分支,结果ISP驱动接口变了,折腾了两天才回退。
| 芯片型号 | 推荐内核版本 | SDK分支示例 | 备注 |
|---|---|---|---|
| RK3588 | 5.10 | linux-5.10-gen-rkr4 | ISP3.0,支持多路MIPI |
| RK3568 | 4.19 / 5.10 | rk356x-linux-4.19 | ISP2.0,性价比高 |
| RK3399 | 4.4 / 4.19 | rk3399-linux-4.4 | 老平台,资料多 |
2.2 内核配置与ISP相关选项
SDK拉下来之后,第一件事就是配内核。很多人直接make defconfig,然后发现Camera设备节点没出来——因为ISP驱动根本没编译进去。
RK的Camera驱动依赖几个关键配置项,我列个清单,你照着配就行:
# 必须开启的ISP相关配置
CONFIG_VIDEO_ROCKCHIP_ISP=y # ISP主驱动
CONFIG_VIDEO_ROCKCHIP_ISP_VERSION=30 # ISP版本,RK3588用30
CONFIG_VIDEO_ROCKCHIP_CIF=y # 并行接口支持
CONFIG_VIDEO_ROCKCHIP_CSI2=y # MIPI CSI-2支持
CONFIG_VIDEO_ROCKCHIP_CSI2_DMA=y # CSI2 DMA模式
CONFIG_VIDEO_ROCKCHIP_ISPP=y # ISP后处理单元
# Sensor驱动(以IMX415为例)
CONFIG_VIDEO_IMX415=y
# 调试选项(开发阶段建议开启)
CONFIG_VIDEO_ROCKCHIP_ISP_DEBUG=y
CONFIG_VIDEO_ROCKCHIP_CIF_DEBUG=y
CONFIG_VIDEO_ROCKCHIP_ISP_VERSION=30;RK3568是ISP2.0,对应20。配错了内核编译不会报错,但驱动加载时会直接panic。
配完内核,编译命令也很简单:
# 设置交叉编译环境
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
# 编译内核
make rk3588-evb1-lp4-v10-linux.img -j8
编译完会在arch/arm64/boot/下生成Image和dtb文件。我习惯把dtb单独拷出来,方便后面调试时只更新设备树。
2.3 DTS设备树编写——Camera节点的灵魂
设备树是Camera驱动和硬件之间的桥梁。写不好DTS,驱动再牛也白搭。RK的Camera DTS结构很清晰,分三层:
- SoC级dtsi:定义ISP、CSI2控制器等硬件模块,一般不用改。
- 板级dts:定义MIPI D-PHY、I2C、GPIO等引脚复用,需要根据原理图配。
- Sensor节点:定义Camera模组的各项参数,这是咱们主要写的地方。
下面是一个IMX415的完整Sensor节点示例:
// rk3588-evb1-imx415.dtsi
&i2c4 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c4m2_xfer>;
imx415: imx415@1a {
compatible = "sony,imx415";
reg = <0x1a>;
clocks = <&cru CLK_MIPI_CAMARAOUT_M4>;
clock-names = "xvclk";
power-domains = <&power RK3588_PD_VI>;
pinctrl-names = "default";
pinctrl-0 = <&mipin4_mipicamera4>;
// 电源配置
avdd-supply = <&vcc_2v8_cam>;
dvdd-supply = <&vcc_1v2_cam>;
dovdd-supply = <&vcc_1v8_cam>;
// MIPI配置
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "CMK-OT2117-PC1";
rockchip,camera-module-lens-name = "M12-40IRC-4MP-F20";
// 数据通道
port {
imx415_out: endpoint {
remote-endpoint = <&mipi4_csi2_input>;
data-lanes = <1 2 3 4>;
};
};
};
};
// 连接CSI2控制器
&mipi4_csi2 {
status = "okay";
ports {
port@0 {
reg = <0>;
mipi4_csi2_input: endpoint {
remote-endpoint = <&imx415_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
mipi4_csi2_output: endpoint {
remote-endpoint = <&isp0_in>;
};
};
};
};
写DTS时,有几个地方特别容易翻车:
- I2C地址:Sensor的I2C地址一般是7位,但有些模组手册给的是8位地址。我遇到过把0x1a写成0x35的,结果i2cdetect死活扫不到设备。
- data-lanes顺序:RK的CSI2控制器要求data-lanes从1开始连续编号。如果Sensor只用了2条lane,写成
data-lanes = <1 2>;就行,别写<0 1>。 - 电源时序:有些Sensor对上电顺序很敏感。我曾在RK3568上调试OV5640,avdd和dvdd上电间隔不够,导致Sensor初始化失败。后来加了
regulator-delay-us才解决。
2.4 Camera模组硬件接口确认
写DTS之前,必须先确认硬件接口。我一般会拿原理图和Sensor模组手册对照着看,重点确认这几项:
| 接口类型 | 确认内容 | 常见问题 |
|---|---|---|
| MIPI CSI | lane数量、时钟极性、数据极性 | 正负极性接反,导致无法锁定同步 |
| I2C | 地址、电压域(1.8V/3.3V) | 电压不匹配,I2C通信失败 |
| 电源 | AVDD/DVDD/IOVDD电压值、上电时序 | 电压偏差超过5%,Sensor工作异常 |
| 时钟 | 主时钟频率(24MHz/27MHz等) | 频率不准,导致帧率异常 |
| 复位/使能 | GPIO编号、有效电平 | 复位时序不对,Sensor无法启动 |
确认硬件接口时,我有个小技巧:用示波器量一下MIPI时钟线的波形。如果时钟频率和Sensor手册标称值差超过1%,那多半是晶振或者PLL配置有问题。别问我怎么知道的——有一次我调了一个星期的图像花屏,最后发现是27MHz晶振焊成了24MHz。
2.5 本章知识体系
下面这张图总结了开发环境搭建的核心流程,从SDK获取到硬件确认,每一步都环环相扣:
核心要点:
- SDK分支选
gen稳定版,别追新 - 内核配置注意ISP版本号,配错了直接panic
- DTS编写时I2C地址、data-lanes、电源时序是三大易错点
- 硬件确认用示波器量时钟,比看原理图靠谱
环境搭建这部分,说白了就是磨刀不误砍柴工。我见过太多人急着写驱动,结果SDK没编译过、DTS配错了、硬件接口没确认,最后花在排查上的时间比写代码还多。你按这个流程走一遍,后面调试Camera驱动会顺畅很多。