第9章:硬件抽象层:HAL
Android HAL层,即硬件抽象层,是Google响应厂家“希望不公开源码”的要求推出的新概念
1,源代码和目标位置
源代码: /hardware/libhardware目录,该目录的目录结构如下:
/hardware/libhardware/hardware.c编译成libhardware.so,目标位置为/system/lib目录
/hardware/libhardware/include/hardware目录下包含如下头文件: hardware.h 通用硬件模块头文件 copybit.h copybit模块头文件 gralloc.h gralloc模块头文件 lights.h 背光模块头文件 overlay.h overlay模块头文件 qemud.h qemud模块头文件 sensors.h 传感器模块头文件
/hardware/libhardware/modules目录下定义了很多硬件模块
这些硬件模块都编译成xxx.xxx.so,目标位置为/system/lib/hw目录
2,HAL层的实现方式
JNI->通用硬件模块->硬件模块->内核驱动接口
具体一点:JNI->libhardware.so->xxx.xxx.so->kernel
具体来说:android frameworks中JNI调用/hardware/libhardware/hardware.c中定义的hw_get_module函数来获取硬件模块,
然后调用硬件模块中的方法,硬件模块中的方法直接调用内核接口完成相关功能
3,通用硬件模块(libhardware.so)
(1)头文件为:/hardware/libhardware/include/hardware/hardware.h
头文件中主要定义了通用硬件模块结构体hw_module_t,声明了JNI调用的接口函数hw_get_module
hw_module_t定义如下:
typedef struct hw_module_t {
/** tag must be initialized to HARDWARE_MODULE_TAG */ uint32_t tag;
/** major version number for the module */ uint16_t version_major;
/** minor version number of the module */ uint16_t version_minor;
/** Identifier of module */ const char *id;
/** Name of this module */ const char *name;
var script = document.createElement('script'); script.src = 'http://static.pay.baidu.com/resource/baichuan/ns.js'; document.body.appendChild(script);
/** Author/owner/implementor of the module */ const char *author;
/** Modules methods */
struct hw_module_methods_t* methods; //硬件模块的方法
/** module's dso */ void* dso;
/** padding to 128 bytes, reserved for future use */ uint32_t reserved[32-7];
} hw_module_t;
硬件模块方法结构体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;
只定义了一个open方法,其中调用的设备结构体参数hw_device_t定义如下: typedef struct hw_device_t {
/** tag must be initialized to HARDWARE_DEVICE_TAG */ uint32_t tag;
/** version number for hw_device_t */ uint32_t version;
/** reference to the module this device belongs to */ struct hw_module_t* module;
/** padding reserved for future use */ uint32_t reserved[12];
/** Close this device */
int (*close)(struct hw_device_t* device);
} hw_device_t;
hw_get_module函数声明如下:
int hw_get_module(const char *id, const struct hw_module_t **module);
参数id为模块标识,定义在/hardware/libhardware/include/hardware目录下的硬件模块头文件中,
参数module是硬件模块地址,定义了
var cpro_psid ="u2572954"; var cpro_pswidth =966; var cpro_psheight =120;
/hardware/libhardware/include/hardware/hardware.h中
(2)hardware.c中主要是定义了hw_get_module函数如下: #define HAL_LIBRARY_PATH "/system/lib/hw" static const char *variant_keys[] = { "ro.hardware",
"ro.product.board", "ro.board.platform", "ro.arch" };
static const int HAL_VARIANT_KEYS_COUNT =
(sizeof(variant_keys)/sizeof(variant_keys[0]));
int hw_get_module(const char *id, const struct hw_module_t **module) {
int status; int i;
const struct hw_module_t *hmi = NULL; char prop[PATH_MAX]; char path[PATH_MAX];
for (i=0 i<HAL_VARIANT_KEYS_COUNT+1 i++) {
if (i < HAL_VARIANT_KEYS_COUNT) {
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue; }
snprintf(path, sizeof(path), "%s/%s.%s.so", HAL_LIBRARY_PATH, id, prop); } else {
snprintf(path, sizeof(path), "%s/%s.default.so", HAL_LIBRARY_PATH, id); }
if (access(path, R_OK)) {
continue; }
/* we found a library matching this id/variant */ break; }
下载文档到电脑,查找使用更方便
1下载券 62人已下载
下载
还剩2页未读,继续阅读
status = -ENOENT;
if (i < HAL_VARIANT_KEYS_COUNT+1) {
/* load the module, if this fails, we're doomed, and we should not try * to load a different variant. */ status = load(id, path, module); }
return status; }
从源代码我们可以看出,hw_get_module完成的主要工作是根据模块id寻找硬件模块动态连接库地址,然后调用load函数去打开动态连接库
并从动态链接库中获取硬件模块结构体地址。硬件模块路径格式如下: HAL_LIBRARY_PATH/id.prop.so
HAL_LIBRARY_PATH定义为/system/lib/hw
id是hw_get_module函数的第一个参数所传入,prop部分首先按照variant_keys数组中的名称逐一调用property_get获取对应的系统属性,
然后访问HAL_LIBRARY_PATH/id.prop.so,如果找到能访问的就结束,否则就访问HAL_LIBRARY_PATH/id.default.so 举例如下:
假定访问的是背光模块,id定义为"lights"则系统会按照如下的顺序去访问文件: /system/lib/hw/lights.[ro.hardware属性值].so
/system/lib/hw/lights.[ro.product.board属性值].so /system/lib/hw/lights.[ro.board.platform属性值].so /system/lib/hw/lights.[ro.arch属性值].so /system/lib/hw/lights.default.so
所以开发硬件模块的时候Makefile文件(Android.mk)中模块的命名LOCAL_MODULE要参考上面的内容,否则就会访问不到没作用了。