HAL的全称是Hardware Abstraction Layer, 即硬件抽象层。


HAL层是介于Android内核与上层之间抽象出来的一层结构,它是对linux驱动的一个封装,对上层提供统一接口,上层应用不必知道下层是如何实现的,它屏蔽了底层的实现细节。


1. HAL的由来

Android的HAL是为了保护一些硬件提供商的知识产权而提出的,是为了避开linux的GPL束缚。思路是把控制硬件的动作都放到了Android HAL中,而linux driver仅仅完成一些简单的数据交互作用,甚至把硬件寄存器空间直接映射到user space。而Android是基于Aparch的license,因此硬件厂商可以只提供二进制代码,所以说Android只是一个开放的平台,并不是一个开源的平台。也许也正是因为Android不遵从GPL,所以Greg Kroah-Hartman才在2.6.33内核将Andorid驱动从linux中删除。GPL和硬件厂商目前还是有着无法弥合的裂痕。Android想要把这个问题处理好也是不容易的。

总结下来,Android HAL存在的原因主要有:

(1). 并不是所有的硬件设备都有标准的linux kernel的接口

(2). KERNEL DRIVER涉及到GPL的版权。某些设备制造商并不愿意公开硬件驱动,所以才去用HAL方式绕过GPL。

(3). 针对某些硬件,An有一些特殊的需求


2. HAL的演进

HAL以前是以module来被调用的。所谓module,就是将c文件编译成so文件,然后在jni中加载调用。此种方式现在在源码的libhardware_legacy文件夹下。后来HAL的架构改变,变成了以stub的形式来被上层调用。这样就有种面向对象的思想了。虽然也是编译成so文件然后加载,但是JNI是直接调用c对象。这种层次更清晰,而且更易于维护和扩展。


3. 源码目录

hardware/libhardware/include/hardware/gps.h

hardware/qcom/gps/loc_api/gps.c


其中gps.h中定义了GPS相关的结构体接口,在“重要结构体及接口”中已经介绍,在此不再赘述。

我们来看一下gps.c文件:

首先定义了gps设备模块实例,下面的注释很重要,说明了如何构建一个模块,这是Android中标准的构建模块写法。

/*** Every hardware module must have a data structure named HAL_MODULE_INFO_SYM* and the fields of this data structure must begin with hw_module_t* followed by module specific information.*/struct hw_module_t HAL_MODULE_INFO_SYM = {    .tag = HARDWARE_MODULE_TAG,    .module_api_version = 1,    .hal_api_version = 0,    .id = GPS_HARDWARE_MODULE_ID,    .name = "loc_api GPS Module",    .author = "Qualcomm USA, Inc.",    .methods = &gps_module_methods,};

这里的id用来指定模块库文件名的,methods指向gps.c文件中的gps_module_methods:
static struct hw_module_methods_t gps_module_methods = {    .open = open_gps};

gps_module_methods定义了设备的open函数为open_gps,我们来看open_gps函数:
static int open_gps(const struct hw_module_t* module, char const* name,        struct hw_device_t** device){    struct gps_device_t *dev = (struct gps_device_t *) malloc(sizeof(struct gps_device_t));    if(dev == NULL)        return -1;    memset(dev, 0, sizeof(*dev));    dev->common.tag = HARDWARE_DEVICE_TAG;    dev->common.version = 0;    dev->common.module = (struct hw_module_t*)module;    dev->get_gps_interface = gps__get_gps_interface;    *device = (struct hw_device_t*)dev;    return 0;}

此处可以看作是GPS设备的初始化函数,在使用设备前必须执行此函数。函数里面指定了hw_device_tmodule成员,以及gps_device_tget_gps_interface成员。上层可通过gps_device_tget_gps_interface调用gps__get_gps_interface函数。gps__get_gps_interface的定义如下:

const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev){    return get_gps_interface();}

get_gps_interface的实现是在gps/loc_api/Loc.cpp:
// for gps.cextern "C" const GpsInterface* get_gps_interface(){    unsigned int target = TARGET_DEFAULT;    loc_eng_read_config();    target = loc_get_target();    LOC_LOGD("Target name check returned %s", loc_get_target_name(target));    int gnssType = getTargetGnssType(target);    switch (gnssType)    {    case GNSS_GSS:        //APQ8064        gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB);        gss_fd = open("/dev/gss", O_RDONLY);        if (gss_fd < 0) {            LOC_LOGE("GSS open failed: %s\n", strerror(errno));        }        else {            LOC_LOGD("GSS open success! CAPABILITIES %0lx\n",                     gps_conf.CAPABILITIES);        }        break;    case GNSS_NONE:        //MPQ8064        LOC_LOGE("No GPS HW on this target. Not returning interface.");        return NULL;    case GNSS_QCA1530:        // qca1530 chip is present        gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB);        LOC_LOGD("qca1530 present: CAPABILITIES %0lx\n", gps_conf.CAPABILITIES);        break;    }    return &sLocEngInterface;}
sLocEngInterface的定义如下:
// Defines the GpsInterface in gps.hstatic const GpsInterface sLocEngInterface ={   sizeof(GpsInterface),   loc_init,   loc_start,   loc_stop,   loc_cleanup,   loc_inject_time,   loc_inject_location,   loc_delete_aiding_data,   loc_set_position_mode,   loc_get_extension};

sLocEngInterface 指定了GpsInterface结构体的各个回调函数,如启动定位/取消定位等,这些回调函数的实现均在Loc.cpp中实现。

更多相关文章

  1. android 4.04的应用程序启动过程及与Zygote的交互(基于静态源码分
  2. 重新审视 Android
  3. Android(安卓)照相机
  4. Android中JNI编程的那些事儿 【转】
  5. Android平台开发-Android(安卓)HAL develop-Android(安卓)HAL开
  6. Android(安卓)关机流程分析-----(1)Framework层
  7. android adb命令
  8. Android(安卓)JNI
  9. 箭头函数的基础使用

随机推荐

  1. android 结合源码深入剖析AsyncTask机制
  2. 播放器适配经验总结――Android
  3. 饺子播放器、IjkVideoView播放器的简单使
  4. Android(安卓)-- PullToRefresh应用
  5. Android六大优势
  6. Android流媒体
  7. Android布局优化之TextView、ImageView合
  8. Android中native进程内存泄露的调试技巧
  9. 别再问我Android前景如何
  10. android 中一个工程引用另一个工程