RK3588 RKISP驱动代码解析:从sensor出图到/dev/video节点 简介这份资源是瑞芯微RK平台ISP子系统的Linux内核驱动源码面向从事嵌入式Linux、摄像头图像处理与V4L2框架开发的工程师及驱动学习者。代码围绕设备树匹配机制展开从of_device_id的匹配方式入手完整呈现了CIF与ISP模块的驱动实现适合用于理解RK平台图像采集链路的注册流程、平台设备与V4L2子设备的对接方式。压缩包共17个文件包含8个.h头文件、7个.c源文件以及Makefile和Kconfig各1个头文件定义寄存器、图像源与平台接口源文件实现V4L2设备、ISP控制与图像源操作Kconfig与Makefile则负责内核编译配置整体约96KB结构紧凑便于逐文件研读。目前已有1750人学习下载可作为RK ISP驱动移植、调试与二次开发的参考素材帮助读者快速定位关键数据结构与驱动入口。1. rkisp 驱动代码到底能拿来干什么从 sensor 出图到 /dev/video 节点如果你手上有块 RK3588 或 RK3568 的板子接了个 MIPI sensordmesg里能看到rkisp字样但/dev/video*死活不出图或者出了图颜色发绿、帧率对不上——那你需要的不是再翻一遍《Rockchip ISP 开发指南》而是把 rkisp 的驱动代码拉下来从probe一路读到streamon。rkisp 是 Rockchip 平台 ISP 硬件模块的 Linux 内核驱动位于内核源码drivers/media/platform/rockchip/isp/目录下负责 sensor 数据接入、ISP pipeline 配置、DMA 输出到内存最终暴露成 V4L2 的 video 节点。它解决的是「sensor 有数据、ISP 有硬件、但用户态拿不到帧」这条链路上的所有粘合问题。适合谁做 RK 平台相机 bring-up 的 BSP 工程师、调 ISP tuning 时想搞清楚参数从哪进内核的算法工程师以及被rkisp日志绕晕、想直接读源码定位问题的驱动开发者。这份代码不是独立仓库而是内核树的一部分所以「下载」的本质是拿到对应内核版本、确认 rkisp 目录完整、能编译进 Image。2. rkisp 驱动代码的目录结构与核心数据流先看懂再动手2.1 代码从哪来、放在哪、依赖什么rkisp 驱动不在独立 Git 仓库里它随 Rockchip 官方内核发布。常见做法是从 Rockchip 的 kernel 仓库拉对应分支比如develop-5.10或develop-6.1然后确认drivers/media/platform/rockchip/isp/存在。这个目录下通常有这些文件文件作用dev.c设备 probe、时钟/复位/中断申请、media device 注册capture.cvideo 节点注册、vb2 队列、DMA buffer 管理rkisp.cISP 硬件抽象层寄存器读写、pipeline 使能hw.cISP 各模块DPCC、BLC、LSC、AWB、CCM 等寄存器配置params.c3A 参数从用户态到内核的传递通道stats.c统计信息回传tuning 工具依赖csi.cMIPI CSI-2 接收端配置bridge.cISP 与 sensor 之间的 media bus 连接依赖的内核配置项一般是CONFIG_VIDEO_ROCKCHIP_ISP它又依赖CONFIG_MEDIA_SUPPORT、CONFIG_V4L2_SUBDEV_API、CONFIG_VIDEOBUF2_DMA_CONTIG等。如果你在menuconfig里找不到这个选项先确认内核版本和 Rockchip 补丁是否打全。2.2 一条帧从 sensor 到用户态要过几道手理解 rkisp 驱动关键是理解 media pipeline。典型链路是sensor subdev → csi2 subdev → rkisp subdev → rkisp capture video nodesensor 通过 I2C 配置输出 MIPI CSI-2 数据csi2 接收后交给 rkisprkisp 内部做 ISP 处理然后通过 DMA 写到内存capture 节点用 vb2 管理 buffer用户态VIDIOC_DQBUF拿到帧。驱动代码里dev.c的rkisp_probe会做几件事申请rkisp的寄存器基地址、使能aclk/hclk/sclk等时钟、复位 ISP、申请中断、调用rkisp_register_platform_subdevs注册子设备、最后rkisp_create_media_dev建立 media graph。如果 probe 失败dmesg里通常能看到failed to get xxx clock或failed to request irq这就是你排查的起点。2.3 编译进内核并确认节点出现假设你已经拿到 Rockchip 内核源码交叉编译工具链就绪操作步骤如下。第一步确认配置# 进入内核源码目录 cd ~/rk3588/kernel # 检查 rkisp 配置是否开启 grep -E ROCKCHIP_ISP|VIDEO_ROCKCHIP .config如果输出里没有CONFIG_VIDEO_ROCKCHIP_ISPy或m需要手动开make ARCHarm64 menuconfig # 路径Device Drivers → Multimedia support → Rockchip ISP # 选中 Rockchip ISP1 Driver第二步编译make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- -j$(nproc) Image make ARCHarm64 CROSS_COMPILEaarch64-linux-gnu- dtbs第三步烧录后确认驱动加载# 查看内核日志里 rkisp 的 probe 信息 dmesg | grep -i rkisp # 查看 media 设备 ls /dev/media* # 用 media-ctl 打印 pipeline media-ctl -d /dev/media0 -pmedia-ctl -p的输出会列出所有 entity 和 pad 连接。如果 sensor、csi2、rkisp 都在且 link 是ENABLED说明驱动层 pipeline 已经通了。如果某个 entity 缺失回到dts里检查对应节点是否status okay。提示不同内核版本 rkisp 目录名可能略有差异5.10 常见为isp/6.1 可能拆成isp1/和isp2/以实际源码为准。3. 把 rkisp 跑起来dts 配置、media pipeline 与出图验证3.1 dts 里 rkisp 节点怎么写才不翻车rkisp 驱动能不能 probe七成看 dts。以 RK3588 为例rkisp节点通常在arch/arm64/boot/dts/rockchip/rk3588s.dtsi里定义板级 dts 里要覆盖status和ports。关键点rkisp0 { status okay; }; mipi_dcphy0 { status okay; }; csi2_dcphy0 { status okay; ports { #address-cells 1; #size-cells 0; port0 { reg 0; #address-cells 1; #size-cells 0; csi_dcphy0_in: endpoint0 { reg 0; remote-endpoint sensor_out; >media-ctl -d /dev/media0 -p | grep -i sensor假设输出里 sensor entity 是m00_b_ov13850 1-0036接下来设置格式# 设置 sensor 输出格式 media-ctl -d /dev/media0 \ --set-v4l2 m00_b_ov13850 1-0036:0[fmt:SBGGR10_1X10/2112x1568] # 设置 rkisp 输入格式 media-ctl -d /dev/media0 \ --set-v4l2 rkisp-isp-subdev:0[fmt:SBGGR10_1X10/2112x1568] # 设置 rkisp 输出格式 media-ctl -d /dev/media0 \ --set-v4l2 rkisp-isp-subdev:2[fmt:YUYV8_2X8/2112x1568]第二步找到 capture video 节点ls /dev/video* v4l2-ctl --list-devices通常 rkisp 会注册多个 video 节点比如rkisp_mainpath、rkisp_selfpath。选 mainpath 对应的节点比如/dev/video0。第三步抓帧# 设置格式 v4l2-ctl -d /dev/video0 \ --set-fmt-videowidth2112,height1568,pixelformatYUYV # 抓 10 帧存成文件 v4l2-ctl -d /dev/video0 \ --stream-mmap4 \ --stream-count10 \ --stream-toframe.raw如果frame.raw大小等于2112*1568*2*10说明帧确实出来了。用ffmpeg或raw2rgb转一下就能看图像。如果stream-to卡住不动先看dmesg有没有rkisp的 timeout 或vb2报错。3.3 参数怎么改分辨率、格式与 buffer 数量rkisp 驱动里分辨率不是随便设的它受 sensor 输出能力和 ISP 内部限制约束。常见做法是sensor 端设一个它支持的模式比如2112x156830fpsrkisp 输入 pad 格式必须和 sensor 输出一致rkisp 输出 pad 可以缩放但缩放比例有限制一般不超过 8 倍。buffer 数量通过--stream-mmap4指定4 表示 4 个 buffer 轮转。太少会丢帧太多占内存。调试阶段用 4 比较稳。如果你要改驱动里的默认行为比如默认输出格式可以看capture.c里rkisp_video_set_fmt函数它决定了用户态没设格式时用什么。但一般不建议改驱动默认值优先在用户态用v4l2-ctl或应用层设置。注意media-ctl设置格式时sensor 的 format code 必须和驱动里sensor-fmt.code匹配写错会返回Invalid argument。4. rkisp 驱动调试避坑五个血泪现场4.1 probe 失败dmesg 只报 clock 错误现象dmesg | grep rkisp显示failed to get aclk或failed to get hclk。原因dts 里 rkisp 节点的clocks和clock-names不匹配或者时钟控制器节点没使能。解决对照rk3588s.dtsi里 rkisp 的clocks定义确认板级 dts 没有覆盖错。常见的是clock-names里少了sclk或者assigned-clocks没配。4.2 media pipeline 建不起来entity 缺失现象media-ctl -p只看到 rkisp看不到 sensor 或 csi2。原因sensor 驱动没 probe或者 csi2 节点status不是okay或者remote-endpoint写错。解决先dmesg | grep -i sensor确认 sensor 是否 probe再检查 csi2 的ports里 endpoint 是否和 sensor 的 endpoint 成对最后确认># 找到 stats 节点 v4l2-ctl --list-devices | grep -A2 rkisp # 假设 stats 节点是 /dev/video1 v4l2-ctl -d /dev/video1 --stream-mmap1 --stream-count1 --stream-tostats.binstats.bin里就是 ISP 硬件统计结果格式由rkisp_stat结构体定义在stats.c里能看到具体字段。如果你要自己解析可以对照include/uapi/linux/rkisp1-config.h里的定义。另一个进阶技巧是直接读寄存器。rkisp 的寄存器基地址在 dts 里probe 后可以通过devm_ioremap映射。调试时可以在hw.c里加dev_dbg打印关键寄存器值比如RKISP_ISP_CTRL、RKISP_ISP_INT_EN确认 pipeline 是否真的使能。但注意改驱动加打印要重新编译内核比较耗时优先用devmem在用户态读# 假设 rkisp 寄存器基地址是 0xfdcc0000 devmem 0xfdcc0000 32不过devmem读之前要确认时钟已使能否则读出来全是 0 或总线报错。我自己的习惯是每次改完 dts 或驱动先dmesg | grep -i rkisp看 probe 有没有报错再用media-ctl -p确认 pipeline最后v4l2-ctl --stream-mmap抓一帧。这三步走完基本能定位八成问题。从那以后我每次 bring-up 新板子都强制走一遍这个流程省得后面调图像时才发现底层就没通。希望帮到你。本文还有配套的精品资源点击获取