Android模拟器学framework和driver之传感器篇3(Android HAL)

前面,带着大家一起写了一个temperature sensor的驱动,已经一个测试tool来测试这个驱动,基本功能已经ok,若还有问题的可以参考前面2篇文章,在这里我们要在HAL层中添加我们的设备,来跟framework中的代码连接起来。

在开始摆代码之前我觉得有必要啰嗦几句,HAL层我个人觉得是个比较重要的东西,虽然这边现在还不是很成熟,还不是很规范,但是google还是做了很大力气针对HAL的。

首先来介绍一下android HAL 层,

Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),其中,硬件抽象层运行在用户空间,而Linux内核驱动程序运行在内核空间。
下图为整个android 架构:


这个是google定义的android整个系统的架构,大家可以看到HAL层起了一个承上启下的作用,HAL层主要是针对一些传感器和一些个硬件而存在的,其实也可以绕过HAL层直接使用JNI来实现从驱动到framework这个过程,但是我们这里主要是讲android中的sensor,针对标准的android而言,sensor都是在HAL中添加的,个人理解还是呼应硬件厂商的建议吧,毕竟这部分代码还可以不开源的。

好了,开源不开源什么的,我是不去关心,对我影响不大,我们还是接着看HAL。

Android硬件抽象层,从下到上涉及到了Android系统的硬件驱动层、硬件抽象层、运行时库和应用程序框架层等等,下图描述了硬件抽象层在Android系统中的位置,以及它和其它层的关系:


现在的 libhardware 作法,使用了stub的概念。stub 虽然仍是以 *.so 檔的形式存在,但 HAL 已经将 *.so 档隐藏起来了。Stub 向 HAL提供操作函数(operations),而 runtime 则是向 HAL 取得特定模块(stub)的 operations,再 callback 这些操作函数。
HAL的实现主要在hardware.c和hardware.h文件中。实质也是通过加载 *.so 库。从而呼叫 *.so 里的符号(symbol)实现。

--------------------------------------------------------------------------------------------------------------------------------------------------------------

到此,都是些理论的东西,实在是不想讲这些条条杠杠的,从小语文就不好的我,最讨厌的就是这些理论的东西了,实践才是真理呢。。。

好了接下来轮到我们的sensor的HAL层了,这里先列出来主要用到的代码:

。。。。。。

讲漏了,这边sensor的HAL层代码我参考的是freescale的BSP,因为个人感觉比较容易懂,哈哈。

先给下载链接,不然大家看不到完整的代码。

http://download.csdn.net/detail/zhangjie201412/4039312

代码目录如下:

sensor/
├── AccelSensor.cpp
├── AccelSensor.h
├── Android.mk
├── InputEventReader.cpp
├── InputEventReader.h
├── LightSensor.cpp
├── LightSensor.h
├── SensorBase.cpp
├── SensorBase.h
├── sensors.cpp
├── sensors.h
├── TemperatureSensor.cpp
└── TemperatureSensor.h

这里我们要修改以及添加的是三个文件:

sensor.cpp TemperatureSensor.cpp TemperatureSensor.h

好了,接下来就带大家分析下android sensor的HAL层!!!

先看一下/hardware/libhareware/hardware.c和/hardware/libhardware/include/hardware/hardware.h

这2个文件是android hal层最重要的两个文件,其中定义了hal层主要要实现的3个结构体,

struct hw_module_t; struct hw_module_methods_t; struct hw_device_t; /** * 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. */ 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; /** 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; 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; /** * Every device data structure must begin with hw_device_t * followed by module specific public methods and attributes. */ 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; 其实标准的android hal就是实现这3个结构体,然后设置一些回调函数,最后把数据poll到framework中。

好,接下来看下sensor中是怎么封装的:

在/hardware/libhardware/include/hardware/sensors.h 中定义了几个结构体,其中都包含了上面的3个结构体,所以我们sensor module只需要去实现sensor.h中的这几个就OK了。

下面提一下如何添加我们的temperature sensor,首先是hardware/libhardware/modules/sensor/sensors.cpp 中sensor list中添加我们的sensor的信息,

/* The SENSORS Module */ static const struct sensor_t sSensorList[] = { { "Analog Devices ADXL345/6 3-axis Accelerometer", "ADI", 1, SENSORS_ACCELERATION_HANDLE, SENSOR_TYPE_ACCELEROMETER, RANGE_A, CONVERT_A, 0.145f, 200, { } }, //20000 { "Android Light sensor", "Android", 1, SENSORS_LIGHT_HANDLE, SENSOR_TYPE_LIGHT, 16000.0f, 1.0f, 0.35f, 0, { } }, //++++++add by Jay for temperature sensor { "Android Temperature Sensor", "Android", 1, SENSORS_TEMPERATURE_HANDLE, SENSOR_TYPE_TEMPERATURE, 100.0f, 1.0f, 1.0f,0, { }}, //----------- };这里面的Android Temperature Sensor就是我们自己添加的sensor,然后我们去实现我们的temperature sensor的功能,也就是填充一些结构体和实现一些回调函数,这里我挑重要的讲。

int TemperatureSensor::readEvents(sensors_event_t* data, int count) { if(count<1) return -EINVAL; if(mHasPendingEvent){ mHasPendingEvent = false; mPendingEvent.timestamp = getTimestamp(); *data = mPendingEvent; return mEnabled ? 1:0; } ssize_t n = mInputReader.fill(data_fd); if(n<0) return n; int numEventReceived = 0; input_event const* event; DEBUG("count: %d\n",count); while(count && mInputReader.readEvent(&event)){ int fd=open("/dev/input/event1", O_RDONLY); if(fd<0){ DEBUG("readEvents: open event2 failed...\n"); return fd; } int ret=read(fd,&event,sizeof(event)); if(ret<sizeof(event)){ DEBUG("readEvent read failed....\n"); return ret; } close(fd); int type=event->type; if(type == EV_ABS){ DEBUG("Current Temp: %d\n",event->value); mPendingEvent.temperature = (float)(event->value); }else if(type==EV_SYN){ mPendingEvent.timestamp = timevalToNano(event->time); if(/*mEnabled &&*/ (mPendingEvent.temperature != mPreviousTemperature)){ *data++ = mPendingEvent; count--; numEventReceived++; mPreviousTemperature = mPendingEvent.temperature; DEBUG("Current Temp: %d\n",(int)mPendingEvent.temperature); } }else DEBUG("temperature : unknow event...\n"); mInputReader.next(); } return numEventReceived; }大家看了Temperature.cpp就应该知道我这里实现HAL层poll数据最主要的就是上面这个函数,这边其实就是linux的应用层的写法,open input 节点,然后read data,在poll给framework层。

这里我要提醒大家,如果对自己不够有信心的话第一次写hal层代码的时候最好多加点debug message,因为在hal层的调试比较麻烦,出现的错误会直接导致系统不断重启,不会告诉你错哪,所以,最好自己加debug message来调试。

代码方面大家可以看下Temperature.h和sensor.cpp这两个文件里面要实现的一些类和结构体,按照规范写好回调函数就ok了,大家自行分析绰绰有余。

还有就是这里的makefile,会把module编译成sensor.goldfish.so,给framework调用,ok来讲一下framework是如何调用HAL层里面的API的,

大家可以看下android源码下面的frameworks/base/services/sensorservice/SensorDevice.cpp

SensorDevice::SensorDevice() : mSensorDevice(0), mSensorModule(0) { status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); LOGE_IF(err, "couldn't load %s module (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); if (mSensorModule) { err = sensors_open(&mSensorModule->common, &mSensorDevice); LOGE_IF(err, "couldn't open device for module %s (%s)", SENSORS_HARDWARE_MODULE_ID, strerror(-err)); if (mSensorDevice) { sensor_t const* list; ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list); mActivationCount.setCapacity(count); Info model; for (size_t i=0 ; i<size_t(count) ; i++) { mActivationCount.add(list[i].handle, model); mSensorDevice->activate(mSensorDevice, list[i].handle, 0); } } } }
这里调用了status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule);

这个函数在哪呢?在这:

hardware/libhardware/hardware.c里的

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]; /* * Here we rely on the fact that calling dlopen multiple times on * the same .so will simply increment a refcount (and not load * a new copy of the library). * We also assume that dlopen() is thread-safe. */ /* Loop through the configuration variants looking for a module */ 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_PATH1, id, prop); if (access(path, R_OK) == 0) break; snprintf(path, sizeof(path), "%s/%s.%s.so", HAL_LIBRARY_PATH2, id, prop); if (access(path, R_OK) == 0) break; } else { snprintf(path, sizeof(path), "%s/%s.default.so", HAL_LIBRARY_PATH1, id); if (access(path, R_OK) == 0) break; } } 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; }
这里首先把要get的module的名字传进去,然后找到sensor.goldfish.so,但是怎么去加载这个binary呢?

看下这里的load函数:

/** * Load the file defined by the variant and if successful * return the dlopen handle and the hmi. * @return 0 = success, !0 = failure. */ static int load(const char *id, const char *path, const struct hw_module_t **pHmi) { int status; void *handle; struct hw_module_t *hmi; /* * load the symbols resolving undefined symbols before * dlopen returns. Since RTLD_GLOBAL is not or'd in with * RTLD_NOW the external symbols will not be global */ handle = dlopen(path, RTLD_NOW); if (handle == NULL) { char const *err_str = dlerror(); LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown"); status = -EINVAL; goto done; } /* Get the address of the struct hal_module_info. */ const char *sym = HAL_MODULE_INFO_SYM_AS_STR; hmi = (struct hw_module_t *)dlsym(handle, sym); if (hmi == NULL) { LOGE("load: couldn't find symbol %s", sym); status = -EINVAL; goto done; } /* Check that the id matches */ if (strcmp(id, hmi->id) != 0) { LOGE("load: id=%s != hmi->id=%s", id, hmi->id); status = -EINVAL; goto done; } hmi->dso = handle; /* success */ status = 0; done: if (status != 0) { hmi = NULL; if (handle != NULL) { dlclose(handle); handle = NULL; } } else { LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p", id, path, *pHmi, handle); } *pHmi = hmi; return status; } handle = dlopen(path, RTLD_NOW);这个函数是用来打开找到的sensor.goldfish.so这个动态库的,然后找到这个库里的一些回调函数,怎么找呢?看下这句话:
    /* Get the address of the struct hal_module_info. */
    const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
 
 

 HAL_MODULE_INFO_SYM_AS_STR;是一个宏,被定义在hardware.h中: 
#define HAL_MODULE_INFO_SYM_AS_STR  "HMI"
好了,就是找HMI这个字串,我们可以用readelf命令查看下sensor.glodfish.so里面的symbol:
 
root@jay:/home/jay/android/android2.3.3# readelf -s out/target/product/generic/system/lib/hw/sensors.goldfish.so 

Symbol table '.dynsym' contains 118 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr0
     2: 00001a29    44 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_f2iz
     4: 00001a5d   364 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context
     5: 00000000     0 FUNC    GLOBAL DEFAULT  UND poll
     6: 00000000     0 FUNC    GLOBAL DEFAULT  UND __errno
     7: 00000000     0 FUNC    GLOBAL DEFAULT  UND strerror
     8: 00000000     0 FUNC    GLOBAL DEFAULT  UND __android_log_print
     9: 00000000     0 FUNC    GLOBAL DEFAULT  UND read
    10: 00001bd1   120 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context
    11: 00000000     0 FUNC    GLOBAL DEFAULT  UND write
    12: 00001c51    42 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context
    13: 00000000     0 FUNC    GLOBAL DEFAULT  UND close
    14: 00000000     0 FUNC    GLOBAL DEFAULT  UND _ZdlPv
    15: 00001c95    42 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context
    16: 00001cc1   216 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context
    17: 00000000     0 FUNC    GLOBAL DEFAULT  UND _Znwj
    18: 00002455   124 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorC1Ev
    19: 00002af1   288 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorC1Ev
    20: 00002fd5   108 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorC1E
    21: 00000000     0 FUNC    GLOBAL DEFAULT  UND pipe
    22: 00000000     0 FUNC    GLOBAL DEFAULT  UND fcntl
    23: 00000000     0 FUNC    GLOBAL DEFAULT  UND memset
    24: 00001ded   216 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context
    25: 0000432c   132 OBJECT  GLOBAL DEFAULT   16 HMI
    26: 00001ec5    24 FUNC    GLOBAL DEFAULT    7 _ZNK10SensorBase5getFdEv
    27: 00001edd     4 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase8setDelayE
    28: 00001ee1     4 FUNC    GLOBAL DEFAULT    7 _ZNK10SensorBase16hasPend
    29: 00001ee5    32 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase12close_de
    30: 00001f05    60 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseD1Ev
    31: 000040e8    36 OBJECT  GLOBAL DEFAULT   13 _ZTV10SensorBase
    32: 00001f41    60 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseD2Ev
    33: 00001f7d   312 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase9openInput
    34: 00000000     0 FUNC    GLOBAL DEFAULT  UND opendir
    35: 00000000     0 FUNC    GLOBAL DEFAULT  UND strcpy
    36: 00000000     0 FUNC    GLOBAL DEFAULT  UND strlen
    37: 00000000     0 FUNC    GLOBAL DEFAULT  UND open
    38: 00000000     0 FUNC    GLOBAL DEFAULT  UND ioctl
    39: 00000000     0 FUNC    GLOBAL DEFAULT  UND strcmp
    40: 00000000     0 FUNC    GLOBAL DEFAULT  UND readdir
    41: 00000000     0 FUNC    GLOBAL DEFAULT  UND closedir
    42: 00000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail
    43: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __stack_chk_guard
    44: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr1
    45: 000020b5    68 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseC1EPKcS1_
    46: 000020f9    68 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseC2EPKcS1_
    47: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_lmul
    48: 00002141    56 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase12getTimes
    49: 00000000     0 FUNC    GLOBAL DEFAULT  UND clock_gettime
    50: 00002179    80 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase11open_dev
    51: 000021c9    18 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseD0Ev
    52: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_pure_virtual
    53: 000021dd     4 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensor8setDelay
    54: 000021e1    24 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensor6enableEi
    55: 000021f9    12 FUNC    GLOBAL DEFAULT    7 _ZNK11LightSensor16hasPen
    56: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_i2f
    57: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_fcmpeq
    58: 00002209   432 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensor10readEve
    59: 00000000     0 FUNC    GLOBAL DEFAULT  UND memcpy
    60: 000030dd    96 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe
    61: 000030c5    24 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe
    62: 000030ad    22 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe
    63: 000023b9    68 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorD1Ev
    64: 0000313d    18 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe
    65: 00004110    36 OBJECT  GLOBAL DEFAULT   13 _ZTV11LightSensor
    66: 000023fd    18 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorD0Ev
    67: 00002411    68 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorD2Ev
    68: 00003165    30 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe
    69: 000024d1   124 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorC2Ev
    70: 0000254d    48 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor6enableEi
    71: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_fmul
    72: 0000257d   120 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor12process
    73: 000025f9   308 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor10readEve
    74: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_ldivmod
    75: 00002731   216 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor8setDelay
    76: 00000000     0 FUNC    GLOBAL DEFAULT  UND fopen
    77: 00000000     0 FUNC    GLOBAL DEFAULT  UND snprintf
    78: 00000000     0 FUNC    GLOBAL DEFAULT  UND fwrite
    79: 00000000     0 FUNC    GLOBAL DEFAULT  UND fclose
    80: 00002809   628 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor11getPoll
    81: 00000000     0 FUNC    GLOBAL DEFAULT  UND strncmp
    82: 00000000     0 FUNC    GLOBAL DEFAULT  UND strcat
    83: 00000000     0 FUNC    GLOBAL DEFAULT  UND fread
    84: 00000000     0 FUNC    GLOBAL DEFAULT  UND strtol
    85: 00002a7d    48 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorD1Ev
    86: 00004138    36 OBJECT  GLOBAL DEFAULT   13 _ZTV11AccelSensor
    87: 00002aad    18 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorD0Ev
    88: 00002ac1    48 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorD2Ev
    89: 00002c11   288 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorC2Ev
    90: 00002d31     4 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensor8se
    91: 00002d35    24 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensor6en
    92: 00002d4d    12 FUNC    GLOBAL DEFAULT    7 _ZNK17TemperatureSensor16
    93: 00002d59   488 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensor10r
    94: 00002f41    64 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorD1E
    95: 00004160    36 OBJECT  GLOBAL DEFAULT   13 _ZTV17TemperatureSensor
    96: 00002f81    18 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorD0E
    97: 00002f95    64 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorD2E
    98: 00003041   108 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorC2E
    99: 00000000     0 FUNC    GLOBAL DEFAULT  UND _ZdaPv
   100: 00003151    18 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe
   101: 00000000     0 FUNC    GLOBAL DEFAULT  UND _Znaj
   102: 00003185    30 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe
   103: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize
   104: 000043c0     0 NOTYPE  GLOBAL DEFAULT   17 __dso_handle
   105: 00004000     0 NOTYPE  GLOBAL DEFAULT   11 __INIT_ARRAY__
   106: 00004008     0 NOTYPE  GLOBAL DEFAULT   12 __FINI_ARRAY__
   107: 000035dc     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_start
   108: 0000371c     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_end
   109: 0000432c     0 NOTYPE  GLOBAL DEFAULT   16 __data_start
   110: 000043b4     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
   111: 000043b4     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
   112: 000043b4     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start__
   113: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS _bss_end__
   114: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_end__
   115: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS __end__
   116: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS _end
   117: 00080000     0 NOTYPE  GLOBAL DEFAULT  ABS _stack
大家可以看到这里的第25行,OK 找到了,这里找到了这个动态库的地址,然后就可以一次找到这个动态库中的函数,最终可以被调用。

结束语:
 这里我只是大致分析了一下这个流程,对于代码是如何编写的,大家可以参考我提供的下载,其实android hal层就是填充一些“规则”。下面一节我们来编写一个测试apk来抓我们的温度,之后再来分析framework层,因为到这里我们sensor的移植就结束了,framework层中android已经帮我们把api都写好了,也就是说sensor是android的标准api,我们不需要自己去搭建。 
 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值