前面,带着大家一起写了一个temperature sensor的驱动,已经一个测试tool来测试这个驱动,基本功能已经ok,若还有问题的可以参考前面2篇文章,在这里我们要在HAL层中添加我们的设备,来跟framework中的代码连接起来。
在开始摆代码之前我觉得有必要啰嗦几句,HAL层我个人觉得是个比较重要的东西,虽然这边现在还不是很成熟,还不是很规范,但是google还是做了很大力气针对HAL的。
首先来介绍一下android HAL 层,
Android的硬件抽象层,简单来说,就是对Linux内核驱动程序的封装,向上提供接口,屏蔽低层的实现细节。也就是说,把对硬件的支持分成了两层,一层放在用户空间(User Space),一层放在内核空间(Kernel Space),其中,硬件抽象层运行在用户空间,而Linux内核驱动程序运行在内核空间。
这个是google定义的android整个系统的架构,大家可以看到HAL层起了一个承上启下的作用,HAL层主要是针对一些传感器和一些个硬件而存在的,其实也可以绕过HAL层直接使用JNI来实现从驱动到framework这个过程,但是我们这里主要是讲android中的sensor,针对标准的android而言,sensor都是在HAL中添加的,个人理解还是呼应硬件厂商的建议吧,毕竟这部分代码还可以不开源的。
好了,开源不开源什么的,我是不去关心,对我影响不大,我们还是接着看HAL。
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;
好,接下来看下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, { }},
- //-----------
- };
- 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;
- }
这里我要提醒大家,如果对自己不够有信心的话第一次写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这个动态库的,然后找到这个库里的一些回调函数,怎么找呢?
- 看下这句话:
- <pre name="code" class="cpp" style="background-color: rgb(255, 255, 255); "><pre name="code" class="cpp"> /* Get the address of the struct hal_module_info. */
- const char *sym = HAL_MODULE_INFO_SYM_AS_STR;</pre>
- <pre></pre>
- <pre></pre>
- <p></p>
- <pre></pre>
- <pre name="code" class="cpp" style="background-color: rgb(255, 255, 255); "> HAL_MODULE_INFO_SYM_AS_STR;是一个宏,被定义在hardware.h中:</pre><pre name="code" class="cpp" style="background-color: rgb(255, 255, 255); "><pre name="code" class="cpp">#define HAL_MODULE_INFO_SYM_AS_STR "HMI"</pre>好了,就是找HMI这个字串,我们可以用readelf命令查看下sensor.glodfish.so里面的symbol:
- <pre></pre>
- <pre name="code" class="cpp" style="background-color: rgb(255, 255, 255); "><pre name="code" class="cpp">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</pre><pre name="code" class="cpp" style="background-color: rgb(255, 255, 255); "></pre>大家可以看到这里的第25行,OK 找到了,这里找到了这个动态库的地址,然后就可以一次找到这个动态库中的函数,最终可以被调用。<br>
- <br>
- 结束语:
- <pre></pre>
- <pre name="code" class="cpp" style="background-color: rgb(255, 255, 255); ">这里我只是大致分析了一下这个流程,对于代码是如何编写的,大家可以参考我提供的下载,其实android hal层就是填充一些“规则”。</pre><pre name="code" class="cpp" style="background-color: rgb(255, 255, 255); ">下面一节我们来编写一个测试apk来抓我们的温度,之后再来分析framework层,因为到这里我们sensor的移植就结束了,framework层中android已经帮我们把api都写好了,也就是说sensor是android的标准api,我们不需要自己去搭建。</pre>
- <pre></pre>
- <p></p>
- <pre></pre>
- <pre></pre>
- </pre></pre></pre>