第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要参考上面的内容,否则就会访问不到没作用了。

posted on 2016-07-03 16:19  茵纸  阅读(234)  评论(0编辑  收藏  举报

导航