Android-HIDL實例解析

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
    │   ├── [email protected]
    │   ├── 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: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
+VNDK-core: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
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: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
+VNDK-core: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
 VNDK-core: [email protected]
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生成一些文件

# [email protected]
# 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/[email protected]
=== 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/ca6823b897b5 https://blog.csdn.net/shift_wwx/article/details/86530600

HIDL實例是一個同學在知識星球提問,我開始研究的,後來我把例子寫出來後,這位同學也寫出了自己的例子,而且形成了pdf文檔,如果想了解 的話,在知識星球回覆「HIDL」獲取下載鏈接。

推薦閱讀:

專輯|Linux文章彙總

專輯|程序人生

嵌入式Linux

微信掃描二維碼,關注我的公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章