基础
HAL层介于android内核和上层应用之间的抽象层接口。作用将硬件抽象化,屏蔽特定平台的硬件接口细节,使平台具有平台无关性,便于移植。
Linux内核源代码遵循GPL1协议,Android直接在linux内核中添加修改代码,需要公开源代码;为保护硬件厂商的知识产权,避开GPL协议约束。
结构
HAL存在两种结构。
- libhardware_legacy 旧的实现
- libhardware 新的实现
libhardware_legacy:
将*.so以共享库的形式使用,在运行时以direct function call使用HAL module。通过直接函数调用的方式,来操作驱动程序。
libhardware:
新的HAL采用HAL module 和HAL stub结合的形式。
HAL stub是一种代理人proxy概念;将供外部访问的方法的函数指针统一保存在一个数据结构中。stub向HAL提供操作函数,而runtime则是向HAL获取特定模块stub的operations。HLAL包含许多stub(代理人)。runtime只要说明类型(module id),就可以取得操作函数,通过接口访问硬件。
代码位置
HAL代码位于/hardware下
- /hardware/libhardware_legacy : 旧的HAL架构,采用链接库方式
- /hardware/libhardware : 新HAL架构,使用HAL Stub
HAL 调用:
- app 调用硬件服务对应的api,如 BluetoothService.java
- FrameWork service 调用JNI方法
- HAL 加载硬件共享库(*.so)
- 从内存获取设备结构
- 调用HAL Stub 方法
简单讲:
Android HAL实现通过JNI实现。APP通过jni调用hardware.c的hw_get_module函数获取硬件模块,然后调用硬件模块中方法,硬件模块中的方法调用内核接口完成相关功能。
通用硬件模块
HAL module 主要由3个结构体,
定义在/hardware/libhardware/include/hardware/hardware.h
- struct hw_module_t 模块类型
- struct hw_module_methods_t 模块方法
- struct hw_device_t 设备类型
hw_module_t
typedef struct hw_module_t {
/** tag must be initialized to HARDWARE_MODULE_TAG */
uint32_t tag;
uint16_t module_api_version;
#define version_major module_api_version //主版本号
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;
- 每个硬件模块第一个变量是hw_module_t,每个模块必须存在HAL_MODULE_INFO_SYM命名的结构,它指向一个自定义的硬件抽象层模块结构。
- hw_module_t成员变量tag的值必须是HARDWARE_MODULE_TAG,用来表示这是一个硬件模块
- hw_module_t的dso,表示打开硬件模块后得到的句柄,
- hw_module_t的methods:硬件模块的方法列表
hw_module_methods_t
typedef struct hw_module_methods_t {
//打开硬件设备
/** Open a specific device */
int (*open)(const struct hw_module_t* module, const char* id,
struct hw_device_t** device);
} hw_module_methods_t;
hw_module_methods_t只有一个函数指针变量,用来打开硬件抽象层的设备。
id代表需要打开的硬件设备ID。硬件抽象层模块可能对应多个硬件设备,在打开硬件设备时需要指定一个硬件设备ID。
如传感器模块,sensor_module,是一个硬件模块,对应的传感器包括:加速度传感器,磁感应器,
hw_device_t
typedef struct hw_device_t {
/** tag must be initialized to HARDWARE_DEVICE_TAG */
uint32_t tag; //设备TAG
uint32_t version;
/** reference to the module this device belongs to */
struct hw_module_t* module; //归属的硬件模块
/** padding reserved for future use */
#ifdef __LP64__
uint64_t reserved[12];
#else
uint32_t reserved[12];
#endif
//关闭设备
/** Close this device */
int (*close)(struct hw_device_t* device);
} hw_device_t;
硬件抽象层的硬件设备使用hw_device_t描述。
每个硬件抽象层中每个硬件设备必须自定义一个硬件设备结构,第一个成员必须是hw_device_t。成员变量close函数指针用来关闭硬件设备。