IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> HIDL 原理及使用详解 -> 正文阅读

[移动开发]HIDL 原理及使用详解

目录

1. ?HIDL 概念

1.1. Hidl 的简单介绍

1.2. Hidl 的设计目的

1.3. Hidl 与 Aidl 的对比

2 . HIDL 类型?

2.1 Passthrough

2.2?Binderized

3. HIDL 服务的实现

3.1 hidl_gen 工具路径

3.2 update-makefiles.sh?

3.3 update-files.sh?

3.4 HIDL 生成的文件?

3.5 service 和 impl 关系

3.6 添加 rc 文件?

3.7 启动 service?

?3.8 实现 client 端

4 . 新旧软件架构对比

4.1 Android 8.0 之前架构图

?4.2 binder 驱动通讯的实现

4.3 使用 HIDL 设计软件架构


1. ?HIDL 概念

1.1. Hidl 的简单介绍

????????HIDL的全称是HAL interface definition language(硬件抽象层接口定义语言),是Android
Framework 与Android HAL之间的接口。HIDL 旨在用于进程间通信 (IPC),进程之间的通信
采用 Binder 机制。

1.2. Hidl 的设计目的

????????HIDL 的目标是,可以在无需重新构建 HAL 的情况下替换框架。HAL 将由供应商或 SOC
制造商构建,并放置在设备的 /vendor 分区中,这样一来,就可以在框架自己的分区中通过
OTA 替换框架,而无需重新编译 HAL。
HIDL 设计在以下方面之间保持了平衡:

? ?互操作性。在可以使用各种架构、工具链和编译配置来编译的进程之间创建可互操作的
可靠接口。HIDL 接口是分版本的,发布后不得再进行更改。


? ?效率。HIDL 会尝试尽可能减少复制操作的次数。HIDL 定义的数据以 C++ 标准布局数
据结构传递至 C++ 代码,无需解压,可直接使用。此外,HIDL 还提供共享内存接
口;由于 RPC 本身有点慢,因此 HIDL 支持两种无需使用 RPC 调用的数据传输方
法:共享内存和快速消息队列 (FMQ)。


? ?直观。通过仅针对 RPC 使用 in 参数,HIDL 避开了内存所有权这一棘手问题:无法通
过相应方法高效返回的值将通过回调函数返回。无论是将数据传递到 HIDL 中以进行传
输,还是从 HIDL 接收数据,都不会改变数据的所有权,也就是说,数据所有权始终属
于调用函数。数据仅需要在函数被调用期间保留,可在被调用的函数返回数据后立即清
除。

1.3. Hidl 与 Aidl 的对比

2 . HIDL 类型?

2.1 Passthrough

????????兼容之前的 HAL 使用方式(在同一个进程)。要将运行早期版本的 Android 的设备更新为
使用 Android O,您可以将惯用的(和旧版)HAL 封装在一个新 HIDL 接口中,该接口将在绑
定式模式和同进程(直通)模式提供 HAL。这种封装对于 HAL 和 Android 框架来说都是透明
的。
????????直通模式仅适用于 C++ 客户端和实现。运行早期版本的 Android 的设备没有用 Java 编
写的 HAL,因此 Java HAL 自然而然经过 Binder 化。

2.2?Binderized

????????使用 Binder 方式进行 IPC(在不同进程)。在使用 HIDL 的时候需要有两个软件包,一个
是 FQName-impl,一个是 FQName-service。FQName-impl 一般是 HAL 实现的部分或者是链接
HAL 的部分,FQName-service 就是 service 端。

3. HIDL 服务的实现

3.1 hidl_gen 工具路径

代码目录:system/tools/hidl

在使用的时候可以直接使用 out/host/linux-x86/bin/hidl-gen 或者使用:
source build/envsetup.sh
lunch m7332-userdebug
lunch 之后可以直接使用 hidl-gen,因为这个时候已经将 bin 的目录添加到了环境变量中了
可以使用 hidl-gen -h 查看

3.2 update-makefiles.sh?

通过/hardware/interfaces/update-makefiles.sh 可以创建编译 HIDL 文件的 Android.bp
假设我们创建一个 helloworld 的模块,在 hardware/interfaces 下创建 helloworld/1.0/IHelloWorld.hal:

通过 update-makefiles.sh 就可以在对应 package 的目录下创建 Android.bp:
chenzhaohao@ubuntu:~/9632-1/public-mtk9632/hardware/interfaces$ ./update-makefiles.sh
…….
Updating android.hardware.helloworld@1.0
…….

name:FQName 的全名
root:定义好的 package root name
interfaces:编译过程中依赖的接口名称,如 c 中的 shared library
gen_java:是否编译为 Java 使用的接口
当然,还有其他的参数,例如 gen_java_constants 设为 true 的时候会生成为 Java 使用的 Constants 类。
可以根据实际情况修改该 Android.bp

3.3 update-files.sh?

IHelloWorld.hal 和对应的 Android.bp 创建好后,就可以根据需要实现 FQName-impl 和 FQName-service 所
需要的文件,而这些文件也是通过 hidl-gen 创建的,就是下面这个脚本。

update-files.sh 文件路径 移动到源码根目录下
执行
chenzhaohao@ubuntu:~/9632-1/public-mtk9632/$ ./update-files.sh

执行完之后自动生成了 default 目录

创建后的 Android.bp 如下:

????????可以根据特殊的需要进行修改,例如,vendor 需要设为 true,这样编译出来的 so 位于 vendor 下面,而不是 system。也可以使用同样的方式为 FQName-service 创建对应的规则。?

?

3.4 HIDL 生成的文件?

在编译 HIDL 文件,会在 out/soong/.interfaces/PACKAGE/MOUDLE/VERSION/下生成对应的文件。例如helloworld 是在 hardware/interfaces 下创建,所以生成的文件路径为:
out/soong/.intermediates/hardware/interfaces/helloworld/1.0

?

其中:
android.hardware.helloworld@1.0 就是模块对应的库文件;
android.hardware.helloworld@1.0_genc++ 为生成对应的 C++临时文件,在使用的时候都是链接到这里;
android.hardware.helloworld@1.0_genc++/gen/android/hardware/helloworld/1.0/HelloWorldAll.cpp
android.hardware.helloworld@1.0_genc++_headers 为生成的 C++ 所需的头文件;

android.hardware.helloworld-V1.0-java 为 java 代码所使用的 java 库文件;
android.hardware.helloworld-V1.0-java_gen_java 为 java 代码所使用的 java 文件

3.5 service 和 impl 关系

当 IHelloworld.hal 创建完成就可以创建对应的 HIDL 实现代码(impl 和 service),而 hidl-gen 也提供了默认提供了生成的方式。
Impl:

service.端的 service.cpp 需要手动去编写,可以拷贝系统已存在的过来进行修改,比较简单

3.6 添加 rc 文件?

在实现了 serivce 和 impl 代码后需要添加 rc 文件,文件名为 android.hardware.helloworld@1.0-
service.rc:

3.7 启动 service?

?在 xml 中配置完成之后就直接 start;另外需要设置 selinux 中添加 te 文件,设置 domain 信息。对于selinux 配置,这里暂不分析

?3.8 实现 client 端

客户端的文件直接使用 java 文件引用编译生成的 java 静态库 android.hardware.helloworld-V1.0-java然后 IHelloWorld.getService(true); 来获取 HIDL 服务。这样就直接跳过 java – jni ---c++

接着可以直接在 HelloWorld.cpp 中引用 hal 层编译生成的 so 文件来操作硬件外设。

4 . 新旧软件架构对比

4.1 Android 8.0 之前架构图


以 Android 原生自带的 Led 硬件访问服务为例子

????????这里的难度是在 binder 通讯那块,如果使用的是 Android 原生的就 不需要重新写。但是想要开发自己的中间件,就必须实现要去实现自己的 binder 驱动通讯。

?4.2 binder 驱动通讯的实现

????????采用旧架构进行中间件的设计和开发架构图如下,这里忽略 app 到中间件的的调用流程,这个流程和HIDL 的一样。流程直接从 native 开始往下走。

从上面的架构流程图可以看出,使用老技术开发操作硬件外设是非常的复杂和繁琐。涉及到的文件和知识点众多,无论是前期开发或者是后期的维护难度是非常大。因此,在 Android 8.0 之后的版本,采用了 HIDL进行软件架构重构,弃用之前的方法。HIDL 加快了相应速度,提高访问效率,而且代码简洁,接口逻辑清晰,开发和维护起来方便。

4.3 使用 HIDL 设计软件架构

有了前面 3 章节介绍 Hidl 的知识点之后,我们就可以设计出基于 HIDL 的软件架构。

通过新软件架构图和传统的软件架构图可以知道 HIDL 那层代替了原来的?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:55:38  更:2022-08-06 10:58:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:49:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码