1. HAL
1.1 HAL介紹
HAL(Hardware Abstraction Layer)是連接Android Framework與Linux設備驅動的橋梁,有兩個方面的目的
1) 屏蔽掉不同硬件設備的差異,為Android提供了統一的設備訪問接口;不同的硬件廠商遵循HAL標准來實現自己的硬件控制邏輯,開發者不必關心硬件設備的差異,只需按照HAL提供的標准接口對硬件進行訪問即可。
2) 幫助硬件廠商隱藏了設備的核心細節,HAL層位於用戶空間,遵循Apache協議,允許硬件廠商不公開源碼,將設備相關的實現放在HAL層中實現,並以共享庫(.so)的形式進行提供。
1.2 分類
Android 8.0以前的HAL可分為傳統HAL(Stub HAL)和舊版HAL(Legacy HAL)
- Legacy HAL: 該方式為標准的Linux共享庫,其它應用程序直接調用HAL層共享庫導出的函數,接口定義位於libhardware_legacy,實現可參考hardware/broadcom/wlan/bcmdhd/wifi_hal
- Stub HAL: 仍然以共享庫(.so)的形式提供,它把所有供外部訪問的的方法(函數)的入口指針保存在統一的數據結構,其它程序需要訪問HAL中方法時,需要先獲得Stub,然后通過具體的函數指針去讀寫底層設備,實現可參考hardware/libhardware/modules/audio_remote_submix
個人理解,Legacy HAL由app/framework直接打開hal so的方式進行使用;Stub HAL則是app/framework通過libhardware模塊找到對應的hal so,由libhardware來進行調用
1.3 實現
由於目前基本上不再使用這種傳統HAL或者舊版HAL,所以這里不做詳細介紹。
2. HIDL
2.1 介紹
HIDL(HAL Interface Definition Language)是用於指定HAL和其用戶之間的接口的一種接口描述語言(IDL),
AIDL是架構在Android binder之上,用來定義Android基於Binder通信的Client與Service之間的接口;而HIDL定義的則是Android Framework與Android HAL實現之間的接口。
2.2 分類
HIDL設計的初衷是更新framework時避免重新編譯 HAL,后者可以由廠商單獨編譯並在vendor分區中單獨更新。在Android 8及更高版本中,較低級別的層已重新編寫以采用更加模塊化的新架構,搭載Android 8或更高版本的設備必須支持使用HIDL語言編寫的HAL。
HIDL類型的HAL又可分為如下類型
綁定式HAL: Binderized HALs, 以HIDL/AIDL表示的HAL。在綁定式HAL中,framework和HAL之間通過Binder IPC調用進行通信 直通式HAL: Passthrough HALs, 以HIDL封裝的傳統HAL或舊版HAL。封裝了現有的HAL,可在綁定模式和Same-Process模式下使用 Same-Process HAL: 由於某些性能的因素,這些HALs必須運行在Framework所在的進程當中
3. HIDL實現
HIDL實現分為三個部分,HIDL接口、服務端和客戶端
2.3.1 接口
首先編寫HAL接口,示例如下
=========================================================== // PATH: vendor/abc/hardware/interfaces/fixme/1.0/IFixMe.hal package android.hardware.fixme@1.0; import IFixMeCallback; interface IFixMe { requestFix(); printStr(string name) generates (string result); registerCallback(IFixMeCallback callback) generates (ResultCode resCode); unregisterCallback(IFixMeCallback callback); }; =========================================================== // PATH: vendor/abc/hardware/interfaces/fixme/1.0/IFixMeCallback.hal package android.hardware.fixme@1.0; interface IFixMeCallback { oneway onStateChanged(RetStatus ret); }; =========================================================== // PATH: vendor/abc/hardware/interfaces/fixme/1.0/types.hal package android.hardware.fixme@1.0; enum RetStatus : int32_t { SUCCESS = 0x00, FAILTURE = 0x01, };
然后執行進入hardware/interfaces目錄,執行./update-makefiles.sh,則會執行如下文件
vendor/abc/hardware/interfaces/fixme/Android.bp vendor/abc/hardware/interfaces/fixme/1.0/Android.bp vendor/abc/hardware/interfaces/fixme/1.0/Android.mk
注意: 執行上面的命令需要系統已經整編過
2.3.2 服務端
TODO
2.3.3 客戶端
TODO
2.3.3.1 C++實現
TODO
2.3.3.2 JAVA實現
TODO
參考:
<LedHidl>
<硬件抽象層HAL>
<HAL接口定義語言(HIDL)>
<使用HIDL新建虛擬HAL以實現system_server與native進程雙向通信>
