level 9
浩淼56
楼主
Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),其中,硬件抽象层运行在用户空间,而Linux内核驱动程序运行在内核空间。

访问路线:app——>框架(framework)——>外部库及runtime——>硬件抽象层——>内核
Android硬件抽象层程序开发过程:(Linux硬件驱动开发相似)
第一步:硬件抽象层模块开发:
a 定义模块id
b 定义设备id
c 定义模块结构体
第一个成员变量必须是标准的hw_module_t 结构体,相当于是定义一个hw_module_t子类
d 定义设备结构体
第一个成员变量必须是hw_device_t结构体,相当于是定义一个hw_device_t的子类;
e 定义符号HAL_MODULE_INFO_SYM,类型为自定义的寂寞开结构体
f 实现设备打开接口和关闭接口;
g 实现设备访问接口(可选)
每一个硬件抽象层模块都使用结构体hw_module_t来描述。
每一个硬件设备都使用结构体hw_device_t来描述。

hw_module_t
(1)硬件抽象层中的每一个模块都必须自定义一个硬件抽象层模块结构体,而且它的第一个成员变量的类型必须为hw_module_t。
(2)硬件抽象层中的每一个模块都必须存在一个导出符号,来指向一个自定义的硬件抽象层模块结构体 HAL_MODULE_INFO_SYM,即“HMI”。
(3)结构体hw_module_t的成员变量tag的值必须设置为HARDWARE_MODULE_TAG,即设置为一个常量值('H'<<24 | 'W'<<16 | 'M'<<8 | 'T'),用来标志这是一个硬件抽象层模块结构体。
(4)结构体hw_module_t的成员变量dso用来保存加载硬件抽象层模块后得到的句柄值。每一个硬件抽象层模块都对应有一个动态链接库文件。加载硬件抽象层模块的过程实际上就是调用dlopen函数来加载与其对应的动态链接库文件的过程。在调用dlclose函数来卸载这个硬件抽象层模块时,要用到这个句柄值,因此,我们在加载时需要将它保存起来。
(5)结构体hw_module_t的成员变量methods定义了一个硬件抽象层模块的操作方法列表。
hw_module_methods_t

结构体hw_module_methods_t只有一个成员变量,它是一个函数指针,用来打开硬件抽象层模块中的硬件设备。其中,参数module表示要打开的硬件设备所在的模块;参数ID表示要打开的硬件设备的ID;参数device是一个输出参数,用来描述一个已经打开的硬件设备。由于一个硬件抽象层模块可能会包含多个硬件设备,因此,在调用结构体hw_module_methods_t的成员变量open来打开一个硬件设备时,我们需要指定它的ID。

hw_device_t
(1)硬件抽象层模块中的每一个硬件设备都必须自定义一个硬件设备结构体,而且它的第一个成员变量的类型必须为hw_device_t。
(2)结构体hw_device_t的成员变量tag的值必须设置为HARDWARE_DEVICE_TAG,即设置为一个常量值('H'<<24 | 'W'<<16 | 'D'<<8 | 'T'),用来标志这是一个硬件抽象层中的硬件设备结构体。
(3)结构体hw_device_t的成员变量close是一直函数指针,它用来关闭一个硬件设备。
注:硬件抽象层中的硬件设备是由其所在的模块提供接口来打开的,而关闭则是由硬件设备自身提供接口来完成的。
第二步Android硬件访问服务开发:
a 定义硬件访问接口IXXX
使用AIDL语言定义,编译后会生成一个IXXX_StubD类
b 实现硬件访问服务XXX
从IXXX_Stub类中继承,实现硬件访问接口IXXX,通过JNI访问硬件抽象成模块;
c 实现硬件访问服务XXX的JNI接口
调用函数hw_get_module加载硬件抽象层模块,打开硬件设备;
d 启动硬件访问服务
在system_server进程中穿件一个XXX实例,调用servermanager.addserver
接口将XXX实例注册到servermanager中。
2017年05月01日 13点05分
1

访问路线:app——>框架(framework)——>外部库及runtime——>硬件抽象层——>内核Android硬件抽象层程序开发过程:(Linux硬件驱动开发相似)
第一步:硬件抽象层模块开发:
a 定义模块id
b 定义设备id
c 定义模块结构体
第一个成员变量必须是标准的hw_module_t 结构体,相当于是定义一个hw_module_t子类
d 定义设备结构体
第一个成员变量必须是hw_device_t结构体,相当于是定义一个hw_device_t的子类;
e 定义符号HAL_MODULE_INFO_SYM,类型为自定义的寂寞开结构体
f 实现设备打开接口和关闭接口;
g 实现设备访问接口(可选)
每一个硬件抽象层模块都使用结构体hw_module_t来描述。
每一个硬件设备都使用结构体hw_device_t来描述。

hw_module_t(1)硬件抽象层中的每一个模块都必须自定义一个硬件抽象层模块结构体,而且它的第一个成员变量的类型必须为hw_module_t。
(2)硬件抽象层中的每一个模块都必须存在一个导出符号,来指向一个自定义的硬件抽象层模块结构体 HAL_MODULE_INFO_SYM,即“HMI”。
(3)结构体hw_module_t的成员变量tag的值必须设置为HARDWARE_MODULE_TAG,即设置为一个常量值('H'<<24 | 'W'<<16 | 'M'<<8 | 'T'),用来标志这是一个硬件抽象层模块结构体。
(4)结构体hw_module_t的成员变量dso用来保存加载硬件抽象层模块后得到的句柄值。每一个硬件抽象层模块都对应有一个动态链接库文件。加载硬件抽象层模块的过程实际上就是调用dlopen函数来加载与其对应的动态链接库文件的过程。在调用dlclose函数来卸载这个硬件抽象层模块时,要用到这个句柄值,因此,我们在加载时需要将它保存起来。
(5)结构体hw_module_t的成员变量methods定义了一个硬件抽象层模块的操作方法列表。
hw_module_methods_t

结构体hw_module_methods_t只有一个成员变量,它是一个函数指针,用来打开硬件抽象层模块中的硬件设备。其中,参数module表示要打开的硬件设备所在的模块;参数ID表示要打开的硬件设备的ID;参数device是一个输出参数,用来描述一个已经打开的硬件设备。由于一个硬件抽象层模块可能会包含多个硬件设备,因此,在调用结构体hw_module_methods_t的成员变量open来打开一个硬件设备时,我们需要指定它的ID。
hw_device_t(1)硬件抽象层模块中的每一个硬件设备都必须自定义一个硬件设备结构体,而且它的第一个成员变量的类型必须为hw_device_t。
(2)结构体hw_device_t的成员变量tag的值必须设置为HARDWARE_DEVICE_TAG,即设置为一个常量值('H'<<24 | 'W'<<16 | 'D'<<8 | 'T'),用来标志这是一个硬件抽象层中的硬件设备结构体。
(3)结构体hw_device_t的成员变量close是一直函数指针,它用来关闭一个硬件设备。
注:硬件抽象层中的硬件设备是由其所在的模块提供接口来打开的,而关闭则是由硬件设备自身提供接口来完成的。
第二步Android硬件访问服务开发:
a 定义硬件访问接口IXXX
使用AIDL语言定义,编译后会生成一个IXXX_StubD类
b 实现硬件访问服务XXX
从IXXX_Stub类中继承,实现硬件访问接口IXXX,通过JNI访问硬件抽象成模块;
c 实现硬件访问服务XXX的JNI接口
调用函数hw_get_module加载硬件抽象层模块,打开硬件设备;
d 启动硬件访问服务
在system_server进程中穿件一个XXX实例,调用servermanager.addserver
接口将XXX实例注册到servermanager中。