Android HAL

来源:互联网 发布:免费永久个人域名注册 编辑:程序博客网 时间:2024/04/30 05:42

1 HAL产生的原因

Android HAL(Hardware Abstraction Libraries)是处于user space的最下层,是Android定义的要求Linux内核空间来具体实现的驱动接口。根据Google的说法,使用user-space HAL的原因为:

1 Not all components have standardizedkernel driver interface

2 Kernel driver are GPL which exposes anyproprietary IP

3 Android has specific requirements forhardware drivers

但这其中最重要的原因为第二个,把控制硬件的动作都放到了user space中,在kernel driver里面只有最简单的读写寄存器的操作。Android user space的代码就可以不必受到GPL的束缚而封装成库,避免了暴露硬件厂商使用的硬件型号。

2 HAL的重要性

HAL的重要性主要表现在两个方面:

1 从学习的角度看,HAL通常是Linux内核开发者想学习整个Android系统架构时选择的突破口,这是由于HAL所处在整个系统架构的位置决定的;同样Android user-space的开发者,想要从APP和中间件进一步深入贯通到内核,HAL也是必经之路。如果把Kernel比作关内,Android user-space比作关外,HAL就是进出关的唯一通道,兵家必争之地。

2 从使用的频度来看,随着对SOC性能要求的进一步提高,越来越多的模块将使用硬件加速,甚至以前使用DSP来加速的一些模块,由于性能和功耗的要求,都改用硬件实现,特别是多媒体相关的领域,GPU也几乎成了最近2年出来的SOC的标配,Android也集成了方便使用硬件加速的标准OpenMAX, OpenGL等。

3 HAL的2种模式

3.1 直接调用(旧的模式)

1 源码路径:\hardware\libhardware_legacy

2 模式简介:libhardware_legacy是将 *.so 文件当作shared library来使用,JNI以 direct function call 使用 HAL module。通过直接函数调用的方式,来操作驱动程序。

3 实例:PowerManager

JNI层:android_os_Power.cpp(frameworks\base\core\jni)

[cpp] view plaincopyprint?
  1. static void  
  2. acquireWakeLock(JNIEnv *env, jobject clazz, jint lock, jstring idObj)  
  3. {  
  4.     if (idObj == NULL) {  
  5.         throw_NullPointerException(env, "id is null");  
  6.         return ;  
  7.     }  
  8.   
  9.     const char *id = env->GetStringUTFChars(idObj, NULL);  
  10.   
  11.     acquire_wake_lock(lock, id);  
  12.   
  13.     env->ReleaseStringUTFChars(idObj, id);  
  14. }  

HAL层:Power.c(hardware\libhardware_legacy\power)
[cpp] view plaincopyprint?
  1. int  
  2. acquire_wake_lock(int lock, const char* id)  
  3. {  
  4.     initialize_fds();  
  5.   
  6. //    LOGI("acquire_wake_lock lock=%d id='%s'\n", lock, id);  
  7.   
  8.     if (g_error) return g_error;  
  9.   
  10.     int fd;  
  11.   
  12.     if (lock == PARTIAL_WAKE_LOCK) {  
  13.         fd = g_fds[ACQUIRE_PARTIAL_WAKE_LOCK];  
  14.     }  
  15.     else {  
  16.         return EINVAL;  
  17.     }  
  18.   
  19.     return write(fd, id, strlen(id));  
  20. }  

3.2 通过回调函数调用并统一接口(新的模式)

1 源码路径:\hardware\libhardware

2 模式简介:hardware.c和hardware.h(hardware\libhardware\include\hardware)提供了使用这种模式的HAL的方式,并规定统一接口。上层通过hardware.c中的函数hw_get_module获取相应module的stub,然后通过stub来访问HAL。

3 接口源码hardware.c和hardware.h说明

(1)Hardware.h用2个结构体规定了统一接口

[cpp] view plaincopyprint?
  1. /** 
  2.  * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM 
  3.  * and the fields of this data structure must begin with hw_module_t 
  4.  * followed by module specific information. 
  5.  */  
  6. typedef struct hw_module_t {  
  7.     /** tag must be initialized to HARDWARE_MODULE_TAG */  
  8.     uint32_t tag;  
  9.   
  10.     /** major version number for the module */  
  11.     uint16_t version_major;  
  12.   
  13.     /** minor version number of the module */  
  14.     uint16_t version_minor;  
  15.   
  16.     /** Identifier of module */  
  17.     const char *id;  
  18.   
  19.     /** Name of this module */  
  20.     const char *name;  
  21.   
  22.     /** Author/owner/implementor of the module */  
  23.     const char *author;  
  24.   
  25.     /** Modules methods */  
  26.     struct hw_module_methods_t* methods;  
  27.   
  28.     /** module's dso */  
  29.     void* dso;  
  30.   
  31.     /** padding to 128 bytes, reserved for future use */  
  32.     uint32_t reserved[32-7];  
  33.   
  34. } hw_module_t;  

由注释可知,每个HAL模块都必须继承这个结构体,继承方式为,定义一个结构体,其第一个元素为hw_module_t,之后是表征自己模块独有的信息的变量。

[cpp] view plaincopyprint?
  1. /** 
  2.  * Every device data structure must begin with hw_device_t 
  3.  * followed by module specific public methods and attributes. 
  4.  */  
  5. typedef struct hw_device_t {  
  6.     /** tag must be initialized to HARDWARE_DEVICE_TAG */  
  7.     uint32_t tag;  
  8.   
  9.     /** version number for hw_device_t */  
  10.     uint32_t version;  
  11.   
  12.     /** reference to the module this device belongs to */  
  13.     struct hw_module_t* module;  
  14.   
  15.     /** padding reserved for future use */  
  16.     uint32_t reserved[12];  
  17.   
  18.     /** Close this device */  
  19.     int (*close)(struct hw_device_t* device);  
  20.   
  21. } hw_device_t;  

由注释可知,每个HAL模块必须继承这个结构体,继承方式类似地,定义一个结构体,其第一个元素为hw_device_t,之后是自己模块独有的方法和属性。

(2)hardware.c使用hw_get_module函数,通过id查找并加载相应HAL模块,并获得相应模块的Stub。相关的解释见这篇文章http://my.unix-center.net/~Simon_fu/?p=630。

4 实例:overlay

Service层:DisplayHardware.cpp(frameworks\base\services\surfaceflinger\displayhardware)

[cpp] view plaincopyprint?
  1. void DisplayHardware::init(uint32_t dpy)  
  2. {  
  3.     mNativeWindow = new FramebufferNativeWindow();  
  4.     framebuffer_device_t const * fbDev = mNativeWindow->getDevice();  
  5.     mDpiX = mNativeWindow->xdpi;  
  6.     mDpiY = mNativeWindow->ydpi;  
  7.     mRefreshRate = fbDev->fps;  
  8.   
  9.     mOverlayEngine = NULL;  
  10.     hw_module_t const* module;  
  11.     if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {  
  12.         overlay_control_open(module, &mOverlayEngine);  
  13.     }  
  14.     ....  
  15. }  

HAL层:Overlay.h(hardware\libhardware\include\hardware)

[cpp] view plaincopyprint?
  1. /** 
  2.  * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM 
  3.  * and the fields of this data structure must begin with hw_module_t 
  4.  * followed by module specific information. 
  5.  */  
  6. struct overlay_module_t {  
  7.     struct hw_module_t common;  
  8. };  

[cpp] view plaincopyprint?
  1. /** 
  2.  * Every device data structure must begin with hw_device_t 
  3.  * followed by module specific public methods and attributes. 
  4.  */  
  5.   
  6. struct overlay_control_device_t {  
  7.     struct hw_device_t common;  
  8.       
  9.     /* get static informations about the capabilities of the overlay engine */  
  10.     int (*get)(struct overlay_control_device_t *dev, int name);  
  11.   
  12.     /* creates an overlay matching the given parameters as closely as possible. 
  13.      * returns an error if no more overlays are available. The actual 
  14.      * size and format is returned in overlay_t. */  
  15.     overlay_t* (*createOverlay)(struct overlay_control_device_t *dev,  
  16.             uint32_t w, uint32_t h, int32_t format);  
  17.       
  18.     /* destroys an overlay. This call releases all 
  19.      * resources associated with overlay_t and make it invalid */  
  20.     void (*destroyOverlay)(struct overlay_control_device_t *dev,  
  21.             overlay_t* overlay);  
  22.   
  23.     /* set position and scaling of the given overlay as closely as possible. 
  24.      * if scaling cannot be performed, overlay must be centered. */  
  25.     int (*setPosition)(struct overlay_control_device_t *dev,  
  26.             overlay_t* overlay,   
  27.             int x, int y, uint32_t w, uint32_t h);  
  28.   
  29.     /* returns the actual position and size of the overlay */  
  30.     int (*getPosition)(struct overlay_control_device_t *dev,  
  31.             overlay_t* overlay,   
  32.             int* x, int* y, uint32_t* w, uint32_t* h);  
  33.   
  34.     /* sets configurable parameters for this overlay. returns an error if not 
  35.      * supported. */  
  36.     int (*setParameter)(struct overlay_control_device_t *dev,  
  37.             overlay_t* overlay, int param, int value);  
  38.   
  39.     int (*stage)(struct overlay_control_device_t *dev, overlay_t* overlay);  
  40.     int (*commit)(struct overlay_control_device_t *dev, overlay_t* overlay);  
  41. };  

Overlay.cpp (hardware\libhardware\modules\overlay)

[cpp] view plaincopyprint?
  1. static int overlay_device_open(const struct hw_module_t* module, const char* name,  
  2.         struct hw_device_t** device);  
  3.   
  4. static struct hw_module_methods_t overlay_module_methods = {  
  5.     open: overlay_device_open  
  6. };  
  7.   
  8. struct overlay_module_t HAL_MODULE_INFO_SYM = {  
  9.     common: {  
  10.         tag: HARDWARE_MODULE_TAG,  
  11.         version_major: 1,  
  12.         version_minor: 0,  
  13.         id: OVERLAY_HARDWARE_MODULE_ID,  
  14.         name: "Sample Overlay module",  
  15.         author: "The Android Open Source Project",  
  16.         methods: &overlay_module_methods,  
  17.     }  
  18. };  

4 后记

在理解HAL的时候,2种模式的区别万不可纠结于上层是用JNI调用,manager调用,还是用service调用,mokoid在这方面也许会造成一些误导。其关键为:旧的模式为直接调用,新的模式为通过hw_get_module获取到相应HAL模块的stub,以回调的方式进行调用。

5 Reference

http://android.tgbus.com/Android/tutorial/201104/350065.shtml

http://blog.csdn.net/k229650014/article/details/5801397

http://my.unix-center.net/~Simon_fu/?p=630

原创粉丝点击