拥抱鸿蒙 - 在展讯T606平台上的探索与实践

news2025/4/6 8:36:31

前 言

自OpenHarmony 问世后受到了社会各界的广泛关注,OpenHarmony 的生态系统在如火如荼的发展。

酷派作为一家积极拥抱变化的公司,经过一段时间的探索与实践,成功实现将OpenHarmony 系统接入到展讯平台上,我们相信这是一个重要的里程碑,标志着我们在推动OpenHarmony 的发展环节取得了重要进展。

本文基于的软硬件信息如下:

1.展讯 T606 Android 13(Kernel5.4)2.OpenHarmony v3.2.2 Release

本文受限于篇幅,将着重介绍GPU Mesa 开源方案在展讯平台上的适配。

图形架构

官方图形子系统的架构如下图:

GPU 的适配主要关注框架层的Render Service (渲染服务),代码仓位于: //foundation/graphic/graphic_2d/。

Mesa 适配方案

在介绍详细的适配过程之前,我们先看下整体开发适配的架构图,如下:

我们在图形栈上的Mesa 适配工作主要包括用户层的Mesa 3D 以及Kernel 层的GPU 驱动 (panfrost)这两个方面。

此外需要注意的是,适配之前需要先将OpenHarmony 图形系统的gpu 配置项使能,如下:

      "subsystem": "graphic",
      "components": [
        {
          "component": "graphic_standard",
          "features": [
            "graphic_standard_feature_ace_enable_gpu = true",
            "graphic_standard_feature_rs_enable_eglimage = true"
          ]
        }
      ]

Mesa 3D Library

T606 采用Mali-G57 GPU,OpenHarmony v3.2.2 的三方mesa3d 不支持,需要从上游版本移植,Mesa 22.2 开始支持。

一. 方案选择

我们认为有三个方案可选:

方案一:基于原有版本,参考Mesa上游合入Mali-G57 支持;

方案二:自行升级Mesa 版本至少到22.2,并添加OpenHarmony 支持;

方案三:直接使用4.0 的Mesa3d 仓,2023.8.30已经升级到22.4;

考虑到方案一相对方案二可能有较多的工作量,我们选择了方案二。不过,在经历方案二的一些波折后,我们发现官方已经升级了mesa3d,所以索性我们就直接切到方案三上,其实方案三的问题也不少。

二. 编译Mesa

我们的编译主机是Ubuntu 18.04, meson 版本是0.61.5。

首先我们希望Mesa 能跟随系统一起编译。可是,我们发现ohos/BUILD.gn 有如下部分:

action("mesa3d_build") {
  inputs = deps_inputs
  script = "build_mesa3d.py"

有个输入依赖deps_inputs,是在ohos/dependency_inputs.gni 里定义的:

  21 declare_args() {
  22   deps_inputs = [
  23     "../CODEOWNERS",
  24     "../OAT.xml",
  25     "../VERSION",
  26     "../meson.build",
  27     "../meson_options.txt",
    ...
6976     "../subprojects/libelf.wrap",
6977     "../subprojects/perfetto.wrap",
6978     "../subprojects/zlib.wrap",
6979   ]
6980 }

好家伙,接近7000行,看上去是包含所有的源码文件。那升级Mesa 版本肯定有一堆文件变动,难道我们要手动编辑这个gni文件?或是做个脚本统计?没必要。我们放弃这种编译方式,直接使用build_ohos.py,并把生成的库文件按ohos_prebuilt_shared_library打包到镜像里。

为了解耦system 和vendor,我们把所有的库文件都放到vendor 侧:

     run_build_cmd += '-Dplatforms=ohos -Degl-native-platform=ohos -Ddri-drivers= -Dgallium-drivers=panfrost \
-                      -Dvulkan-drivers= -Dgbm=enabled -Degl=enabled -Dcpp_rtti=false -Dglx=disabled -Dtools=panfrost -Ddri-search-path=/system/lib '
+                      -Dvulkan-drivers= -Dgbm=enabled -Degl=enabled -Dgles1=enabled -Dgles2=enabled -Dcpp_rtti=false -Dglx=disabled -Dtools= -Ddri-search-path=/vendor/lib64/chipsetsdk '

同时,gn 打包的安装路径要保持一致否则会找不到库:

  install_images = [ chipset_base_dir ]
  relative_install_dir = "chipsetsdk"

另外,编译过程生成的临时目录build-ohos,里面不仅仅存放着obj,还有一些重要文件,这是后话,先卖个关子,这正印证了没有实践就没有发言权。

编译过程会遇到一些错误,有的是本地环境导致,比如:

../src/util/u_endian.h:97:3: error: "UTIL_ARCH_LITTLE_ENDIAN and/or UTIL_ARCH_BIG_ENDIAN were unset."
# error "UTIL_ARCH_LITTLE_ENDIAN and/or UTIL_ARCH_BIG_ENDIAN were unset."

可以参考defined(ANDROID)分支添加大小端定义即可:

--- a/src/util/u_endian.h
+++ b/src/util/u_endian.h
@@ -89,6 +89,10 @@

 #endif

+#define UTIL_ARCH_LITTLE_ENDIAN 1
+#define UTIL_ARCH_BIG_ENDIAN 0

编译成功后会生成如下so:

build-ohos/install/lib/libEGL.so.1.0.0
build-ohos/install/lib/libgbm.so.1.0.0
build-ohos/install/lib/libGLESv2.so.2.0.0
build-ohos/install/lib/libGLESv1_CM.so.1.1.0
build-ohos/install/lib/libglapi.so.0.0.0
build-ohos/src/gallium/targets/dri/libgallium_dri.so
build-ohos/install/lib/dri/panfrost_dri.so

Mesa GPU Driver

ARM 官方本身提供了kbase 驱动,但由于其闭源,且采用私有so 进行交互的方式,所以无法应用到OpenHarmony 上。

在展讯平台上,我们选择了Panfrost 这一ARM Mali 系列的GPU 开源驱动,panfrost 主要用于Midgard 和Bifrost 架构的GPU。与kbase 不同,panfrost 接入了Linux drm 框架,从原生层面提供了Linux GPU 驱动体验。

一. 功能移植

由于我们本次适配的展讯平台是基于Kernel 5.4,在5.4 版本上自带的panfrost 还没有支持Mali-G57,所以需要从上游移植panfrost。

关于panfrost 的移植过程可以分为三部分:

1.移植对Mali-G57 平台的支持,从上游backport patch set drm/panfrost: Valhall (JM) support。2.移植上游支持Mali-G57 之前,对其他平台提供的支持。避免丢失某些 Mali-G57 依赖的其他平台的特性。比如 bifrost 平台,以及其他一些 quirk。3.移植对Mali-G57 平台的漏洞修复。

Panfrost 无法解析基于Kbase 的dts,需要手动修改gpu-supply,interrupt-names 等项目。

二. SPRD** 客制化

Dts 中,除了基础的 compatible,寄存器,电源,中断,Sprd 还自定义了一些项目,比如动态调频的控制器和频率,GPU 状态寄存器,时钟等。为了让 GPU 正常工作,需要正确地设置时钟,并对一些必要的寄存器初始化。

在驱动层面,Sprd 在 kbase 驱动的基础上,封装了三组基于平台的接口:

1.平台初始化和退出2.power manager callback。这些接口注册后,kbase 会在合适的时候调用,比如 suspend/resume。3.动态调频接口,通过嵌入到 kbase 调频流程中发挥作用。

这部分是 sprd 针对 kbase 驱动单独添加的内容。如需要相关功能,需要移植到 panfrost 中。这里介绍一种能够启动 GPU 的最小化方案:移植平台初始化代码。

平台初始化代码主要负责频率获取,时钟使能。频率和时钟的信息都定义在 dts 中,最终解析结果如下:

gpu_dvfs_ctx.clk_gpu_i                  <&aonapb_gate CLK_GPU_EB>
gpu_dvfs_ctx.clk_gpu_core_eb            <&g1_pll CLK_RPLL_26M>
gpu_dvfs_ctx.clk_gpu_mem_eb             <&g5l_pll CLK_TGPLL_76M8>
gpu_dvfs_ctx.clk_gpu_sys_eb             <&g5l_pll CLK_TGPLL_153M6>
gpu_dvfs_ctx.gpu_clk_src [
                                        <&g5l_pll CLK_TGPLL_384M>
                                        <&g5l_pll CLK_TGPLL_512M>
                                        <&g5r_pll CLK_GPLL>
                                        <&g5r_pll CLK_GPLL_850M>  // clk_set_rate(..., 650000_000)
]

gpu_dvfs_ctx.freq_list = [
        384000
        512000
        614400
        650000
]

将平台初始化代码移植到panfrost ,基本可以使 GPU 正常工作。但是因为缺失了电源和频率模块,相关功能都不可用。我们尝试通过 /sys/class/devfreq 获取 GPU 频率,但只获取到一个错误的值(26M),跟踪相关代码发现 panfrost 将时钟绑定到了<&aonapb_gate CLK_GPU_EB> 上,但真正用于GPU 工作的是后四个clock,即 384M,512M,614M,650M。

调试验证

在调试Mesa 前需用三方modetest 测试图形显示是否正常。

Step1: 测试前需要先停掉render_service

service_control stop render_service

Step2: 使用atomic 方式来测试sprd 的图形驱动

# 指定 mode: connector_id=92, crtc_id=83, mode=720x1520
# 指定 plane: plane_id=31, crtc_id=83, weight*height=720*1520
modetest -a -M sprd -s 92@83:720x1520 -P 31@83:720x1520

正常的出图效果如下:

下面来看我们遇到的问题,在Mesa 适配完刷机后我们就发现系统在反复重启,内核能看到如下错误:

[   32.857012]c7 [ T1615] CPU: 7 PID: 1615 Comm: render_service Tainted: G S

主要是render_service 配置了critical 字段:

// graphic.cfg
     "services" : [{
             "name" : "render_service",
             "path" : ["/system/bin/render_service"],
             "critical" : [1, 5, 60],

参考官方对critical 字段的说明:

其实就是服务重启次数过多了就重启系统,为了便于调试,我们可以设置为0 先不使能。

抓取到的render_service crash 栈如下:

能看出来渲染主线程Init 挂掉了,在添加日志后发现死在opengl_wrapper 的glGetString(),这个接口按理说是openGL 提供的标准接口,所以对于堆栈挂在这个接口上,我们一开始并没有太多的头绪。

随着通过不断加日志debug 梳理上下文的调用关系,最终定位是由于一个比较隐蔽的平台差异性问题导致,这里受限于篇幅就不详细展开了。

如下图,正常运行时的render_service crashCnt 是0,status 是running:

我们还未来得及欣喜,却又遇到如下crash:

死在Mesa 的libEGL 上,没有什么能阻挡我们前进的步伐,我们再次跟踪Mesa,也修复了此问题。

调试过程中hilog 可以使用-D 过滤日志:

-D , --domain= Show specific domain/domains logs with format: domain1,domain2,doman3 Don’t show specific domain/domains logs with format: ^domain1,domain2,doman3 Max domain count is 5.

图形domain ID 定义如下:

29 // The "0xD001400" is the domain ID for graphic module that alloted by the OS.
 30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL_RS = { LOG_CORE, 0xD001400, "OHOS::RS" };
 31 constexpr OHOS::HiviewDFX::HiLogLabel LABEL_ROSEN = { LOG_CORE, 0xD001400, "OHOS::ROSEN" };

使用如下命令启动渲染服务时只抓图形log并存于本地:

hdc shell "hilog -D 0xD001400 & service_control start render_service" > hilog-rs.txt

另外,可以用一个gl_test 来验证,正常情况如下图,屏幕左上角会出现一个三角形:

性能分析

我们在移植结束后遇到了这样的一个问题,现象是:拖动桌面图标时界面卡顿。

熟悉Android 性能问题分析的小伙伴都知道,Android 提供了抓取trace 的atrace 工具,那么在OpenHarmony 平台上是否也有现成的抓取trace 功能呢?

其实OpenHarmony 提供了名为bytrace 的工具,借助这个工具我们可以抓取一份Ftrace ,命令如下:

echo > /sys/kernel/debug/tracing/trace
echo 90096 > /sys/kernel/debug/tracing/saved_cmdlines_size
bytrace -t 20 -b 90096 --overwrite ohos zimage zmedia zcamera zaudio ability distributeddatamgr graphic freq irq mdfs workq  mmc idle notification sync pagecache ace app > /data/Launcher.ftrace
echo > /sys/kernel/debug/tracing/trace

Ftrace 的抓取步骤和Android 平台是一样的,导出的Ftrace 文件用前端工具打开。

如下图所示:

很快,我们在Launcher 所在进程区域发现了异常,那就是当Launcher 界面卡顿时,应用的绘制和渲染侧都是空白的(红圈处),所以自然而然也就没有帧送到屏幕上。

那么对于应用侧没有出帧的情况,根据我们以往的经验,通常是由于主线程被某个事务阻塞,导致没有办法响应Vsync 的callback。

结合Hilog 观测到如下片段持续高频的输出:

[js_progress.cpp(SetCircularStyle)-(1)] circular Style error. now use default scaleWidth

此时可以认定是由于Launcher 在调用框架接口SetCircularStyle 时陷入了循环调用中,另一方面也说明了应用自身的容错能力存在问题。

接下来的工作主要是跟着代码搜寻SetCircularStyle这一函数调用场景及排查报错的原因,最终我们解决了该问题,受限于篇幅不详细展开。

结 语

在移植适配Mesa 到展讯平台的过程中,除了文中提到的问题,我们还遇到了许多棘手的问题,有图形领域相关的,也有不少平台兼容性的问题。

在解决这些问题的过程中,我们深感图形领域的错综复杂。未来,我们将不断地补齐短板,继续探索深耕图形领域,为OpenHarmony 的生态发展贡献我们的绵薄之力。

为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙 (Harmony OS)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. 应用开发导读(Java)

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1327152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Infant-freesurfer安装和使用,适用于0-2岁婴幼儿大脑自动分割

Infant-freesurfer安装和使用 #Note https://surfer.nmr.mgh.harvard.edu/fswiki/infantFS --官网申请下载infant_recon_all --s SUBJ --age age_in_months--newborn flag (it aut

AVP摄像头与ECU交互需求规范

目录 1 文档范围及控制方法... 5 1.1 目的.... 5 1.2 文档授权... 5 1.3 文档变更管理... 5 1.4 缩写.... 5 1.5 术语.... 5 2 系统组成... 6 2.1 系统框图... 6 2.2 电源供应和时序要求... 7 2.2.1 摄像头供电控制... 7 2.2.2 摄像头上电时序要求…

Linux Centos7 安装NVIDIA 驱动

cat /etc/redhat-release 查看系统版本 服务器IP 系统版本 内核 GPU 内存和硬盘 后期扩容 10.0.2.125 CentOS Linux release 7.9.2009 5.3.10-1.el7.elrepo.x86_64 4 张 Tesla T4&#xff08;16G&#xff09; 376G 1.5T 物理机 10.0.2.130 CentOS Linux release …

消息中间件的介绍

消息中间件&#xff08;message oriented middleware&#xff09;是指支持与保障分布式应用程序之间同步/异步收发消息的中间件。消息是分布式应用之间进行数据交换的基本信息单位&#xff0c;分布式应用程序 之间的通信接口由消息中间件提供。其中&#xff0c;异步方式指消息发…

T2I-Adapter: 让马良之神笔(扩散模型)从文本生成图像更加可控

文章信息 单位&#xff1a;北大深张健团队&#xff0c;腾讯ARC lab 源码: https://github.com/TencentARC/T2I-Adapter 图1. 插个DXL的渲染图&#xff0c;这么真实的光感&#xff0c;感觉PS都可以被取代了 目录 文章信息前言一、介绍二、相关工作1.图像合成与转换2 扩散模型3 适…

多维时序 | MATLAB实现SSA-CNN-SVM麻雀算法优化卷积神经网络-支持向量机多变量时间序列预测

多维时序 | MATLAB实现SSA-CNN-SVM麻雀算法优化卷积神经网络-支持向量机多变量时间序列预测 目录 多维时序 | MATLAB实现SSA-CNN-SVM麻雀算法优化卷积神经网络-支持向量机多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | MATLAB实现…

【计算机图形学】Ditto: Building Digital Twins of Articulated Objects from Interaction

项目主页&#xff1a;Ditto: Building Digital Twins of Articulated Objects from Interaction 文章目录 1. 为什么要做这件事2. 做了件什么事3. 之前的工作&#xff08;Related work&#xff09;铰接模型估计铰接物体的3D重建隐式神经表达物理仿真中的铰接物体 4. 问题定义5…

腾讯云服务器上传文件 :Permission denied (os error 13) ,由于权限无法上传

根据网上的修改云服务器上传文件目录的权限&#xff0c;或是用root权限上传本地文件&#xff0c;均失败。 正解办法&#xff1a; ubuntu:/home/wwwroot# sudo passwd root Enter new UNIX password: Retype new UNIX password: passwd: password updated successfully首先修…

Windows常用的功能命令

Win操作方法 快捷键winR&#xff0c;输入cmd回车&#xff0c;然后就可以输入cmd命令了&#xff0c;赶紧收藏起来&#xff0c;用的时候更方便 打开程序和功能 快捷键winR&#xff0c;输入appwiz.cpl回车 启动计算器 快捷键winR&#xff0c;输入calc回车 计算机管理 …

saas供应链批发订货系统源码整套输出的3大好处

随着电子商务的快速发展&#xff0c;越来越多的企业开始关注和采用供应链批发订货系统&#xff0c;以提高其供应链管理的管理效率和数据沉淀。现在大多企业还是使用SaaS供应链系统&#xff0c;而源码整套输出的3大好处、尤其是第三个可让企业受益匪浅。 1. 定制化能力&#xff…

Leetcode 55 跳跃游戏

题意理解&#xff1a; 非负整数数组 nums, 最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 需要跳到nums最后一个元素即为成功。 目标&#xff1a;是否能够跳到最后一个元素。 解题思路&#xff1a; 使用贪心算法来解题&#xff0c;需要理解…

Unity中Shader平移矩阵

文章目录 前言方式一&#xff1a;对顶点本地空间下的坐标进行相加平移1、在属性面板定义一个四维变量记录在 xyz 上平移多少。2、在常量缓冲区进行申明3、在顶点着色器中&#xff0c;在进行其他坐标转化之前&#xff0c;对模型顶点本地空间下的坐标进行转化4、我们来看看效果 方…

NIO的实战教程(简单且高效)

1. 参考 建议按顺序阅读以下三篇文章 为什么NIO被称为同步非阻塞&#xff1f; Java IO 与 NIO&#xff1a;高效的输入输出操作探究 【Java.NIO】Selector&#xff0c;及SelectionKey 2. 实战 我们将模拟一个简单的HTTP服务器&#xff0c;它将响应客户端请求并返回一个固定的…

​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进

在当今数字化浪潮愈发汹涌的时代&#xff0c;科技公司的发展不仅需要更强大的计算能力和创新性技术&#xff0c;还需要对环境的高度责任感。在这一背景下&#xff0c;亚马逊云科技的海外服务器产品成为了推动清洁、高效数字未来的领导者之一。亚马逊云科技的高级主管阿比谢克夏…

【MyBatis学习笔记】MyBatis基础学习

MyBatis基础 MyBatis简介MyBatis特性MyBatis下载和其他持久化层技术对比 核心配置文件详解默认的类型别名 搭建MyBatis开发环境创建maven工程创建MyBatis的核心配置文件创建mapper接口创建MyBatis的映射文件通过junit测试功能加入log4j日志功能 MyBatis获取参数值的两种方式&am…

vue-pure-admin源码解读与使用

vue-pure-admin 全面使用ESMVue3ViteElement-PlusTypeScript编写的一款后台管理系统&#xff08;兼容移动端&#xff09;,目前斩获11.5k个star。 界面构成 主题Layout的组成 左边sidebar由Vertical组件定义tab标签栏由layoutHeader组件定义中间Body由appMain组件定义 为何点…

@RequestParam、@PathVariable、@RequestBody、@RequestAttribute详解

一、RequestParam注解 作用&#xff1a;用于将指定的请求参数赋值给方法中的形参。 属性&#xff1a; 1&#xff09;value&#xff1a;请求参数名&#xff08;必须配置&#xff09; 2&#xff09;required&#xff1a;是否必需&#xff0c;默认为 true&#xff0c;即请求中必须…

GESP认证第四次考试百分榜考生名单及学校

考生姓名 所在学校 编程语言 得分 谢秉修 上海市民办华育中学 C 八级 100 张洪森 淄博市张店区第八中学 C 四级 100 高希文 宜兴市实验中学 C 四级 100 窦铭泽 温州市实验中学教育集团府东分校 C 四级 100 袁…

浅析 fuse kernel mmap write 过程及性能问题

前言 最近在项目里面用到了fuse文件系统&#xff0c;在使用过程中遇到了一个内核在做mmap write的一个bug&#xff0c;目前并没有从根本上解决这个bug&#xff0c;而是通过修改fuse kernel module的一些参数&#xff0c;绕开了这个bug。这里记录一下这个问题&#xff0c;并顺便…

学会这个插件,职业生涯少写 1w 行代码。

前言 学会这个插件&#xff0c;职业生涯少写 1w 行代码。 与前端对接、与后端对接、与数据对接、与第三方对接等等。这些工作发生在大家的整个工作周期中&#xff0c;其中有些工作都是重复性的&#xff0c;而且是机械的。 所以今天给大家推荐一款非常实用 IDEA 插件&#xf…