日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android O 前期预研之二:HIDL相关介绍

發(fā)布時(shí)間:2025/3/15 Android 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android O 前期预研之二:HIDL相关介绍 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在上一篇博客里,大致介紹了下Android O 中treble計(jì)劃的一些背景與相關(guān)基本架構(gòu),這一篇中跟大家一起來探討下HIDL相關(guān)的內(nèi)容。

Android HAL類型?
在此之前的ANDROID版本當(dāng)中Android HAL沒有什么特殊的特殊的,也么有什么分類,但是從android 8.0開始,Android重構(gòu)了HAL與Android FW之間的聯(lián)系結(jié)構(gòu),所以Android HAL會被區(qū)分成以下2種類型:?
1,Binderized HALs,從名字上應(yīng)該是指Binder化的HAL,對Android 比較熟悉的同學(xué)應(yīng)該對binder這個(gè)東西很熟悉,我們是不是可以大膽猜猜下Android 8.0里的HAL是不是都是binder化了?也就是說HAL都被寫成了binder service了?Android FW都是binder client?后續(xù)我們研究研究再來看看我們的猜測是不是正確的。?
2,Passthrough HALs,從google的官方介紹來說,這個(gè)是對原先HAL的包裝,但是最終的binder service 跟binder client都是活在同一個(gè)進(jìn)程當(dāng)中。這個(gè)應(yīng)該是對老版本HAL的兼容。?
3,Same-Process HALs,由于某些性能的因素,這些HALs必須運(yùn)行在Android Framework 所在的進(jìn)程當(dāng)中。

按照google的要求,新設(shè)計(jì)生產(chǎn)的Android O設(shè)備,必須而且只能支持 Binderized HALs,而老版本的設(shè)備升級到Android O可以支持 Passthrough HALs,但是有些HAL也必須修改成 Binderized HALs。?

以下HAL可以根據(jù)是升級設(shè)備或者新設(shè)備自由選擇:?

以下跟graphic相關(guān)的HAL因?yàn)樯婕暗叫阅軉栴},只能在同一個(gè)進(jìn)程當(dāng)中運(yùn)行:?

HIDL的相關(guān)介紹?
HIDL的全稱是HAL interface definition language(硬件抽象層接口定義語言),在此之前Android 有AIDL,架構(gòu)在Android binder 之上,用來定義Android 基于Binder通信的Client 與Service之間的接口。HIDL也是類似的作用,只不過定義的是Android Framework與Android HAL實(shí)現(xiàn)之間的接口。

在AIDL機(jī)制中Android 會提供一系列工具會將用戶定義的*.aidl文件編譯生成Client端代碼與Service端代碼,用戶僅僅 需要1)在Service端實(shí)現(xiàn)所需要實(shí)現(xiàn)的接口。2)在Client端調(diào)用相關(guān)接口。基于Binder機(jī)制,在Clinet端的調(diào)用會自動通過binder驅(qū)動跨進(jìn)程到service進(jìn)程當(dāng)中。

而在HIDL里,與AIDL比較類似,底層也是基于binder機(jī)制。但是也有稍微不一樣的地方。為了支持HIDL,Android 對BInder做了一定程度的修改。

接下來,我們來研究下HIDL的語法,以及通過一個(gè)實(shí)際的例子來真實(shí)感受下HIDL。

HIDL的基本語法:

1)定義接口:

package android.hardware.tests.foo@1.0;interface ISimpleTest {enum SomeBaseEnum : uint8_t {bar = 66};struct Goober {int32_t q;string name;string address;};getCookie() generates (int32_t cookie);customVecInt() generates (vec<int32_t> chain);customVecStr() generates (vec<string> chain);mystr() generates (string str);myhandle() generates (handle str);};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在這里,我們定義一個(gè)新的HIDL接口,取名叫做 ISimpleTest, 從語法上看有點(diǎn)像JAVA的語法。interface是關(guān)鍵字,代表要創(chuàng)建一個(gè)HIDL的接口。我們把上述接口保存成 IsimpleTest.hal文件存放在hardware/interfaces/tests/foo/1.0/ISimpleTest.hal,其實(shí)我們完全可以新建一個(gè)新目錄,使用一個(gè)新的package名,而不使用android.hardware.tests.foo,

2)定義成員:?
如上所示,HIDL當(dāng)中可以像JAVA/C代碼一樣,很容易定義出聯(lián)合體/結(jié)構(gòu)體變量。

3)定義成員函數(shù):?
如上所示,定義的都是無參函數(shù),如果需要定義一個(gè)帶有參數(shù)的函數(shù),可以寫成doThis(float param);,這就代表是一個(gè)有參數(shù),但是無返回值的函數(shù)。

而以上定義的 getCookie() generates (int32_t cookie); 其含義為:函數(shù)名為 getCookie,無參數(shù)傳入,函數(shù)的返回值為一個(gè)int32_t 類型。

HIDL編譯?
在根目錄執(zhí)行./hardware/interfaces/update-makefiles.sh,我們能夠看到會把Android 在hardware/interfaces下的所有package都會更新一遍,我們看下hardware/interfaces/tests/foo/1.0/Android.bp,在Android O當(dāng)中,貌似使用了 Android.bp來替代Android.mk來作為編譯管理工具。至于Android.bp的東西可以后續(xù)在研究,這里我們只關(guān)注于HIDL。

3 filegroup {4 name: "android.hardware.tests.foo@1.0_hal",5 srcs: [6 "types.hal",7 "IFoo.hal",8 "IFooCallback.hal",9 "IMyTypes.hal",10 "ISimple.hal",11 "ISimpleTest.hal",12 "ITheirTypes.hal",13 ],14 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

我們可以看到”ISimpleTest.hal”,已經(jīng)被加進(jìn)編譯文件列表當(dāng)中。

而在生成的C++文件:

16 genrule {17 name: "android.hardware.tests.foo@1.0_genc++",18 tools: ["hidl-gen"],19 cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.foo@1.0",20 srcs: [21 ":android.hardware.tests.foo@1.0_hal",22 ],23 out: [24 "android/hardware/tests/foo/1.0/types.cpp",25 "android/hardware/tests/foo/1.0/FooAll.cpp",26 "android/hardware/tests/foo/1.0/FooCallbackAll.cpp",27 "android/hardware/tests/foo/1.0/MyTypesAll.cpp",28 "android/hardware/tests/foo/1.0/SimpleAll.cpp",29 "android/hardware/tests/foo/1.0/SimpleTestAll.cpp",30 "android/hardware/tests/foo/1.0/TheirTypesAll.cpp",31 ], 32 }33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

我們可以看到這段邏輯是利用 hidl-gen工具來生成.cpp文件。命令是: cmd: “(locationhidl?gen)?o(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.foo@1.0”,?
.hal源碼是:

20 srcs: [21 ":android.hardware.tests.foo@1.0_hal",22 ],
  • 1
  • 2
  • 3

而這部分就是上面所定義的各種.hal文件。最終輸出就是各種.cpp文件。我們比較關(guān)注的就是 SimpleTestAll.cpp文件。

同時(shí)會生成以下一些頭文件:

34 genrule {35 name: "android.hardware.tests.foo@1.0_genc++_headers",36 tools: ["hidl-gen"],37 cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.foo@1 .0",38 srcs: [39 ":android.hardware.tests.foo@1.0_hal",40 ],41 out: [……………………….64 "android/hardware/tests/foo/1.0/ISimpleTest.h",65 "android/hardware/tests/foo/1.0/IHwSimpleTest.h",66 "android/hardware/tests/foo/1.0/BnHwSimpleTest.h",67 "android/hardware/tests/foo/1.0/BpHwSimpleTest.h",68 "android/hardware/tests/foo/1.0/BsSimpleTest.h",………………………...74 ],75 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

從生成的頭文件里看,我們看到有 ISimpleTest.h, BnHwSimpleTest.h, BpHwSimpleTest.h,Bnxxxxx與Bpxxxxx這兩個(gè)東西我們是不是看起來很眼熟?在Binder里, Ixxxxx.h定義了client與service統(tǒng)一的通用接口,而Bnxxxxx.h 派生自 Ixxxxx.h,做為service端實(shí)現(xiàn)的頭文件,Bpxxxxx.h同樣派生自 Ixxxxx.h做為client端的頭文件。這樣調(diào)用Bpxxxxx.h定義的接口,就自動利用binder機(jī)制跨進(jìn)程由service端實(shí)現(xiàn)了Bnxxxxx.h定義函數(shù)。

我們大膽的猜測下,HIDL編譯生成的這些頭文件使用方式應(yīng)該是與AIDL編譯出來的Bnxxxxx/Bpxxxxx作用類似,恭喜你,你的猜測很正確。

IFoo.h. Describes the pure IFoo interface in a C++ class; it contains the methods and types defined in the IFoointerface in the IFoo.hal file, translated to C++ types where necessary. Does not contain details related to the RPC mechanism (e.g., HwBinder) used to implement this interface. The class is namespaced with the package and version, e.g. ::android::hardware::samples::IFoo::V1_0. Both clients and servers include this header: Clients for calling methods on it and servers for implementing those methods.?
IHwFoo.h. Header file that contains declarations for functions that serialize data types used in the interface. Developers should never include his header directly (it does not contain any classes).?
BpFoo.h. A class that inherits from IFoo and describes the HwBinder proxy (client-side) implementation of the interface. Developers should never refer to this class directly.?
BnFoo.h. A class that holds a reference to an IFoo implementation and describes the HwBinder stub (server-side) implementation of the interface. Developers should never refer to this class directly.

FooAll.cpp. A class that contains the implementations for both the HwBinder proxy and the HwBinder stub. When a client calls an interface method, the proxy automatically marshals the arguments from the client and sends the transaction to the binder kernel driver, which delivers the transaction to the stub on the other side (which then calls the actual server implementation).

Google的解釋還是挺清楚,我就不畫蛇添足的翻譯成中文了。

.hal最終編譯出來的結(jié)果是:

cc_library_shared {name: "android.hardware.tests.foo@1.0",defaults: ["hidl-module-defaults"],generated_sources: ["android.hardware.tests.foo@1.0_genc++"],generated_headers: ["android.hardware.tests.foo@1.0_genc++_headers"],export_generated_headers: ["android.hardware.tests.foo@1.0_genc++_headers"],vendor_available: true,shared_libs: ["libhidlbase","libhidltransport","libhwbinder","liblog","libutils","libcutils","android.hidl.base@1.0",],export_shared_lib_headers: ["libhidlbase","libhidltransport","libhwbinder","libutils","android.hidl.base@1.0",],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

從上面看得很清楚,.hal文件被編譯后會生成一個(gè)動態(tài)庫文件 android.hardware.tests.foo@1.0.so

HIDL的使用?
HIDL的使用,其實(shí)就是指怎么在service端實(shí)現(xiàn),怎么在client端調(diào)用。其實(shí)也挺簡單,基本流程就是service端往系統(tǒng)里注冊,client從系統(tǒng)里拿到service 的proxy,然后調(diào)用。跟AIDL的Binder一樣一樣的。

Client端拿service的proxy:?
foo = IFoo::getService(“foo”, mode == PASSTHROUGH /* getStub */);

使用的是Ixxx里自動生成的 getService函數(shù),拿到之后就能使用.hal定義的接口了。

Service端往系統(tǒng)注冊:?
int main() {?
return defaultPassthroughServiceImplementation();?
}?
而且nfc 模塊自己寫了一個(gè).rc文件:?
service nfc_hal_service /vendor/bin/hw/android.hardware.nfc@1.0-service?
class hal?
user nfc?
group nfc

這樣就能讓系統(tǒng)的Init進(jìn)程在開機(jī)階段就把這個(gè)service啟動起來。

稍微總結(jié)下HIDL相關(guān)的內(nèi)容:?
1)HIDL是Android O里的Treble計(jì)劃的核心。目的是通過HIDL語法構(gòu)建出一個(gè)松耦合的系統(tǒng),最終目的是為了方便Android 升級,解決碎片化的問題。?
2)Android為了實(shí)現(xiàn) Binderized HAL有一個(gè)比較清晰的road map:?

不過其實(shí)還有些東西還沒有涉及到,比如FMQ,后續(xù)再來做探討。下一部分,我們開始來研究下Android 新給出的Vendor NDK.


原文地址: http://blog.csdn.net/ljp1205/article/details/77876008

總結(jié)

以上是生活随笔為你收集整理的Android O 前期预研之二:HIDL相关介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。