Android硬件抽象层模块编写规范

从Android系统体系结构分析中,我们知道Android使用了硬件抽象层(HAL)来屏蔽底层驱动实现的相关参数和细节,同时也为硬件的访问服务提供了访问接口。所以,硬件抽象层在整个系统中,起到了十分重要的作用。在硬件抽象层中,封装有很多模块,而每一个模块都对应有一个动态的连接库文件;通过这个文件,硬件访问服务(我们可以理解为框架访问)才能为应用程序提供访问底层设备的通道接口,具体如下图所示:

android bootloader保存在哪_Android

结合上面的图形说明,可以知道首先要编写一个硬件抽象层模块接口,利用这个接口找到对应的驱动程序,来访问对应的物理设备硬件。那么如何编写这个模块接口?答案是这样的:Android系统有自己的一套硬件抽象接口编写的规则,所以,我们应该且必须按照这个编写规范来实现硬件抽象模块的接口(如果可以的话,我们可以改变Android系统的内部执行结构)。

在Android系统中,每一个硬件抽象层模块都使用结构体hw_module_t来代表描述,而这个模块对应的硬件设备则用结构体hw_device_t来描述。具体的命名和编写规范如下。

硬件抽象层模块文件编写规范:

android bootloader保存在哪_自定义_02

上面的源代码是位于目录hardware/libhardware/中的hardware.c文件中。依据代码中的注释和预定义的系统属性,我们可以知道硬件抽象层文件的命名原则为”<MODULE_ID>.variant.so“,其中的MODULE_ID表示硬件抽象模块的唯一编号ID,而variant则代表着ro.hardware、ro.product.board、ro.board.platform及ro.arch等四个系统属性之中的一个类型。也就是说,系统启动后按照定义的属性列表顺序逐一取对应的属性的值,如果列表中的一个值被找到的话,那么就会将它的值作为variant的值,否则就使用xxx.variant.so作为默认的抽象模块文件来加载硬件抽象层。

硬件抽象层模块定义规范:(在下面的说明中,只列出部分说明,其他的说明,可以根据代码说明理解)

1、hw_module_t定义规范

android bootloader保存在哪_成员变量_03

硬件抽象层的编写规范说明也在目录hardware/libhardware/中的hardware.c文件中。首先,我们看到上面的注释,它的意思就是在硬件抽象层中,每一个模块都必须自定义一个硬件抽象层模块结构体,并且结构体的第一个成员变量的类型必须是hw_modult_t类型。另外,在每个模块中都必须存在一个“HMI”,即是导出符号“HAL_MODULE_INFO_SYM”用来指向自定义的硬件抽象层模块。

在hw_modult_t结构体中,成员变量tag的作用也很明显。根据它的说明,该变量的值必须设定为HARDWARE_MODULT_TAG,也就是设定一个常量值(‘H’ <<24|’W’<<16|’M’<<8|’T’),用来标识硬件抽象层模块是一个结构体。同时我们也看到成员变量dso,这个成员变量是用来保存记录模块加载之后的句柄值(指向加载模块的唯一索引值)。在需要卸载或释放(dlclose)加载模块的时候,就会使用该句柄值来操作对应的硬件抽象层模块。

当然,还有一个很重要的methods变量。这个变量定义了硬件抽象层模块的操作方法列表,并且类型为hw_module_methods_t类型。源代码如下图:

android bootloader保存在哪_Android_04

操作方法列表hw_module_methods_t目前只有一个成员变量,它是一个指针类型,很明显用来打开硬件抽象层模块所对应的硬件设备的。参数module指要打开的模块;参数id为欲打开设备的编号ID值;而参数device无可置疑指的是我们要打开的硬件设备。从最上面的说明图,我们可以知道在硬件抽象层中可能含有多个硬件设备,所以需要指定要打开的设备的编号ID。硬件抽象层中对应的硬件设备结构体使用了结构体hw_device_来描述,具体如下所示。

2、hw_device_t定义规范

android bootloader保存在哪_Android_05

类似于hw_module_t模块的定义模式,这个结构体的实现说明也在目录hardware/libhardware/include/hardware/中的hardware.h文件中。结构体hw_device_t中,每一个硬件设备都必须自定义一个结构体,并且这个结构体的第一个成员变量必须为hw_device_t类型。而成员变量“tag”的值必须设定为HARDWARE_DEVICE_TAG,用来指定这是一个硬件抽象层中的硬件设备结构体。另外,成员变量close是一个指针类型函数,是用来关闭一个硬件设备的。

注意:在硬件抽象层中,关闭硬件设备是由设备自身提供的关闭接口来完成的,而硬件设备的打开是由硬件抽象层提供的对应的设备接口来打开的,这一点很重要。

介绍完了开发Android硬件抽象层的准备工作之后,我们就可以为欲访问的设备定义和实现硬件抽象层模块接口了,具体实现会在工作之余及时更新!!!