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

HAL

个人理解,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实现之间的接口。

binder_domain

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进程双向通信>

posted @ 2021-02-06 16:32  北落不吉  阅读(2299)  评论(0编辑  收藏  举报