分享

Android-HIDL实例解析

 西北望msm66g9f 2020-07-07
HIDL 简介

HAL interface definition language or HIDL (pronounced “hide-l”) is an interface description language (IDL) to specify the interface between a HAL and its users. It allows specifying types and method calls, collected into interfaces and packages. More broadly, HIDL is a system for communicating between codebases that may be compiled independently.

HIDL 是用于指定 HAL 与其用户之间接口的一个接口描述语言(Interface Description Language),它允许定义变量和函数类型做成封装接口给其他程序调用。通俗的说,HIDL是两个独立程序的桥梁,另外两个程序可以独自编译生成互不影响。

HIDL is intended to be used for inter-process communication (IPC). Communication between processes is referred to as Binderized. For libraries that must be linked to a process, a passthough mode is also available (not supported in Java).

HIDL 实际上是用于进行进程间通信(Inter-process Communication,IPC)。进程间的通信可以称为 Binder 化(Binderized)。对于必须连接到进程的库,也可以使用 passthough 模式(但在Java中不支持)。

HIDL specifies data structures and method signatures, organized in interfaces (similar to a class) that are collected into packages. The syntax of HIDL will look familiar to C++ and Java programmers, though with a different set of keywords. HIDL also uses Java-style annotations.

HIDL 将指定的数据结构与方法签名组织到接口中,这些接口又会被收集到包中以供使用。它的语法与 C++、JAVA 是类似的,不过他们的关键字存在一些差异。其注释风格与 JAVA 是一致的。

为什么需要HIDL

(HIDL design)

The goal of HIDL is that the framework can be replaced without having to rebuild HALs. HALs will be built by vendors or SOC makers and put in a /vendor partition on the device, enabling the framework, in its own partition, to be replaced with an OTA without recompiling the HALs.

设计 HIDL 这个机制的目的,主要是想把**框架(framework)**与 HAL 进行隔离,使得框架部分可以直接被覆盖、更新,而不需要重新对 HAL 进行编译。HAL 的部分将会放在设备的 /vendor 分区中,并且是由设备供应商(vendors)或 SOC 制造商来构建。这使得框架部分可以通过 OTA 方式更新,同时不需要重新编译 HAL。

上图是Framework和HAL的发展图示,之前,具体是到什么时候,我没有去考证,如果知道的同学可以留个言说下,Framework直接调用 HAL,这样导致一个问题,如果HAL增加了什么接口,就需要重新整个都编译系统。

大佬们就发现了这个问题,然后就想多加一个东西,这个东西可以规范一些接口,底层的同学就去填充这些接口就好了。然后就有了直通模式Binderized化模式


测试demo源码

代码位置

  • https://github.com/weiqifa0/android-hidl-demo/blob/master/README.md

源码结构

weiqifa@bsp-ubuntu1804:~/mt8167s-9.0-sdk$ tree hardware/interfaces/naruto/
hardware/interfaces/naruto/
└── 1.0
├── Android.bp
├── default
│   ├── Android.bp
│   ├── android.hardware.naruto@1.0-service.rc
│   ├── Naruto.cpp
│   ├── Naruto.h
│   └── service.cpp
├── INaruto.hal
└── test
├── Android.mk
└── client.cpp

3 directories, 9 files
weiqifa@bsp-ubuntu1804:~/mt8167s-9.0-sdk$

default 里面编译后会生成服务,服务的名字看Android.bp文件,里面有指定了名字,这个名字需要和系统修改对应起来。

test这个目录是测试程序,会编译生成一个测试程序,需要先执行服务,再执行测试程序,代码比较简单,就没有必要解释了。

测试平台

  • Android 9.0 SDK
  • MTK8167s 硬件平台

系统部分修改

weiqifa@bsp-ubuntu1804:~/mt8167s-9.0-sdk$ git diff
diff --git a/build/make/target/product/vndk/28.txt b/build/make/target/product/vndk/28.txt
old mode 100644
diff --git a/build/make/target/product/vndk/28.txt b/build/make/target/product/vndk/28.txt
old mode 100644
new mode 100755
index 712e91c587..82b4f53a7e
--- a/build/make/target/product/vndk/28.txt
+++ b/build/make/target/product/vndk/28.txt
@@ -106,6 +106,7 @@ VNDK-core: android.hardware.media.bufferpool@1.0.so
VNDK-core: android.hardware.media.omx@1.0.so
VNDK-core: android.hardware.media@1.0.so
VNDK-core: android.hardware.memtrack@1.0.so
+VNDK-core: android.hardware.naruto@1.0.so
VNDK-core: android.hardware.neuralnetworks@1.0.so
VNDK-core: android.hardware.neuralnetworks@1.1.so
VNDK-core: android.hardware.nfc@1.0.so
diff --git a/build/make/target/product/vndk/current.txt b/build/make/target/product/vndk/current.txt
old mode 100644
new mode 100755
index 712e91c587..82b4f53a7e
--- a/build/make/target/product/vndk/current.txt
+++ b/build/make/target/product/vndk/current.txt
@@ -106,6 +106,7 @@ VNDK-core: android.hardware.media.bufferpool@1.0.so
VNDK-core: android.hardware.media.omx@1.0.so
VNDK-core: android.hardware.media@1.0.so
VNDK-core: android.hardware.memtrack@1.0.so
+VNDK-core: android.hardware.naruto@1.0.so
VNDK-core: android.hardware.neuralnetworks@1.0.so
VNDK-core: android.hardware.neuralnetworks@1.1.so
VNDK-core: android.hardware.nfc@1.0.so
diff --git a/device/mediatek/mt8167/manifest.xml b/device/mediatek/mt8167/manifest.xml
index 2ae425901b..0bef90c30e 100644
--- a/device/mediatek/mt8167/manifest.xml
+++ b/device/mediatek/mt8167/manifest.xml
@@ -29,6 +29,16 @@
<instance>default</instance>
</interface>
</hal>
+
+<hal format='hidl'>
+ <name>android.hardware.naruto</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>INaruto</name>
+ <instance>default</instance>
+ </interface>
+</hal>
<hal format='hidl'>
<name>android.hardware.light</name>
<transport>hwbinder</transport>
weiqifa@bsp-ubuntu1804:~/mt8167s-9.0-sdk$

编译

编译之前最好系统全编译一次,确保环境变量都生效

source build/envsetup.sh
lunch

使用hidl-gen生成一些文件

# PACKAGE=android.hardware.naruto@1.0
# LOC=hardware/interfaces/naruto/1.0/default/
# make hidl-gen -j64
# hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
# hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE

使用update-makefiles.sh 生成Android.mk 和Android.bp

# ./hardware/interfaces/update-makefiles.sh

单独编译service

mmm hardware/interfaces/naruto/1.0/default/

编译测试client程序

mmm hardware/interfaces/naruto/1.0/test/

Service端执行

Knowin inSight5:/ # vendor/bin/hw/android.hardware.naruto@1.0-service
=== weiqifa ===start service

注意执行service 后是不会马上退出的,如果是马上退出的,可能你是用push方式的,是不对的。

Client 输出

PS C:\Users\weiqifa> adb shell
Knowin inSight5:/ # naruto_test
Hello World, JayZhang
Knowin inSight5:/ #

参考

这里面的链接有些地方没有说明清楚,我重新整理了下,代码主要来自这里,标明出处。

https://www.jianshu.com/p/ca6823b897b5https://blog.csdn.net/shift_wwx/article/details/86530600

HIDL实例是一个同学在知识星球提问,我开始研究的,后来我把例子写出来后,这位同学也写出了自己的例子,而且形成了pdf文档,如果想了解 的话,在知识星球回复「HIDL」获取下载链接。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多