os08a20是一款支持mipi接口的摄像头sensor芯片,可以通过i2c总线挂载到3588的开发板上,通过mipi信号线向3588传输RAW格式的视频流,本文采用了一款以os08a20为核心设计的摄像头模组进行调试。
在firefly对应的3588开发板的资料下载页Firefly | 让科技更简单,让生活更智能下载Linux版本的SDK,并在我的电脑上的虚拟机内解压。在/proj/rk3588_sdk/kernel/drivers/media/i2c/的路径下可以找到一个名为os08a20.c的文件,这个就是rk3588为os08a20配置的驱动文件,同样地,在这个文件夹里可以找到的sensor芯片型号都是对rk3588兼容的。在os08a20.c文件的os08a20_probe函数(设备初始化和驱动注册)中保留对reset对应gpio口的配置,然后将文件里的其余关于reset的配置注释掉。
os08a20->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(os08a20->reset_gpio))
dev_warn(dev, "Failed to get reset-gpios, maybe no use\n");
接下来配置设备树文件,在/proj/rk3588_sdk/kernel/arch/arm64/boot/dts/rockchip/下有firefly配置好的设备树文件,他们对8ms1m摄像头模组一、产品介绍 — Firefly Wiki配置了设备树文件rk3588-firefly-itx-cam-8ms1m.dtsi,把这个文件复制一份改名为rk3588-firefly-itx-cam-os08a20.dtsi。在设备树文件中可以看到对i2c3节点的配置,因为os08a20的地址为0x36,所以作如下修改。
&i2c3 {
status = "okay";
os08a20: os08a20@36{
compatible = "ovti,os08a20";
reg = <0x36>;
clocks = <&cru CLK_MIPI_CAMARAOUT_M3>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&mipim0_camera3_clk>;
power-domains = <&power RK3588_PD_VI>;
reset-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>;
firefly,clkout-enabled-index = <0>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
port {
os08a20_out0: endpoint {
remote-endpoint = <&mipidphy0_in_ucam0>;
data-lanes = <1 2 3 4>;
};
};
};
};
由于8ms1m和os08a20不同之处在于8ms1m输出的是YUV格式,os08a20输出的是RAW格式,所以需要打开isp节点对图像数据进行处理。将以下节点的status都改为“okay”。
&rkcif {
status = "okay";
};
&rkcif_mipi_lvds2 {
status = "okay";
port {
cif_mipi2_in0: endpoint {
remote-endpoint = <&mipi2_csi2_output>;
};
};
};
&rkcif_mipi_lvds2_sditf {
status = "okay";
port {
mipi_lvds2_sditf: endpoint {
remote-endpoint = <&isp0_vir0>;
};
};
};
&rkcif_mmu {
status = "okay";
};
&rkisp0 {
status = "okay";
};
&isp0_mmu {
status = "okay";
};
&rkisp0_vir0 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp0_vir0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds2_sditf>;
};
};
};
将配置好的设备树文件放到设备树总文件里,当编译固件时,可以看到设备树总文件名为rk3588-firefly-itx-3588j-mipi101-M101014-BE45-A1.dtsi,在这个文件中加上#include "rk3588-firefly-itx-cam-os08a20.dtsi"。
最后,打开/proj/rk3588_sdk/kernel/arch/arm64/configs/路径下的rockchip_linux_defconfig文件,在里面搜索os08a20,把对os08a20的编译选项改为'y',放入内核里编译。
CONFIG_VIDEO_OS08A20=y
完成对os08a20的驱动配置之后,就可以编译固件并烧写到3588里去了,启动3588后,终端运行'i2cdetect -r -y 3',就可以在3节点36地址下看到挂载的os08a20了。
通过以下命令可以查看视频节点支持的视频格式
v4l2-ctl -d /dev/video0 --list-formats-ext
如果用v4l2命令可以根据得到的视频格式拉取原始视频流,但是由于未经过isp节点的处理,得到的图像并不是正常图像。
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10
--stream-mmap --stream-skip=1
需要找到os08a20对应的iqfile'os08a20_default_default.json',将它传到/etc/iqfiles/路径下,然后利用SDK中的ispdemo就可以拉取正常的视频流了。
rkisp_demo --device /dev/video11 --width 3840 --height 2160 --iqpath /etc/iqfiles
--rkaiq --stream-skip=10 --stream-count=50 --stream-to=os08a20.yuv
os08a20支持4K/30FPS和1K/120FPS,如果想要修改输出的分辨率和帧率,需要根据os08a20的数据手册修改驱动文件os08a20.c中寄存器的值,利用V4L2命令可以查看实时帧率。
v4l2-ctl --verbose -d /dev/video11 --set-fmt-video=width=1920,height=1080,pixe
lformat=NV12 --stream-mmap=3 --stream-skip=1
利用rkisp_demo可以将采集到的图像用HDMI输出到显示器上。
rkisp_demo --device /dev/video11 --width 1920 --height 1080 --iqpath /etc/iqfiles
--rkaiq --vop