文章目录
- 1、环境介绍
- [2、RK3576 VI](#2、RK3576 VI)
-
- [2.1、Video Input Interface](#2.1、Video Input Interface)
-
- [2.1.1、MIPI CSI-2 接口](#2.1.1、MIPI CSI-2 接口)
- [2.1.2、DVP 并口输入能力](#2.1.2、DVP 并口输入能力)
- [2.2、VI 框图](#2.2、VI 框图)
- [2.3、AIQ 工作模式](#2.3、AIQ 工作模式)
- 3、原理图查看
- 4、内核配置
- 5、设备树配置
- 6、测试
- 7、遇到的问题
- 8、参考文章
- 9、总结
1、环境介绍
硬件:RK3576 板卡、OV5648 模组
软件:RK3576 原厂 SDK(buildroot 系统)
2、RK3576 VI
RK3576 ISP 属于 RK ISP v3.9 版本。RK3576 VI 作为视频输入模块总称,其中包含:
- 接口以及数据采集部分:DPHY、DVP、CSI、VICAP
- 图像处理部分:ISP、VPSS
2.1、Video Input Interface
2.1.1、MIPI CSI-2 接口
RK3576 支持 3 组 MIPI CSI-2 输入接口,其中包括 2 组 D-PHY 接口 和 1 组 C/D-PHY 接口。
RK3576 的 MIPI CSI-2 输入能力如下:
plain
2 组 4-lane D-PHY v1.2 接口
1 组 4-lane D-PHY v2.0 / 3-trio C-PHY v1.1 接口
其中:
plain
D-PHY v1.2:用于普通 MIPI CSI-2 摄像头输入
C/D-PHY:可配置为 D-PHY 或 C-PHY 模式
两组普通 D-PHY 接口均支持拆分模式:
plain
每组 4-lane D-PHY 可配置为 2 个 2-lane port
因此从接口形态上看,RK3576 可支持:
plain
2 组 4-lane D-PHY
或者
4 组 2-lane D-PHY + 1 组 C/D-PHY
也就是说,理论上最多可形成:
plain
4 路 2-lane MIPI CSI + 1 路 C/D-PHY MIPI CSI
2.1.2、DVP 并口输入能力
plain
支持 8 / 10 / 12 / 16-bit 数据宽度
最高 I/O 频率 150MHz
支持 BT.601 / BT.656 / BT.1120 视频输入接口
支持 pixel_clk / hsync / vsync 极性配置
支持 BT.656 / BT.1120 的 2/4 mux byte interleave 格式
支持 BT.656 / BT.1120 双边沿采样
2.2、VI 框图

2.3、AIQ 工作模式
ISP39 包括硬件算法实现及软件逻辑控制部分,RkAiq 即为软件逻辑控制部分的实现。
RkAiq 软件模块主要实现的功能为:从 ISP 驱动获取图像统计,结合 IQ Tuning 参数,使用一系列算法计算出新的ISP、Sensor 等硬件参数,不断迭代该过程,最终达到最优的图像效果。
ISP 硬件 pipeline 目前可工作在如下三种模式下:
- CIS -> VICAP -> ISP
- 该模式 Sensor Raw 数据经 VICAP 采集后直通到 ISP,未经过 DDR 中转。应用于单摄情况,该方式为最省内存、带宽方式。
- CIS -> VICAP -> DDR -> ISP
- 该模式 Sensor Raw 数据经 VICAP 采集后先存放在 DDR,ISP 再从 DDR 读取 Raw 数据进行处理。应用于多摄、超分辨率或者应用需要先处理 Raw 的情况。
- DDR->ISP
- 该模式 Raw 数据不直接从 Sensor 来,可来源于文件系统或其他方式。将 Raw 数据放入 DDR 后,ISP 再从 DDR 读取 Raw 进行处理。该方式未实际接 Sensor,所以不需要控制 Sensor 曝光。
3、原理图查看

从原理可得:
- Sensor 时钟由 RK3576 提供,引脚 GPIO4_A1_d(CLK_MIPI_CAMERAOUT_M2)
- i2c 接口:i2c4_m3
- PWDN 脚:GPIO3_D4_d
- RESET 脚:GPIO3_D6_d
- LED 补光灯 EN 脚:GPIO3_D2_d
4、内核配置
OV5648 模组集成了一个 DW9714 对焦芯片,需要开启驱动。
plain
CONFIG_VIDEO_OV5648=y
CONFIG_VIDEO_DW9714=y
5、设备树配置
设备树使用主设备树加模块设备树的形式,在主设备树中引入摄像头设备树:

plain
rk3576-xfboard-dphy3-ov5648.dtsi
c
/* dphy3 */
/* RST GPIO3_D6_d */
/* PWDN GPIO3_D4_d */
/* PWREN GPIO3_C6_d */
/* LED_PWREN GPIO3_D2_d */
&{/} {
ov5648_avdd: ov5648-avdd-regulator {
compatible = "regulator-fixed";
gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&ov5648_pwr>;
regulator-name = "ov5648_avdd";
enable-active-high;
};
ov5648_led_reg: ov5648-led-en {
compatible = "regulator-fixed";
gpio = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&ov5648_led_pwr>;
regulator-name = "ov5648_led_en";
enable-active-high;
regulator-boot-on;
regulator-always-on;
};
};
&i2c4 {
status = "okay";
pinctrl-0 = <&i2c4m3_xfer>;
dw9714: dw9714-0@c {
status = "okay";
compatible = "dongwoon,dw9714";
reg = <0xc>;
avdd-supply = <&ov5648_avdd>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,vcm-max-current = <120>;
rockchip,vcm-start-current = <10>;
rockchip,vcm-rated-current = <85>;
rockchip,vcm-step-mode = <9>;
};
ov5648: ov5648-0@36 {
compatible = "ovti,ov5648";
status = "okay";
reg = <0x36>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M2>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&cam_clk2m0_clk2
&ov5648_pwdn
&ov5648_rst>;
reset-gpios = <&gpio3 RK_PD6 GPIO_ACTIVE_LOW>;
pwdn-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
avdd-supply = <&ov5648_avdd>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "THDS11073";
rockchip,camera-module-lens-name = "Largan-40122a1";
lens-focus = <&dw9714>;
port {
/* MIPI CSI-2 bus endpoint */
ov5648_dphy3_out: endpoint {
remote-endpoint = <&dphy3_in_ov5648>;
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
};
};
/* sensor --> csi2_dphy3 --> mipi3_csi2 --> rkcif_mipi_lvds3 */
/* rkcif_mipi_lvds3_sditf --> rkisp_vir2 */
&csi2_dphy3 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
dphy3_in_ov5648: endpoint@1 {
reg = <1>;
remote-endpoint = <&ov5648_dphy3_out>;
data-lanes = <1 2>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy3_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi3_csi2_input>;
};
};
};
};
&mipi3_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi3_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidphy3_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi3_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi_in3>;
};
};
};
};
&rkcif_mipi_lvds3 {
status = "okay";
port {
cif_mipi_in3: endpoint {
remote-endpoint = <&mipi3_csi2_output>;
};
};
};
&rkcif_mipi_lvds3_sditf {
status = "okay";
port {
mipi3_lvds_sditf: endpoint {
remote-endpoint = <&isp_vir2>;
};
};
};
&rkisp_vir2 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir2: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi3_lvds_sditf>;
};
};
};
&rkcif {
status = "okay";
};
&rkcif_mmu {
status = "okay";
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkvpss {
status = "okay";
};
&rkvpss_mmu {
status = "okay";
};
&rkvpss_vir3 {
status = "okay";
};
&pinctrl {
ov5648 {
ov5648_led_pwr: ov5648-led-en {
rockchip,pins =
/* led power en */
<3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
};
ov5648_pwr: ov5648-pwr {
rockchip,pins =
/* camera power en */
<3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
};
ov5648_rst: ov5648-rst {
rockchip,pins =
/* camera reset */
<3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
};
ov5648_pwdn: ov5648-pwdn {
rockchip,pins =
/* camera power down */
<3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
};
6、测试
详细的抓图测试可以参考:摄像头应用编程(一):使用v4l2-ctl、media-ctl采集摄像头数据-CSDN博客
本次抓图的节点为 video11、video12:

以 video12 为例,抓图命令:
c
v4l2-ctl --verbose -d /dev/video12 --set-fmt-video=width=640,height=480,pixelformat=NV21 --stream-mmap=4 --stream-skip=3 --stream-count=1 --stream-to=./video12.yuv --stream-poll
c
root@rk3576-buildroot:/# v4l2-ctl --verbose -d /dev/video12 --set-fmt-video=width=640,height=480,pixelformat=NV21 --stream-mmap=4 --stream-ski p=3 --stream-count=1 --stream-to=./video12.yuv --stream-poll
VIDIOC_QUERYCAP: ok
VIDIOC_G_FMT: ok
VIDIOC_S_FMT: ok
Format Video Capture Multiplanar:
Width/Height : 640/480
Pixel Format : 'NV21' (Y/VU 4:2:0)
Field : None
Number of planes : 1
Flags :
Colorspace : Default
Transfer Function : Default
YCbCr/HSV Encoding: Default
Quantization : Full Range
Plane 0 :
Bytes per Line : 640
Size Image : 460800
VIDIOC_REQBUFS returned 0 (Success)
VIDIOC_CREATE_BUFS returned 0 (Success)
VIDIOC_QUERYBUF returned 0 (Success)
VIDIOC_QUERYBUF returned 0 (Success)
[ 1574.217263] rkisp_hw 27c00000.isp: set isp clk = 396000000Hz
VIDIOC_QUERYBUF returned 0 (Success)
VIDIOC_QUERYBUF returned 0 (Success)
VIDIOC_G_FMT returned 0 (Success)
VIDIOC_QBUF returned 0 (Success)
VIDIOC_QBUF returned 0 (Success)
VIDIOC_QBUF returned 0 (Success)
VIDIOC_QBUF returned 0 (Success)
[ 1574.229970] rkcif-mipi-lvds3: stream[0] start streaming
[ 1574.231418] rockchip-mipi-csi2 mipi3-csi2: stream on, src_sd: 000000004cc53e5a, sd_name:rockchip-csi2-dphy3
[ 1574.232849] rockchip-mipi-csi2 mipi3-csi2: stream ON
[ 1574.234428] rockchip-csi2-dphy3: dphy4, data_rate_mbps 420
[ 1574.235861] rockchip-csi2-dphy csi2-dphy3: csi2_dphy_s_stream stream on:1, dphy4, ret 0
[ 1574.237292] ov5648 4-0036: ov5648_s_stream(878) enter!
[ 1574.238709] ov5648 4-0036: stream on!!!
[ 1574.259778] ov5648 4-0036: ov5648_set_ctrl Unhandled id:0x9f0905, val:0x400
VIDIOC_STREAMON returned 0 (Success)
cap dqbuf: 0 seq: 0 bytesused: 460800 ts: 1572.884470 field: Any (ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq: 1 bytesused: 460800 ts: 1572.951033 delta: 66.563 ms field: Any (ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq: 2 bytesused: 460800 ts: 1573.017541 delta: 66.508 ms field: Any (ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq: 3 bytesused: 460800 ts: 1573.084043 delta: 66.502 ms field: Any (ts-monotonic, ts-src-eof)
[ 1574.595782] rkcif-mipi-lvds3: stream[0] start stopping, total mode 0x2, cur 0x2
[ 1574.662471] rockchip-mipi-csi2 mipi3-csi2: stream off, src_sd: 000000004cc53e5a, sd_name:rockchip-csi2-dphy3
[ 1574.668727] rockchip-mipi-csi2 mipi3-csi2: stream OFF
[ 1574.674856] rockchip-csi2-dphy csi2-dphy3: csi2_dphy_s_stream_stop stream stop, dphy4
[ 1574.680976] rockchip-csi2-dphy csi2-dphy3: csi2_dphy_s_stream stream on:0, dphy4, ret 0
[ 1574.687120] ov5648 4-0036: ov5648_s_stream(878) enter!
[ 1574.693220] ov5648 4-0036: stream off!!!
[ 1574.699776] rkcif-mipi-lvds3: stream[0] stopping finished, dma_en 0x0
windows 下使用 yuv player.exe 查看,这是没有 iqfile 的效果:

7、遇到的问题
7.1、系统启动后,内核概率性崩溃
c
Starting irqbalance: OK
Starting system message bus: done
Failed to detect Wi-Fi/BT chip!
Starting bluetoothd: OK
Starting network: OK
Starting dhcpcd...
dhcpcd-10.1.0 starting
dev: loaded udev
no valid interfaces found
Starting chronyd: [ 11.704973] ov5648 4-0036: write reg(0x100 val:0x0)failed !
[ 11.706449] m00_b_ov5648 4-0036: could not set init registers
[ 11.709296] ------------[ cut here ]------------
[ 11.711001] WARNING: CPU: 4 PID: 601 at drivers/media/v4l2-core/v4l2-mc.c:475 pipeline_pm_power_one+0xfc/0x150
[ 11.712603] Modules linked in:
[ 11.714174] CPU: 4 PID: 601 Comm: rkaiq_3A_server Tainted: G W 6.1.118 #8
[ 11.715757] Hardware name: Rockchip RK3576 XFBoard (DT)
[ 11.717324] pstate: a0000005 (NzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 11.718886] pc : pipeline_pm_power_one+0xfc/0x150
[ 11.720445] lr : pipeline_pm_power.part.0+0x5c/0xf0
[ 11.721996] sp : ffffffc00d223ac0
[ 11.723546] x29: ffffffc00d223ac0 x28: 0000000000000004 x27: 0000000000000000
[ 11.725112] x26: 0000000000000000 x25: ffffff80c4b00958 x24: ffffffc00a7e4000
[ 11.726669] x23: ffffff80c4b00958 x22: 00000000ffffffff x21: 00000000ffffffff
[ 11.728230] x20: ffffff80c2116920 x19: 00000000ffffffff x18: 0000000000000000
[ 11.729761] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
[ 11.731299] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[ 11.732843] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffffc008d5788c
[ 11.734366] x8 : ffffff80c35f0588 x7 : 0000000000000000 x6 : ffffffc00a750520
[ 11.735875] x5 : 0000000000007002 x4 : ffffff80c5390128 x3 : 0000000000000004
[ 11.737386] x2 : 0000000000000002 x1 : 0000000000000002 x0 : ffffff80c2116920
[ 11.738901] Call trace:
[ 11.740415] pipeline_pm_power_one+0xfc/0x150
[ 11.741939] pipeline_pm_power.part.0+0x5c/0xf0
[ 11.743457] v4l2_pipeline_pm_use+0x58/0x90
[ 11.744979] v4l2_pipeline_pm_put+0x18/0x30
[ 11.746503] sditf_s_power+0x148/0x244
[ 11.748049] pipeline_pm_power_one+0x148/0x150
[ 11.749591] pipeline_pm_power.part.0+0x5c/0xf0
[ 11.751131] v4l2_pipeline_pm_use+0x58/0x90
[ 11.752673] v4l2_pipeline_pm_put+0x18/0x30
[ 11.754222] rkisp_stats_fop_release+0x4c/0x5c
[ 11.755753] v4l2_release+0xbc/0xf0
[ 11.757289] __fput+0x84/0x260
[ 11.758827] ____fput+0x14/0x1c
[ 11.760353] task_work_run+0xb8/0x170
[ 11.761875] do_notify_resume+0x450/0xde0
[ 11.763385] el0_svc+0x6c/0x80
[ 11.764908] el0t_64_sync_handler+0xb0/0xb4
[ 11.766420] el0t_64_sync+0x158/0x15c
codex 说这是 /usr/lib/udev/rules.d/60-persistent-v4l.rules udev 规则文件的问题。修改 60-persistent-v4l.rules,将 v4l_id 调用限制在 USB video 设备上,避免 udev 冷启动阶段打开 Rockchip ISP/CIF摄像头节点,导致 OV5648 pipeline 被提前上电/下电并触发 v4l2_pipeline_pm_use warning。修改后的规则文件如下:
c
# do not edit this file, it will be overwritten on update
ACTION=="remove", GOTO="persistent_v4l_end"
SUBSYSTEM!="video4linux", GOTO="persistent_v4l_end"
ENV{MAJOR}=="", GOTO="persistent_v4l_end"
# Only run v4l_id for USB cameras. Opening Rockchip ISP/CIF video nodes
# during udev coldplug may power-cycle the camera pipeline before userspace
# is ready and can trigger v4l2_pipeline_pm_use warnings.
SUBSYSTEMS=="usb", IMPORT{program}="v4l_id $devnode"
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
SUBSYSTEMS=="usb", KERNEL=="video*", ENV{ID_SERIAL}=="?*", SYMLINK+="v4l/by-id/$env{ID_BUS}-$env{ID_SERIAL}-video-index$attr{index}"
# check for valid "index" number
TEST!="index", GOTO="persistent_v4l_end"
ATTR{index}!="?*", GOTO="persistent_v4l_end"
IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", KERNEL=="video*|vbi*", SYMLINK+="v4l/by-path/$env{ID_PATH}-video-index$attr{index}"
ENV{ID_PATH}=="?*", KERNEL=="audio*", SYMLINK+="v4l/by-path/$env{ID_PATH}-audio-index$attr{index}"
LABEL="persistent_v4l_end"
8、参考文章
无。
9、总结
无。