Android HIDL介绍
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进程双向通信>