Android HAL(Hardware Abstract Layer)硬件抽象层,从字面意思可以看出是对硬件设备的抽象和封装,为Android在不同硬件设备提供统一的访问接口。HAL处于Android framework和Linux kernel driver之间,HAL存在的意义有以下2个方面:
HAL屏蔽了不同硬件设备的差异,为Android提供了统一的访问硬件设备的接口。不同的硬件厂商遵循HAL标准来实现自己的硬件控制逻辑,但开发者不必关心不同硬件设备的差异,只需要按照HAL提供的标准接口访问硬件就可以了。
HAL层帮助硬件厂商隐藏了设备相关模块的核心细节。硬件厂商处于利益考虑,不希望公开硬件设备相关的实现细节;有了HAL层之后,他们可以把一些核心的算法之类的东西的实现放在HAL层,而HAL层位于用户空间,不属于linux内核,和android源码一样遵循的是Apache license协议,这个是可以开源或者不开的。
搞清楚了HAL存在的作用,就可以对其框架做个简单的总结。这里从以下3个方面来简单分析下HAL架构,以备后忘。
分析HAL的2个核心数据结构:hw_module_t 和 hw_device_t;
描述HAL是如何查询和加载设备动态共享库的;
以GPS为例,简单分析上层是如何使用HAL来访问硬件设备的。
以Android 6.0 源码为基础,对HAL框架进行分析。
hw_module_t和hw_device_t
Android HAL将各类硬件设备抽象为硬件模块,HAL使用hw_module_t结构体描述一类硬件抽象模块。每个硬件抽象模块都对应一个动态链接库,一般是由厂商提供的,这个动态链接库必须尊重HAL的命名规范才能被HAL加载到,我们后面会看到。
每一类硬件抽象模块又包含多个独立的硬件设备,HAL使用hw_device_t结构体描述硬件模块中的独立硬件设备。
因此,hw_module_t和hw_device_t是HAL中的核心数据结构,这2个结构体代表了HAL对硬件设备的抽象逻辑。我们第一步先来分析下这2个核心数据结构。
hw_module_t定义在/hardware/libhardware/include/hardware/hardware.h文件中:
/**
* Every hardware module must have a data structure named HAL_MODULE_INFO_SYM
* and the fields of this data structure must begin with hw_module_t
* followed by module specific information.
*/
typedef struct hw_module_t {
/* tag must be initialized to HARDWARE_MODULE_TAG /
uint32_t tag;
/**
* The API version of the implemented module. The module owner is
* responsible for updating the version when a module interface has
* changed.
*
* The derived modules such as gralloc and audio own and manage this field.
* The module user must interpret the version field to decide whether or
* not to inter-operate with the supplied module implementation.
* For example, SurfaceFlinger is responsible for making sure that
* it knows how to manage different versions of the gralloc-module API,
* and AudioFlinger must know how to do the same for audio-module API.
*
* The module API version should include a major and a minor component.
* For example, version 1.0 could be represented as 0x0100. This format
* implies that versions 0x0100-0x01ff are all API-compatible.
*
* In the future, libhardware will expose a hw_get_module_version()
* (or equivalent) function that will take minimum/maximum supported
* versions as arguments and would be able to reject modules with
* versions outside of the supplied range.
*/
uint16_t module_api_version;
define version_major module_api_version
/**
* version_major/version_minor defines are supplied here for temporary
* source code compatibility. They will be removed in the next version.
* ALL clients must convert to the new version format.
*/
/**
* The API version of the HAL module interface. This is meant to
* version the hw_module_t, hw_module_methods_t, and hw_device_t
* structures and definitions.
*
* The HAL interface owns this field. Module users/implementations
* must NOT rely on this value for version information.
*
* Presently, 0 is the only valid value.
*/
uint16_t hal_api_version;
define version_minor hal_api_version
/** Identifier of module */
const char *id;
/** Name of this module */
const char *name;
/** Author/owner/implementor of the module */
const char *author;
/** Modules methods */
struct hw_module_methods_t* methods;
/** module's dso */
void* dso;
ifdef LP64
uint64_t reserved[32-7];
else
/** padding to 128 bytes, reserved for future use */
uint32_t reserved[32-7];
endif
} hw_module_t;
注释里面规定,每个硬件模块必须包含一个名字为HAL_MODULE_INFO_SYM的结构体;这个结构体的第一个元素必须为hw_module_t,然后后面可以增加模块相关的其他信息。这里可以理解为是一种继承关系,相当于应硬件模块的HAL_MODULE_INFO_SYM结构体,继承了hw_module_t,只不过是C语言中没有继承的概念,是通过在结构体中包含的方式间接实现的。
HAL_MODULE_INFO_SYM值定义同样在hardware.h中:
/**
* Name of the hal_module_info
*/
define HAL_MODULE_INFO_SYM HMI
/**
* Name of the hal_module_info as a string
*/