ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

RK3588+IMX415摄像头适配:设备树配置与调试实战

RK3588+IMX415摄像头适配:设备树配置与调试实战 1. 链路整体设计与思路拆解1.1 一条完整的视频数据路径先说结论在RK3588上把IMX415跑起来本质上是在做一件事——让sensor输出的RAW图像数据沿着一条固定的硬件路径最终到达内存里变成你应用程序可以拿到的buffer。这条路径在RK3588上大概是这样的IMX415 sensorMIPI CSI-2 发送端 ↓ MIPI D-PHY 物理层4 lane CSI2 DPHYRK3588 的 csi2_dphy0/csi2_dphy1 ↓ RKCIFRockchip Camera Interface接收并转存RAW数据 ↓ RKISP图像信号处理器做3A、降噪、坏点校正等 ↓ DDR内存V4L2/Media framework 管理的buffer很多朋友一开始就懵在这里为什么RK3588的DTS里有csi2_dphy_hw、csi2_dphy0、rkcif、rkcif_mipi_lvds0、rkcif_mipi_lvds0_sditf、rkisp、rkisp_vir0这么多节点其实它们就是上面这条路径上的各个硬件模块对应的软件抽象一个都不能少。IMX415是索尼的一款1/2.8英寸约830万像素的CMOS sensor支持4K30输出接口是标准的MIPI CSI-2默认4 lane。RK3588的MIPI CSI控制器支持最多4 lane输入两者搭配在硬件上很顺。你要做的不是像单片机那样写一堆寄存器操作而是把这些硬件模块在设备树里按正确的拓扑关系“串”起来驱动才能按图索骥完成链路初始化。1.2 为什么RK3588适配摄像头必须看懂DTSRockchip的Linux SDK5.10内核vendor分支对camera这条链路的驱动划分得很细sensor驱动只负责初始化sensor、设置分辨率、曝光增益phy驱动只负责配置D-PHY的lane速率、时钟cif驱动只负责接收数据isp驱动只负责图像处理。它们之间谁也不直接知道对方的存在全靠设备树里endpoint的remote-endpoint引用关系来建立“认识”。这意味着你在DTS里写错一个>pinctrl { cam_imx415: cam-imx415 { rockchip,pins 2 RK_PB5 RK_FUNC_GPIO pcfg_pull_up, 2 RK_PB4 RK_FUNC_GPIO pcfg_pull_up; }; };RK_PB5这种宏展开后就是GPIO组的位号第一个数字2代表GPIO2组。写错了直接导致驱动操作了错误的引脚轻则sensor不工作重则和别的外设打架务必和原理图一一核对。然后是电源。IMX415是典型的3路供电sensorAVDD模拟供电2.8VDOVDD IO供电1.8VDVDD数字核心供电1.2V。RK3588的sensor驱动probe时会检查这三路regulator是否存在缺失会直接报-EPROBE_DEFER或者no regulator provided。如果你的板子上电压都是默认常供的那也要在DTS里用固定电压regulator补上不能省略vcc2v8_sensor: vcc2v8-sensor-regulator { compatible regulator-fixed; regulator-name vcc2v8_sensor; regulator-boot-on; regulator-always-on; regulator-min-microvolt 2800000; regulator-max-microvolt 2800000; }; vcc1v8_sensor: vcc1v8-sensor-regulator { compatible regulator-fixed; regulator-name vcc1v8_sensor; regulator-boot-on; regulator-always-on; regulator-min-microvolt 1800000; regulator-max-microvolt 1800000; }; vcc1v2_sensor: vcc1v2-sensor-regulator { compatible regulator-fixed; regulator-name vcc1v2_sensor; regulator-boot-on; regulator-always-on; regulator-min-microvolt 1200000; regulator-max-microvolt 1200000; };时钟方面IMX415的xvclk一般要求27MHzDTS里通过clocks引用CLK_MIPI_CAMERAOUT_M0并在sensor节点里用clock-frequency显式声明频率。Rockchip的sensor驱动会在stream on阶段把时钟配置到这个频率。如果你发现sensor I2C都能读但就是不出图时钟频率不对是一个很容易踩的坑。2.3 IMX415的sensor节点配置详解接下来是核心的sensor节点。挂在I2C4下面地址0x1a完整配置如下i2c4 { status okay; clock-frequency 400000; pinctrl-names default; pinctrl-0 i2c4m2_xfer; imx415: imx4151a { compatible sony,imx415; reg 0x1a; clocks cru CLK_MIPI_CAMERAOUT_M0; clock-names xvclk; clock-frequency 27000000; pinctrl-names rockchip,camera_default; pinctrl-0 cam_imx415; reset-gpios gpio2 RK_PB5 GPIO_ACTIVE_HIGH; pwdn-gpios gpio2 RK_PB4 GPIO_ACTIVE_HIGH; avdd-supply vcc2v8_sensor; dovdd-supply vcc1v8_sensor; dvdd-supply vcc1v2_sensor; rockchip,camera-module-index 0; rockchip,camera-module-facing back; rockchip,camera-module-name default; rockchip,camera-module-lens-name default; port { imx415_out: endpoint { remote-endpoint mipi_dphy0_in_imx415; >csi2_dphy_hw { status okay; }; csi2_dphy0 { status okay; ports { #address-cells 1; #size-cells 0; port0 { reg 0; #address-cells 1; #size-cells 0; mipi_dphy0_in_imx415: endpoint0 { reg 0; remote-endpoint imx415_out; >rkcif { status okay; }; rkcif_mipi_lvds0 { status okay; port { rkcif_mipi_in_dphy0: endpoint { remote-endpoint mipi_dphy0_out_rkcif; }; }; }; rkcif_mipi_lvds0_sditf { status okay; port { rkcif_mipi_lvds0_sditf_out: endpoint { remote-endpoint rkisp0_in_sditf; }; }; };rkcif_mipi_lvds0的职责是把MIPI数据包接收下来解析成RAW图像写进内存。它自己就能生成一个video节点也就是说即使不配ISP只靠rkcif也能采到RAW图。rkcif_mipi_lvds0_sditf则是cif内部的一条转送通路专门把数据继续送给ISP做处理。很多板子为了节省内存带宽会直接把这条通路禁掉只用RAW直出这属于功能取舍不是必须项。最后是ISP相关节点rkisp { status okay; }; rkisp_vir0 { status okay; port { #address-cells 1; #size-cells 0; rkisp0_in_sditf: endpoint0 { reg 0; remote-endpoint rkcif_mipi_lvds0_sditf_out; }; }; };rkisp_vir0是rkisp虚拟出来的主控制器节点它内部会再注册出mainpath、selfpath、rawpath等多个video节点。你在用户空间如果想拿到已经处理好的NV12/RGB图像就是从mainpath那个video节点取的。DTS写到这一步链路已经完整了sensor - dphy0 - rkcif - sditf - rkisp。编译内核后把dtb烧进板子启动日志里应该能看到sensor probe成功的消息。2.6 编译、烧录与启动日志确认DTS修改后需要重新编译内核设备树。用Rockchip SDK时通常直接编译整个boot.img或者单独编译dtb。以SDK默认的构建方式为例./make.sh dtb ./make.sh boot.img烧录后启动用dmesg | grep -i imx415应该能看到[ 9.123456] imx415 4-001a: Detected imx415 sensor同时i2cdetect -y 4应该能看到0x1a这个地址。如果这两条都没有别急着查应用层先把DTS的每一环按上面的清单重新对一遍。我见过最多的失误就是GPIO编号写错或者regulator节点命名和实际不一致导致驱动probe被延迟。3. 内核配置与驱动确认3.1 menuconfig需要勾选的选项DTS配好只是第一步内核里这几个驱动开关必须打开否则设备树写得再完整驱动根本没编进去。以5.10版本vendor内核为例你需要在menuconfig里确认以下选项Device Drivers Multimedia support Media driver V4L platform devices Rockchip Camera CIF → CONFIG_VIDEO_ROCKCHIP_CIF Rockchip ISP → CONFIG_VIDEO_ROCKCHIP_ISP Rockchip Camera Sensors Sony IMX415 → CONFIG_VIDEO_IMX415这几个选项默认在很多SDK里是y但如果你用的是精简过的内核或者自己裁剪过defconfig很容易漏掉。漏掉CONFIG_VIDEO_IMX415的表现很典型DTS写对了i2cdetect也能看到0x1a但/dev/video*里就是没有对应的sensor entitiydmesg里也安静得很。还有两个基础选项也要确认CONFIG_MEDIA_CONTROLLER和CONFIG_VIDEO_V4L2。现在的Rockchip camera框架完全依赖media controller来管理sensor、dphy、cif、isp之间的拓扑关系没有它的话media-ctl工具根本列不出东西。编译命令直接用SDK里的方式make ARCHarm64 rockchip_defconfig # 或者你用的具体defconfig make ARCHarm64 menuconfig make ARCHarm64 boot.img -j$(nproc)3.2 驱动加载与i2c探测实操内核起来后第一个要看的不是/dev/video0而是sensor驱动到底有没有成功绑定设备。dmesg | grep imx415 dmesg | grep rkcif dmesg | grep rkisp正常的probe日志里会有一句sensor register success或者Detected imx415之类。如果看到probe deferred说明驱动依赖的某个资源regulator、clock、gpio还没准备好通常是DTS里资源引用名对不上。这时候可以看cat /sys/kernel/debug/devices_deferred里面会写明具体在等什么东西排查方向一下子就清楚了。i2c探测也要做i2cdetect -y 4输出里1a符号出现说明sensor在I2C层面是活的。如果这一关就挂了后面media-ctl看到的graph一定是残缺的。这里有个细节IMX415上电后可能地址是0x1a但也有些模组因为ID引脚电平不同变成0x10探测时两个地址都留意一下。如果i2c正常但驱动没probe可以手动把驱动解绑再绑定试试用来区分是时序问题还是初始化问题echo 4-001a /sys/bus/i2c/drivers/imx415/unbind echo 4-001a /sys/bus/i2c/drivers/imx415/bind注意4-001a是bus address i2c address的组合换成你自己的总线编号。重新绑定时dmesg会再次打印probe过程比开机日志更集中。4. 跑通采集链路4.1 用media-ctl检查拓扑结构驱动都加载成功后可以用media-ctl查看整个media graph。先确认media设备编号for i in /dev/media*; do echo $i ; media-ctl -d $i -p | head -20; done找到包含IMX415那一个然后完整打印media-ctl -d /dev/media0 -p正常时你会看到一条清晰的链路sensor entity在最左边中间经过csi2 dphy、rkcif最后到rkisp。如果media graph里sensor entity压根没出现问题在sensor驱动或DTS的sensor部分如果sensor出现了但后面没连到dphy检查endpoint的remote-endpoint引用如果dphy和cif之间断了检查dphy的port1和cif的port配置。有些SDK版本里cif和sditf、isp之间的link默认不是enable状态需要手动设置。可以用media-ctl把链路固定下来media-ctl -d /dev/media0 -l imx415 4-001a:0 - csi2-dphy0:0 [1] media-ctl -d /dev/media0 -l csi2-dphy0:1 - rkcif-mipi-lvds0:0 [1] media-ctl -d /dev/media0 -l rkcif-mipi-lvds0:1 - rkcif-mipi-lvds0-sditf:0 [1] media-ctl -d /dev/media0 -l rkcif-mipi-lvds0-sditf:1 - rkisp0_vir0:0 [1]注意不同SDK的entity名称会有差异以media-ctl -p打印出来的实际名称为准。做完这步后最好再执行一遍media-ctl -d /dev/media0 -p确认所有link都变成[1]使能状态。4.2 直出RAW的v4l2命令链路拓扑没问题后先试RAW直出这样能最快判断sensor和phy部分是否正常。RK3588上rkcif的video节点是/dev/video0或者/dev/video1具体哪个是mipi-lvds0节点用v4l2-ctl --list-devices查看。IMX415输出的是RAW10 Bayer格式常见的是SG10SRGGB10。用v4l2-ctl直接采集一帧v4l2-ctl -d /dev/video0 --set-fmt-videowidth3840,height2160,pixelformatRG10 --stream-mmap --stream-count1如果sensor是4K30输出这一帧应该在几百毫秒内完成。如果超时卡住多半是lane数不匹配或者时钟配置不对。采集到的raw文件在线看的话可以用ImageJ或者PythonOpenCV转一下只要能解出Bayer马赛克图案说明数据链路已经通了。4.3 走ISP出YUV画面RAW直出通了对很多人来说只是“链路通了”但实际产品肯定要走ISP因为只有ISP才能把RAW变成人眼能看的图像同时提供自动曝光、自动白平衡这些功能。走ISP时数据会从rkcif_mipi_lvds0_sditf送到rkisp0_vir0然后从rkisp的mainpath video节点取数据显示。先查一下video设备对应关系v4l2-ctl --list-devices找到带rkisp_mainpath的那个节点。假设是/dev/video3那么采集一帧NV12图像测试v4l2-ctl -d /dev/video3 --set-fmt-videowidth1920,height1080,pixelformatNV12 --stream-mmap --stream-count30能连续采30帧不报错说明ISP处理链路正常。这里建议先用1080p测因为4K对ISP的处理速度和内存带宽要求更高万一板子的内存频率偏低4K可能会因为带宽不够丢帧。1080p跑通后再把分辨率切到4K逐级验证。4.4 用GStreamer出图命令行用GStreamer可以直接出预览画面不用自己写采集程序。前提是RK3588的图形显示环境已经跑起来HDMI接显示器、Wayland/x11窗口系统正常。gst-launch-1.0 v4l2src device/dev/video3 ! video/x-raw,formatNV12,width1920,height1080,framerate30/1 ! waylandsink如果显示环境是X11把waylandsink换成xvimagesink或者autovideosink。能看到画面说明从sensor到屏幕整个通路已经打通。后续你可以在GStreamer管线上继续接videoconvert、jpegenc、h264enc这些插件直接做推流或者录像这就是产品化的事了。还有一个经验如果GStreamer报not negotiated先检查v4l2-ctl --list-formats-ext看看当前video设备支持哪些格式和分辨率组合。IMX415的驱动里通常只注册了固定几组分辨率比如3840x216030、1920x108030、1280x72060。你随便指定一个驱动里没有的分辨率格式协商必然失败。5. 常见问题与排查技巧实录5.1 i2c读不到sensor全是FF或者UU这是量产调试阶段遇到最多的故障。级别从高到低大概分几层供电没到位、时钟没起振、复位脚电平不对、I2C地址不对。供电问题建议用万用表直接量IMX415芯片附近的AVDD/DOVDD/DVDD测试点三路电压要和规格书一致。很多模组是把三路供电合在一个板级电源芯片里如果板子设计成需要某个GPIO来enable这颗电源芯片但DTS里没配就会出现上电时间不够或者压根没电。时钟问题用示波器探头量sensor的xvclk pin27MHz应该是稳定正弦或方波。看不到波形就查DTS里clocks引用是否正确以及内核里sensor驱动有没有在probe阶段正确enable clock。这里有个坑有些板子的MCLK脚默认被别的外设复用DTS里如果没有写pinctrl的mux时钟输出根本到不了sensor脚。复位脚问题可以用GPIO sysfs手动拉一下试试。先把DTS里的reset-gpios临时禁用或改成别的空脚然后在用户空间控制GPIOecho 75 /sys/class/gpio/export echo out /sys/class/gpio/gpio75/direction echo 0 /sys/class/gpio/gpio75/value sleep 0.1 echo 1 /sys/class/gpio/gpio75/value之后再跑i2cdetect如果地址出现了说明就是DTS里gpio编号或极性写错。5.2 probe失败或者卡在probe deferred驱动probe失败最麻烦的地方是它不会告诉你详细原因只会给一行failed to probe。这时候除了看devices_deferred还可以在挂载debugfs后看sensor驱动自己的状态cat /sys/kernel/debug/imx415/status有些SDK版本里sensor驱动会有调试节点能直接显示当前供电、时钟、sensor ID的实测值一目了然。另外IMX415的sensor ID校验很严格。驱动probe时会读取特定寄存器比对芯片ID如果你的模组实际是IMX415兼容版或者国产替换料ID可能略有差异需要看驱动源码确认它读的是哪些寄存器。这个场景不常见但遇到会非常隐蔽I2C正常、供电正常、可就是报chip id mismatch。5.3 能出图但花屏、偏色、亮度异常花屏先查lane顺序。IMX415作为sensor端固定输出>
返回列表