rk3399调试ov2659(camera模块@dvp接口)–移植过程

rk3399调试ov2659(camera模块@dvp接口)–移植过程刚接手某款硬件,嵌入式开发者往往对硬件熟悉,而对实现硬件行为的软件及其软件框架不太熟。所以,我们一般从硬件拓扑图入手,分析数据流和硬件动作过程来熟悉或编写软件框架,并向该框架填充一些逻辑/业务代码来实现最终的驱动代码。

大家好,又见面了,我是你们的朋友全栈君。

版权声明:本文为博主原创文章,转载请注明出处:https://blog.csdn.net/huang_165/article/details/86130288

参考博客:
RGB 与YUY格式简介:https://blog.csdn.net/u010657219/article/details/41008767、 https://blog.csdn.net/yuyangyg/article/details/62038162
MIPI接口和DVP接口:https://blog.csdn.net/qq_24546137/article/details/80918675
camera模组CMM介绍:https://blog.csdn.net/xubin341719/article/details/7723725

建议读者先对图像格式、图传接口有所了解。
实现目标:
      摄像头采集到的实时数据、摄像头以NV21格式输出到ISP的SP通道并存放在内存中(抓图操作)


硬件性能–先从芯片手册获取一些信息:
1).ov2659硬件性能
1.自动3A、可编程的输出帧率及分辨率、支持输出raw rgb、rgb565/555、yuv
2.标准sccb接口(iic控制口)
3.有效感光阵列的大小:1632×1212=197 7984(两百万像素)
5.镜头的大小:1/5寸
6.像素点颗粒的大小: 1.75um * 1.75um,镜头越小其颗粒越小那么摄像头感光性越差。
7.最大的图像传输速率:注意了,图传速率只是表征摄像头输出数据能力而言。
UXGA(1600×1200):15fps
SVGA(800×600):30fps
720p(1280×720):30fps    //p是指连续扫描,与它相对应的是I:隔行扫描
1336×768(1336×768):24fps

2). 内部数据的处理流程
摄像头内部框架图:

rk3399调试ov2659(camera模块@dvp接口)--移植过程
   image sensor core部分:
翻转、增益大小调整、黑电平校准、饱和度的控制。
    image sensor process部分:
提供测试功能、镜头补偿功能、自动白平衡、RAW RGB->RGB、RGB->YUV、窗口功能、缩小放大功能
    image output interface部分:
RAW RGB/YUV、VGA/QVGA、BT601/BT656

      刚接手某款硬件,嵌入式开发者往往对硬件熟悉,而对实现硬件行为的软件及其软件框架不太熟。
所以,我们一般从硬件拓扑图入手,分析数据流和硬件动作过程来熟悉或编写软件框架,并向该框架填充一些逻辑/业务代码来实现最终的驱动代码。
整个数据采集流程拓扑图:

rk3399调试ov2659(camera模块@dvp接口)--移植过程

抓图涉及:
1.摄像头的初始化(输出格式、分辨率、输出速率)
2.使能摄像头接入主控板卡中的物理通道(mipi、cif也就是dvp;摄像头的dvp口传输协议和lcd ttl口协议差不多。)
3.使能主控板卡中的ISP(图像信号处理模块)、并让ISP知道当前有效接入的摄像头是哪一个(因为可以多个接入,但只能一个有效)。
4.告诉ISP输进来的数据如何处理(颜色空间转换、缩放、裁剪、旋转等)、经由那个通道输出到内存/显存(MP主通道、SP自身通道)。SP一般用来预览图片,SP图片的最大分辨率比MP低。
5.输出到内存

 

配置设备树:

1.摄像头

camera4: camera-module@30 {
		status = "okay";
		compatible = "omnivision,ov2659-v4l2-i2c-subdev";
		reg = < 0x30 >;
		device_type = "v4l2-i2c-subdev";
		clocks = <&cru SCLK_CIF_OUT>;
		clock-names = "clk_cif_out";
		pinctrl-names = "rockchip,camera_default",
		"rockchip,camera_sleep";
		pinctrl-0 = <&isp_dvp_d0d7>;
		pinctrl-1 = <&cif_clkout>;
		rockchip,pd-gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
		rockchip,rst-gpio = <&gpio2 RK_PD4 GPIO_ACTIVE_LOW>;
		rockchip,camera-module-mclk-name = "clk_cif_out";
		rockchip,camera-module-facing = "back";
		rockchip,camera-module-name = "cmk-cb0695-fv1";
		rockchip,camera-module-len-name = "lg9569a2";
		rockchip,camera-module-fov-h = "133.0";
		rockchip,camera-module-fov-v = "100.1";
		rockchip,camera-module-orientation = <0>;
		rockchip,camera-module-iq-flip = <0>;
		rockchip,camera-module-iq-mirror = <0>;
		rockchip,camera-module-flip = <0>;
		rockchip,camera-module-mirror = <0>;
		rockchip,camera-module-defrect0 = <1280 720 0 0 1280 720>;
		rockchip,camera-module-defrect1 = <1280 720 0 0 1280 720>;
		rockchip,camera-module-defrect2 = <1280 720 0 0 1280 720>;
		rockchip,camera-module-defrect3 = <1280 720 0 0 1280 720>;
		rockchip,camera-module-flash-support = <0>;
	}

2.ISP

#ISP 接口bind摄像头
&cif_isp1 {
	rockchip,camera-modules-attached = <&camera4>;
	status = "okay";
};
#ISP接口
cif_isp1: cif_isp@ff920000 {
	compatible = "rockchip,rk3399-cif-isp";
	rockchip,grf = <&grf>;
	reg = <0x0 0xff920000 0x0 0x4000>, <0x0 0xff968000 0x0 0x8000>;
	reg-names = "register", "dsihost-register";
	clocks =
		<&cru ACLK_ISP1_NOC>, <&cru ACLK_ISP1_WRAPPER>,
		<&cru HCLK_ISP1_NOC>, <&cru HCLK_ISP1_WRAPPER>,
		<&cru SCLK_ISP1>, <&cru PCLK_ISP1_WRAPPER>,
		<&cru SCLK_DPHY_TX1RX1_CFG>,
		<&cru PCLK_MIPI_DSI1>, <&cru SCLK_MIPIDPHY_CFG>,
		<&cru SCLK_CIF_OUT>, <&cru SCLK_CIF_OUT>,
		<&cru SCLK_MIPIDPHY_REF>;
	clock-names =
		"aclk_isp1_noc", "aclk_isp1_wrapper",
		"hclk_isp1_noc", "hclk_isp1_wrapper",
		"clk_isp1", "pclkin_isp1",
		"pclk_dphytxrx",
		"pclk_mipi_dsi","mipi_dphy_cfg",
		"clk_cif_out", "clk_cif_pll",
		"pclk_dphy_ref";
	interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
	interrupt-names = "cif_isp10_irq";
	power-domains = <&power RK3399_PD_ISP1>;
	rockchip,isp,iommu-enable = <1>;
	iommus = <&isp1_mmu>;
	status = "okay";
};

3.记得打开iommu

(当内核没有大块连续内存时,isp的iommu将会把内存碎片整理好并建立一个页表,那么驱动访问这页表就可以访问连续空间。)

&isp1_mmu {
	status = "okay";
};

     我打算用v4l-utils工具包中的:v4l2-ctl实现抓图。
     V4l2-ctl 工具则是针对/dev/video0,/dev/video1 等 video设备,它在 video 设备上进行 set_fmt,reqbuf(申请buf),qbuf(送buf回队列),dqbuf(从队列取出buf),stream_on,stream_off 等一系列操作。
n为4的倍数(0,1,2,3…)
/dev/videon+0:视频输出 SP主通道
/dev/videon+1:视频输出 MP自身通道
/dev/videon+2:3A统计
/dev/videon+3:3A参数设置

设置 fmt 并抓帧:

板端:

v4l2-ctl -d /dev/video0 --set-selection=target=crop,width=1920,height=1080 --set-fmt-video=width=1280,height=720,pixelformat=NV21 \
--stream-mmap=3 --stream-to=mp.out --stream-count=1 --stream-poll

参数的说明:
    -d,指定操作对象为/dev/video0 设备。
    –set-selection=target=crop 设置裁剪功能,width=1920,height=1080 裁剪后的大小1920×1080
    –set-fmt-video,指定了宽高及 pxielformat。NV12,即用 FourCC 表示的 pixelformat。FourCC 编码详见下文 FourCC。
    –stream-mmap,指定 buffer 的类型为 mmap,即由 kernel 分配的物理连续的或经过iommu 映射的 buffer。
    –stream-to,指定帧数据保存的文件路径
    –stream-count,指定抓取的帧数, 不包括–stream-skip 丢弃的数量
    –stream-poll,该选项指示 v4l2-ctl 采用异步 IO,即在 dqbuf 前先用 select 等等帧数据完成,从而保证 dqbuf 不阻塞。否则 dqbuf 将会阻塞直到有数据帧到来。

那么我们将mp.out推到ubantu上用mplayer打开它。
ubantu端:
W=1280; H=720; mplayer mp.out -loop 0 -demuxer rawvideo -fps 25 -rawvideo w=${W}:h=${H}:size=$((${W}*${H}*3/2)):format=nv21
    注意了抓图操作的pixelformat和mplayer播放的format需要一致。
当然了,前提是摄像头驱动和摄像头本身要支持nv12,分辨率也同理。

FourCC:全称 Four Character Codes,它用 4 个字符(即 32bit)来命名图像格式。
以下列出本文中常用到的几个格式。更详细的定义请参阅 kernel 代码之 videodev2.h。
FourCC图:

rk3399调试ov2659(camera模块@dvp接口)--移植过程

调试摄像头注意点:
A:上电流程:
摄像头根据采用内/外部DVDD、上电时刻iic是否有效来分出四种上电时序。
1.内部DVDD+iic还无效。
2.内部DVDD+iic有效。
3.外部DVDD+iic还无效。
4.外部DVDD+iic有效。
这是第4种情况
外部DVDD和iic有效图:

rk3399调试ov2659(camera模块@dvp接口)--移植过程

B:操作流程
摄像头端的:
1.上电时序、供合适工作时钟(一般24MHZ)
2.复位信号时序
3.ISP设置传输图像数据时序(在这里是DVP时序)
4.摄像头、ISP设置图传的分辨率、速率、格式

做1,2两步通过iic就能把摄像头的ID读出来。
做3,4两步就能从DVP读出图像数据

主板摄像头接口端(ISP)的:主要配置板卡的dts
参考上面的“抓图涉及”一节


附录:

试验的mp.out

成功启动log:

[    0.879203] ov2659.ov2659_check_camera_id: successfully detected camera ID 0x2656
[    0.879919] cif_isp10_pltfrm_get_img_src_device: ov2659 attach to cif isp10 img_src_array[0]
[    0.881313] cif_isp10_v4l2_register_video_device: video device video-1.0 (rkisp10_selfpath) successfully registered
[    0.882480] video4linux video1: successfully registered video device for cifisp(video1)
[    0.883705] cif_isp10_v4l2_register_video_device: video device video-1.2 (rkisp10_mainpath) successfully registered
[    0.884893] cif_isp10_v4l2_register_video_device: video device video-1.3 (rkisp10_dmapath) successfully registered

打开v4l2中的ioctl调用开关:

echo 0x1f > /sys/class/video4linux/video0/dev_debug
echo 0x1f > /sys/class/video4linux/video1/dev_debug
echo 0x1f > /sys/class/video4linux/video2/dev_debug
echo 0x1f > /sys/class/video4linux/video3/dev_debug

ov2659支持:

# v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUYV 4:2:2

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUYV 4:2:2

        Index       : 2
        Type        : Video Capture
        Pixel Format: 'UYVY'
        Name        : UYVY 4:2:2

        Index       : 3
        Type        : Video Capture
        Pixel Format: '422P'
        Name        : Planar YVU 4:2:2

        Index       : 4
        Type        : Video Capture
        Pixel Format: 'NV16'
        Name        : Y/CbCr 4:2:2

        Index       : 5
        Type        : Video Capture
        Pixel Format: 'YU12'
        Name        : Planar YUV 4:2:0

        Index       : 6
        Type        : Video Capture
        Pixel Format: 'YU12'
        Name        : Planar YUV 4:2:0

        Index       : 7
        Type        : Video Capture
        Pixel Format: 'YV12'
        Name        : Planar YVU 4:2:0

        Index       : 8
        Type        : Video Capture
        Pixel Format: 'NV12'
        Name        : Y/CbCr 4:2:0

        Index       : 9
        Type        : Video Capture
        Pixel Format: 'NV21'
        Name        : Y/CrCb 4:2:0

        Index       : 10
        Type        : Video Capture
        Pixel Format: 'GREY'
        Name        : 8-bit Greyscale

        Index       : 11
        Type        : Video Capture
        Pixel Format: 'Y444'
        Name        : 16-bit A/XYUV 4-4-4-4

        Index       : 12
        Type        : Video Capture
        Pixel Format: 'NV24'
        Name        : Y/CbCr 4:4:4

        Index       : 13
        Type        : Video Capture
        Pixel Format: 'JPEG' (compressed)
        Name        : JFIF JPEG

        Index       : 14
        Type        : Video Capture
        Pixel Format: 'RGBP'
        Name        : 16-bit RGB 5-6-5

        Index       : 15
        Type        : Video Capture
        Pixel Format: 'GRBG'
        Name        : 8-bit Bayer GRGR/BGBG

[ 2816.016913] v4l2_enum_fmt_cap(1545) ERR: index 16
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132474.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • Java代码实体类生成SQL语句(Java实体类转数据库)

    Java代码实体类生成SQL语句(Java实体类转数据库)有的时候把数据库删了,如果照着实体类重新创建数据库的话比较麻烦,可以使用这个工具,把代码复制到项目里面设置一下即可把Java代码中的实体类转换为SQL语句输出为一个文件,打开执行命令即可。代码如下:packageMain;importjavax.xml.bind.annotation.XmlElement;importjava.io.*;importjava.lang.annotation.Annotation;importjava.lang.reflect.Field;p.

    2022年5月6日
  • Alex 的 Hadoop 菜鸟教程: 第10课 Hive 安装和使用教程

    Alex 的 Hadoop 菜鸟教程: 第10课 Hive 安装和使用教程Hive提供了一个让大家可以使用sql去查询数据的途径。让大家可以在hadoop上写sql语句。但是最好不要拿Hive进行实时的查询。因为Hive的实现原理是把sql语句转化为多个MapReduce任务所以Hive非常慢,官方文档说Hive适用于高延时性的场景而且很费资源。

    2022年6月7日
  • 复制粘贴不到远程桌面_远程桌面无法复制到本地

    复制粘贴不到远程桌面_远程桌面无法复制到本地在远程服务器上打开任务管理器,在进程里面找到rdpclip进程(或者剪贴板监视器),点击“结束进程”打卡DOS命令符,输入rdpclip后,确认,从新打开远程剪贴服务。

    2022年8月19日
  • MySql必知必会实战练习(一)表创建和数据添加

    1.实战环境windows1064位mysql-8.0.13mysql编辑和查看工具:NaviCatforMySql表脚本文件:###########################

    2021年12月29日
  • c++ string类头文件_printf用什么头文件

    c++ string类头文件_printf用什么头文件1.string与cstring有什么区别是C++标准库头文件,包含了拟容器classstd::string的声明(不过classstring事实上只是basic_string的typedef),用于字符串操作。是C标准库头文件<string.h>的C++标准库版本,包含了C风格字符串(NUL即’\0’结尾字符串)相关的一些类型和函数的声明,例如strcmp、strchr、strstr等。和<string.h>的最大区别在于,其中声明的名称都是位于std命名空间中的,而不是后

    2022年9月12日
  • 如何制作SWD接口接线,并使用keil4_Jlink烧录芯片

    如何制作SWD接口接线,并使用keil4_Jlink烧录芯片如何制作SWD接口接线,并使用keil4_Jlink烧录芯片。背景过程背景刚到一个新公司的第一个礼拜。通过web界面更新app总是导致bios失效。又因为是接手一个离职人的项目,调试线已经找不到,所以需要自己做一个。由于自己是个菜鸡,所以做出来的东西也是比较难看,由此记录一下,希望下次能做的美观一点。过程现在说一个我做上面一个东西需要查找那些东西。首先知道SWD需要Jlink的脚是GND(地线)、TMS(数据线)、TCK(时钟线)、NSRST(重启线)。所以得得将jlink这几个角引出来。这

    2022年4月25日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号