Android GPS学习笔记(4)—HAL实现

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中标准的构建模块写法。

[cpp]  view plain copy
  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 hw_module_t HAL_MODULE_INFO_SYM = {  
  7.     .tag = HARDWARE_MODULE_TAG,  
  8.     .module_api_version = 1,  
  9.     .hal_api_version = 0,  
  10.     .id = GPS_HARDWARE_MODULE_ID,  
  11.     .name = "loc_api GPS Module",  
  12.     .author = "Qualcomm USA, Inc.",  
  13.     .methods = &gps_module_methods,  
  14. };  

这里的id用来指定模块库文件名的,methods指向gps.c文件中的gps_module_methods:
[cpp]  view plain copy
  1. static struct hw_module_methods_t gps_module_methods = {  
  2.     .open = open_gps  
  3. };  

gps_module_methods定义了设备的open函数为open_gps,我们来看open_gps函数:
[cpp]  view plain copy
  1. static int open_gps(const struct hw_module_t* module, char const* name,  
  2.         struct hw_device_t** device)  
  3. {  
  4.     struct gps_device_t *dev = (struct gps_device_t *) malloc(sizeof(struct gps_device_t));  
  5.   
  6.     if(dev == NULL)  
  7.         return -1;  
  8.   
  9.     memset(dev, 0, sizeof(*dev));  
  10.   
  11.     dev->common.tag = HARDWARE_DEVICE_TAG;  
  12.     dev->common.version = 0;  
  13.     dev->common.module = (struct hw_module_t*)module;  
  14.     dev->get_gps_interface = gps__get_gps_interface;  
  15.   
  16.     *device = (struct hw_device_t*)dev;  
  17.     return 0;  
  18. }  

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

[cpp]  view plain copy
  1. const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)  
  2. {  
  3.     return get_gps_interface();  
  4. }  

get_gps_interface的实现是在gps/loc_api/Loc.cpp:
[cpp]  view plain copy
  1. // for gps.c  
  2. extern "C" const GpsInterface* get_gps_interface()  
  3. {  
  4.     unsigned int target = TARGET_DEFAULT;  
  5.     loc_eng_read_config();  
  6.   
  7.     target = loc_get_target();  
  8.     LOC_LOGD("Target name check returned %s", loc_get_target_name(target));  
  9.   
  10.     int gnssType = getTargetGnssType(target);  
  11.     switch (gnssType)  
  12.     {  
  13.     case GNSS_GSS:  
  14.         //APQ8064  
  15.         gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB);  
  16.         gss_fd = open("/dev/gss", O_RDONLY);  
  17.         if (gss_fd < 0) {  
  18.             LOC_LOGE("GSS open failed: %s\n", strerror(errno));  
  19.         }  
  20.         else {  
  21.             LOC_LOGD("GSS open success! CAPABILITIES %0lx\n",  
  22.                      gps_conf.CAPABILITIES);  
  23.         }  
  24.         break;  
  25.     case GNSS_NONE:  
  26.         //MPQ8064  
  27.         LOC_LOGE("No GPS HW on this target. Not returning interface.");  
  28.         return NULL;  
  29.     case GNSS_QCA1530:  
  30.         // qca1530 chip is present  
  31.         gps_conf.CAPABILITIES &= ~(GPS_CAPABILITY_MSA | GPS_CAPABILITY_MSB);  
  32.         LOC_LOGD("qca1530 present: CAPABILITIES %0lx\n", gps_conf.CAPABILITIES);  
  33.         break;  
  34.     }  
  35.     return &sLocEngInterface;  
  36. }  
sLocEngInterface的定义如下:
[cpp]  view plain copy
  1. // Defines the GpsInterface in gps.h  
  2. static const GpsInterface sLocEngInterface =  
  3. {  
  4.    sizeof(GpsInterface),  
  5.    loc_init,  
  6.    loc_start,  
  7.    loc_stop,  
  8.    loc_cleanup,  
  9.    loc_inject_time,  
  10.    loc_inject_location,  
  11.    loc_delete_aiding_data,  
  12.    loc_set_position_mode,  
  13.    loc_get_extension  
  14. };  

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


原文:http://blog.csdn.net/dreamback1987/article/details/46605943

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值