当前位置: 首页 > news >正文

RK 安卓10/11平台 HDMI-IN 调试

这篇文章我们介绍一下在安卓9、10、11的版本上,rk平台的hdmi-in功能是如何实现的,下篇文章我们再介绍安卓12之后的版本有了什么变化。希望对在rk平台调试hdmi-in功能的朋友有一些帮助。

目录

(1)概述

(2)基本功能流程实现原理

1.系统功能框图

2.系统功能流程

2.1 APK工作流程

2.2 热拔插

2.3 切换分辨率

(3)功能配置说明

1.驱动代码与配置

1.1 驱动代码

1.2 config配置

2.DTS配置

2.1 设备配置

2.2 图像链路配置

2.2.1 RK3399

2.2.2 RK3568

3.camera xml注册设备

3.1 设备名称与ID

3.2 分辨率配置

3.3 SOC模式

3.4 旋转角配置

4.APK适配

4.1 获取APK

4.2 APK 源码适配

5.EDID配置

(4)调试方法

1.查看设备是否注册camera

2.查看拓扑结构

3.v4l2抓取数据流

4.v4l2抓图

5.不同芯片平台接收能力

6.配置使用ISP CMA内存

7.配置RK3399 ISP超频

(5)总结

(1)概述

安卓9/10/11等版本一般对应的都是rk比较旧的主控芯片,例如rk3399、rk3568/6等等,这里呢,我们又可以分为两类,一类是rk3399等较久的主控,一类是RK3566/8两个平台。rk3399之类的主控芯片没有VICAP的图像模块,都是通过ISP接收HDMI-IN的图像数据,RK3566/68的平台有VICAP(RKCIF)模块,也有RKISP模块,可以两种方式实现。

在RK的主控芯片中只有RK3588拥有独立的HDMIRX模块,其他主控芯片都没有HDMI-RX模块,想要实现HDMI-IN 的功能只能通过外挂转接芯片的方式实现。比较常用的转接芯片有RK628、LT6911系列等等,这篇文章我们就介绍一下这种方式的实现以及调试指南

(2)基本功能流程实现原理

1.系统功能框图

系统框图如下图所示,RK628D作为类camera设备使用,基于V4L2框架实现相关驱动,HDMI信号源通过RK628的HDMIRX接口输入,经过RK628的内部模块处理将接收的图像数据处理为MIPI-CSI信号作为数据输出,同时图像格式也统一转换为YUV422格式输出,经MIPI lane接入到主控的MIPI接口,由主控接收图像并对图像进行处理显示,从而实现HDMI-IN的功能。

2.系统功能流程

HDMI IN video 部分的软件实现方案是将 RK628 模拟成一个 MIPI SOC camera 设备,通过 camera 框架接 收video 数据并在 APK 进行显示,同时基于 HDMI IN 的应用场景需要,增加 HDMI IN 热拔插和 HDMI IN 分辨率自适应支持。
2.1 APK工作流程

APK预览工作流程如下图所示:

2.2 热拔插

热拔插中断处理流程如下图所示

2.3 切换分辨率

切换分辨率流程如下图所示:

(3)功能配置说明

1.驱动代码与配置

1.1 驱动代码

转接芯片驱动代码如下:

drivers/media/i2c/rk628/
drivers/media/i2c/lt6911uxe.c
drivers/media/i2c/lt6911uxc.c
drivers/media/i2c/tc35874x.c
1.2 config配置

kernel的config配置如下:

CONFIG_VIDEO_LT6911UXC=y
CONFIG_VIDEO_LT6911UXE=y
CONFIG_VIDEO_RK628_CSI=y
CONFIG_VIDEO_TC35874X=y

2.DTS配置

以下介绍调试的时候的dts配置。主要有设备配置,链路配置,链路配置中,由于rk3566/68平台有两种场景,因此,我们分别介绍两种场景的配置。

2.1 设备配置

转接芯片一般都是i2c设备,需要配置到i2c总线下,参考如下配置:

&i2c5 {status = "okay";rk628_csi: rk628_csi@50 {reg = <0x50>;compatible = "rockchip,rk628-csi-v4l2";status = "okay";power-domains = <&power RK3588_PD_VI>;pinctrl-names = "default";pinctrl-0 = <&rk628_pin>;interrupt-parent = <&gpio2>;interrupts = <RK_PC4 IRQ_TYPE_EDGE_RISING>;enable-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;plugin-det-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;continues-clk = <1>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "HDMI-MIPI";rockchip,camera-module-lens-name = "RK628-CSI";port {hdmiin_out0: endpoint {remote-endpoint = <&hdmi_mipi0_in>;data-lanes = <1 2 3 4>;};};};
};
  • interrupt-parent/ interrupts:连接RK628中断的GPIO引脚;

  • enable-gpios:RK628供电控制GPIO引脚(若为常供电可不配置);

  • reset-gpios:RK628复位控制GPIO引脚

  • rockchip,camera-module相关的都是适配RK的camera框架平台私有配置,与camera类似。

2.2 图像链路配置

这里具体RK3399以及RK3568为例,RK3399代表的是RK旧的平台,RK3568代表的是引入VICAP之后的平台,在RK3568之后的芯片平台也没有基于安卓11的版本,都是基于安卓12以后得版本,我们后续在做详细的介绍。

2.2.1 RK3399

RK339平台只能使用ISP接收图像,链路我们可以描述为:转接芯片-->dphy_rx0 -->isp

其中dts配置可以参考如下配置。需要注意的是rk3399有两个isp,配置对应的是哪一路即可。

&i2c4 {clock-frequency = <400000>;status = "okay";rk628_csi_v4l2: rk628_csi_v4l2@50 {reg = <0x50>;compatible = "rockchip,rk628-csi-v4l2";interrupt-parent = <&gpio2>;interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;//enable-gpios = <&gpio5 RK_PC3 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>;plugin-det-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;//power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "RK628-CSI";rockchip,camera-module-lens-name = "NC";port {hdmiin_out0: endpoint {remote-endpoint = <&mipi_in>;data-lanes = <1 2 3 4>;};};};
};&mipi_dphy_rx0 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;mipi_in: endpoint@1 {reg = <1>;remote-endpoint = <&hdmiin_out0>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;dphy_rx_out: endpoint@0 {reg = <0>;remote-endpoint = <&isp_mipi_in>;};};};
};&isp0 {status = "okay";port {#address-cells = <1>;#size-cells = <0>;isp_mipi_in: endpoint@0 {reg = <0>;remote-endpoint = <&dphy_rx_out>;};};
};&isp0_mmu {status = "okay";
};
2.2.2 RK3568

RK3568则有两种情况,一是使用isp接收,二是使用vicap模块接收图像,我们分别进行介绍。

rk3568使用isp的场景,对应的图像链路为:

对应的dts配置为:

&csi2_dphy_hw {status = "okay";
};&csi2_dphy0 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;mipi_in: endpoint@1 {reg = <1>;remote-endpoint = <&hdmiin_out0>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;csidphy_out: endpoint@0 {reg = <0>;remote-endpoint = <&isp0_in>;};};};
};&i2c4 {clock-frequency = <400000>;status = "okay";rk628_csi_v4l2: rk628_csi_v4l2@50 {reg = <0x50>;compatible = "rockchip,rk628-csi-v4l2";interrupt-parent = <&gpio2>;interrupts = <2 IRQ_TYPE_LEVEL_HIGH>;//enable-gpios = <&gpio5 RK_PC3 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio2 RK_PA3 GPIO_ACTIVE_LOW>;plugin-det-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_LOW>;//power-gpios = <&gpio0 17 GPIO_ACTIVE_HIGH>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "RK628-CSI";rockchip,camera-module-lens-name = "NC";port {hdmiin_out0: endpoint {remote-endpoint = <&mipi_in>;data-lanes = <1 2 3 4>;};};};
};&rkisp {status = "okay";
};&rkisp_mmu {status = "okay";
};&rkisp_vir0 {status = "okay";port {#address-cells = <1>;#size-cells = <0>;isp0_in: endpoint@0 {reg = <0>;remote-endpoint = <&csidphy_out>;};};
};

RK3568使用VICap的场景,图像链路为:

对应的dts配置参考为:

&csi2_dphy_hw {status = "okay";
};&csi2_dphy0 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;hdmi_to_mipi_in: endpoint@1 {reg = <1>;remote-endpoint = <&lt6911uxc_out>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;csidphy_out: endpoint@1 {reg = <1>;remote-endpoint = <&mipi_csi2_input>;data-lanes = <1 2 3 4>;};};};
};&i2c3 {status = "okay";lt6911uxc: lt6911uxc@2b {status = "okay";reg = <0x2b>;compatible = "lontium,lt6911uxc";clocks = <&ext_cam_clk>;clock-names = "xvclk";interrupt-parent = <&gpio4>;interrupts = <16 IRQ_TYPE_LEVEL_LOW>;power-gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;reset-gpios = <&gpio4 26 GPIO_ACTIVE_LOW>;plugin-det-gpios = <&gpio0 30 GPIO_ACTIVE_LOW>;hpd-ctl-gpios = <&gpio3 27 GPIO_ACTIVE_LOW>;rockchip,camera-module-index = <0>;rockchip,camera-module-facing = "back";rockchip,camera-module-name = "LT6911UXC";rockchip,camera-module-lens-name = "NC";port {lt6911uxc_out: endpoint {remote-endpoint = <&hdmi_to_mipi_in>;data-lanes = <1 2 3 4>;};};};
};&mipi_csi2 {status = "okay";ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;#address-cells = <1>;#size-cells = <0>;mipi_csi2_input: endpoint@1 {reg = <1>;remote-endpoint = <&csidphy_out>;data-lanes = <1 2 3 4>;};};port@1 {reg = <1>;#address-cells = <1>;#size-cells = <0>;mipi_csi2_output: endpoint@0 {reg = <0>;remote-endpoint = <&cif_mipi_in>;data-lanes = <1 2 3 4>;};};};
};&rkcif_mipi_lvds {status = "okay";port {cif_mipi_in: endpoint {remote-endpoint = <&mipi_csi2_output>;data-lanes = <1 2 3 4>;};};
};&rkcif_mmu {status = "okay";
};&rkcif {status = "okay";
};
3.camera xml注册设备

camera3_profiles.xml文件对应SDK目录下具体芯片平台的文件:

hardware/rockchip/camera/etc/camera/camera3_profiles_rk3xxx.xml

在设备上的路径为:

/vendor/etc/camera/camera3_profiles.xml

若是临时调试,可以采用adb替换文件的形式,但需要注意文件路径与文件名的正确性。

xml增加配置的时候可以参考其他已有的sensor,后续仅介绍关键的几个修改点。

3.1 设备名称与ID

xml中name参数与moduleid参数取决定着能否成功注册安卓camera设备,若该两项属性配置异常,则会导致

  • name:需要与驱动名称一致,有大小写区别;

  • moduleId:需要与驱动dts中配置的index一致;

3.2 分辨率配置

scaler.availableStreamConfigurations/scaler.availableMinFrameDurations/ scaler.availableStallDurations:需要正确配置预预览支持的分辨率以及帧率,此处的分辨率不能大于驱动实际输出的分辨率大小,如下所示:

            <scaler.availableStreamConfigurations value="BLOB,1920x1080,OUTPUT,BLOB,176x144,OUTPUT,YCbCr_420_888,1920x1080,OUTPUT,YCbCr_420_888,176x144,OUTPUT,IMPLEMENTATION_DEFINED,1920x1080,OUTPUT,IMPLEMENTATION_DEFINED,176x144,OUTPUT"/><scaler.availableMinFrameDurations value="BLOB,1920x1080,33333333,BLOB,176x144,33333333,YCbCr_420_888,1920x1080,33333333,YCbCr_420_888,176x144,33333333,IMPLEMENTATION_DEFINED,1920x1080,33333333,IMPLEMENTATION_DEFINED,176x144,33333333" /><scaler.availableStallDurations value="BLOB,1920x1080,33333333,
3.3 SOC模式

在<Sensor_info_RKISP1>中需要配置sensorType,一般SOC为YUVsensor,即不启动3A,RAW为RAW sensor,启动3A,HDMI-IN都是YUV的图像,因此需要设置为SOC模式。

<sensorType value="SENSOR_TYPE_SOC"/> <!-- SENSOR_TYPE_SOC or SENSOR_TYPE_RAW -->
3.4 旋转角配置
<sensor. Orientation value="0"/>

4.APK适配

4.1 获取APK

APK源码地址:

RKDocs/common/hdmi-in/apk/rkCamera2_based_on_CameraHal3_V1.3.tar.gz
4.2 APK 源码适配
APK 通过 ioctl 的方式访问 RK628D 设备节点,获取当前的连接状态和分辨率。 RK628D 设备节点在
isp1/isp2/vicap 链路上可能会差异。需要根据实际情况修改 APK 源码。
rkCamera2/jni/native.cpp

获取连接状态和分辨率的位置:

于在 APK 访问了设备节点,所以需要确认是否关闭了 selinux ,可通过 getenforce 命令查看:

5.EDID配置

若需要修改分辨率支持,可直接在驱动代码中修改 EDID。

(4)调试方法

1.查看设备是否注册camera

使用如下命令查看是否成功注册cameraID

dumpsys media.camera

2.查看拓扑结构

HDMI2MIPI驱动框架类似camera,需要保证pipeline的完整才可以正常工作,使用media-ctl查看pipeline,同时也可以查看转接芯片对应的subdev节点,以便于apk那边适配修改。

media-ctl -d /dev/mediaX -p      //X=0123...

3.v4l2抓取数据流

v4l2-ctl --verbose -d /dev/video0 --set-fmt-video=width=3840,height=2160,pixelformat='NV12' --stream-mmap=4

4.v4l2抓图

v4l2-ctl --verbose -d /dev/video0 --set-fmt-video=width=3840,height=2160,pixelformat='NV12' --stream-mmap=3 --stream-skip=4 --stream-to=/data/3840x2160_nv12.yuv --stream-count=5 --stream-poll

5.不同芯片平台接收能力

由于各个芯片平台isp/vicap的性能不同,对图像的最大接收能力也不同。可参考下表

芯片平台控制器支持分辨率
RK3288/RK3326ISP1080P60
RK3399ISP4K30 超频
RK3568/6ISP/VICAP

ISP:1080P60

VICAP:4K30

6.配置使用ISP CMA内存

部分平台HDMI IN接收图像数据时,根据实际系统负载,可能会存在带宽不足导致丢帧或MIPI接收异常等问题。此时需要提高DDR频率,若仍无改善,可给ISP预留使用CMA内存,以改善解决此问题。

  • rockchip_defconfig 配置预留 CMA 内存 128MB
CONFIG_CMA=y
CONFIG_CMA_SIZE_MBYTES=128
  • 在dts配置ISP关闭IOMMU,使用CMA内存
&rkisp_mmu {status = "disabled";
};

7.配置RK3399 ISP超频

配置RK3399超频625M,实现接收4K30图像。

diff --git a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
index 5ed8dac..e8f259d 100644
--- a/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3399-vop-clk-set.dtsi
@@ -148,7 +148,7 @@<50000000>, <100000000>,<75000000>, <75000000>,<816000000>, <816000000>,
-			 <600000000>, <200000000>,
+			 <625000000>, <200000000>,<800000000>, <150000000>,<75000000>, <37500000>,<300000000>, <100000000>,
diff --git a/drivers/media/platform/rockchip/isp1/dev.c b/drivers/media/platform/rockchip/isp1/dev.c
index 4e548f0..5aa9e13 100644
--- a/drivers/media/platform/rockchip/isp1/dev.c
+++ b/drivers/media/platform/rockchip/isp1/dev.c
@@ -757,7 +757,7 @@ static const unsigned int rk3368_isp_clk_rate[] = {/* isp clock adjustment table (MHz) */static const unsigned int rk3399_isp_clk_rate[] = {
-	300, 400, 600
+	300, 400, 625};static struct isp_irqs_data rk1808_isp_irqs[] = {

(5)总结

本文较长基本详细介绍了安卓9/10/11等平台hdmi-in功能的开发,可以看到hdmi-in与camera最大的不同在于增加了切换分辨率与热拔插的功能,而目前在安卓11的版本上面,都是使用apk轮询的方式实现的,而在安卓12之后的版本中,对这一方式有所优化,并且也增加了低延时送显示的应用框架,不再完全依赖于camera框架,后续我们在做介绍。

http://www.lryc.cn/news/571397.html

相关文章:

  • RAG轻松通-P1:分块
  • 爬虫技术:数据获取的利器与伦理边界
  • 输电线路电缆护层环流在线监测装置:原理、优势与应用解析
  • Elasticsearch/OpenSearch MCP Quickstart
  • 日本生活:日语语言学校-日语作文-沟通无国界(2):回忆深刻的生日
  • threejs webVR获取相机正前方向量
  • 【保姆级】讯飞ROS智能车 Debian系统 U盘克隆/恢复教程
  • Spring Boot启动流程深度解析(源码级剖析)
  • 键盘动作可视化技术浅析:如何做到低延迟显示
  • word如何插入高清晰的matlab绘图
  • 【数据分析三:Data Storage】数据存储
  • Kafka数据写入流程源码深度剖析(Broker篇)
  • Python训练营打卡Day50
  • Linux网络配置工具ifconfig与ip命令的全面对比
  • 游戏技能编辑器之状态机的设计与实现
  • 攻防世界[level7]-Web_php_wrong_nginx_config
  • 一次生产故障引发的JVM垃圾回收器选型思考:彻底掌握垃圾回收原理及通用配置!
  • 在 Java 中操作 Map时,高效遍历和安全删除数据
  • Arrays.asList() 的不可变陷阱:问题、原理与解决方案
  • FPGA 43 ,UDP 协议详细解析( FPGA 中的 UDP 协议 )
  • 升级OpenSSL和OpenSSH 修复漏洞
  • 多组件 flask 项目
  • 数据库新选择?KingbaseES在线体验详解
  • Patch Position Embedding (PPE) 在医疗 AI 中的应用编程分析
  • 工业 AI Agent:智能化转型的核心驱动力
  • 计算机网络学习笔记:TCP流控、拥塞控制
  • taro小程序如何实现新用户引导功能?
  • 【数据结构】图论实战:DAG空间压缩术——42%存储优化实战解析
  • AI大模型初识(一):AI大模型的底层原理与技术演进
  • 数据库系统概论(二十)数据库恢复技术