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

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个结构体,

  1. struct hw_module_t;  
  2. struct hw_module_methods_t;  
  3. struct hw_device_t;  
  4.   
  5. /** 
  6.  * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM 
  7.  * and the fields of this data structure must begin with hw_module_t 
  8.  * followed by module specific information. 
  9.  */  
  10. typedef struct hw_module_t {  
  11.     /** tag must be initialized to HARDWARE_MODULE_TAG */  
  12.     uint32_t tag;  
  13.   
  14.     /** major version number for the module */  
  15.     uint16_t version_major;  
  16.   
  17.     /** minor version number of the module */  
  18.     uint16_t version_minor;  
  19.   
  20.     /** Identifier of module */  
  21.     const char *id;  
  22.   
  23.     /** Name of this module */  
  24.     const char *name;  
  25.   
  26.     /** Author/owner/implementor of the module */  
  27.     const char *author;  
  28.   
  29.     /** Modules methods */  
  30.     struct hw_module_methods_t* methods;  
  31.   
  32.     /** module's dso */  
  33.     void* dso;  
  34.   
  35.     /** padding to 128 bytes, reserved for future use */  
  36.     uint32_t reserved[32-7];  
  37.   
  38. } hw_module_t;  
  39.   
  40. typedef struct hw_module_methods_t {  
  41.     /** Open a specific device */  
  42.     int (*open)(const struct hw_module_t* module, const char* id,  
  43.             struct hw_device_t** device);  
  44.   
  45. } hw_module_methods_t;  
  46.   
  47. /** 
  48.  * Every device data structure must begin with hw_device_t 
  49.  * followed by module specific public methods and attributes. 
  50.  */  
  51. typedef struct hw_device_t {  
  52.     /** tag must be initialized to HARDWARE_DEVICE_TAG */  
  53.     uint32_t tag;  
  54.   
  55.     /** version number for hw_device_t */  
  56.     uint32_t version;  
  57.   
  58.     /** reference to the module this device belongs to */  
  59.     struct hw_module_t* module;  
  60.   
  61.     /** padding reserved for future use */  
  62.     uint32_t reserved[12];  
  63.   
  64.     /** Close this device */  
  65.     int (*close)(struct hw_device_t* device);  
  66.   
  67. } hw_device_t;  
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的信息,

  1. /* The SENSORS Module */  
  2. static const struct sensor_t sSensorList[] = {  
  3.         { "Analog Devices ADXL345/6 3-axis Accelerometer",  
  4.           "ADI",  
  5.           1, SENSORS_ACCELERATION_HANDLE,  
  6.           SENSOR_TYPE_ACCELEROMETER, RANGE_A, CONVERT_A, 0.145f, 200, { } },    //20000  
  7.         { "Android Light sensor",  
  8.           "Android",  
  9.           1, SENSORS_LIGHT_HANDLE,  
  10.           SENSOR_TYPE_LIGHT, 16000.0f, 1.0f, 0.35f, 0, { } },  
  11.     //++++++add by Jay for temperature sensor  
  12.     { "Android Temperature Sensor",  
  13.       "Android",  
  14.       1, SENSORS_TEMPERATURE_HANDLE,  
  15.       SENSOR_TYPE_TEMPERATURE, 100.0f, 1.0f, 1.0f,0, { }},    
  16.     //-----------  
  17. };  
/* 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的功能,也就是填充一些结构体和实现一些回调函数,这里我挑重要的讲。

  1. int TemperatureSensor::readEvents(sensors_event_t* data, int count)  
  2. {  
  3.     if(count<1)  
  4.         return -EINVAL;  
  5.   
  6.     if(mHasPendingEvent){  
  7.         mHasPendingEvent = false;  
  8.         mPendingEvent.timestamp = getTimestamp();  
  9.         *data = mPendingEvent;  
  10.         return mEnabled ? 1:0;  
  11.     }  
  12.     ssize_t n = mInputReader.fill(data_fd);  
  13.     if(n<0)  
  14.         return n;  
  15.   
  16.     int numEventReceived = 0;  
  17.     input_event const* event;  
  18.     DEBUG("count: %d\n",count);  
  19.     while(count && mInputReader.readEvent(&event)){  
  20.         int fd=open("/dev/input/event1", O_RDONLY);  
  21.         if(fd<0){  
  22.             DEBUG("readEvents: open event2 failed...\n");  
  23.             return fd;  
  24.         }  
  25.         int ret=read(fd,&event,sizeof(event));  
  26.         if(ret<sizeof(event)){  
  27.             DEBUG("readEvent read failed....\n");  
  28.             return ret;  
  29.         }  
  30.         close(fd);  
  31.         int type=event->type;  
  32.         if(type == EV_ABS){  
  33.             DEBUG("Current Temp: %d\n",event->value);  
  34.             mPendingEvent.temperature = (float)(event->value);  
  35.         }else if(type==EV_SYN){  
  36.             mPendingEvent.timestamp = timevalToNano(event->time);  
  37.             if(/*mEnabled &&*/ (mPendingEvent.temperature != mPreviousTemperature)){  
  38.                 *data++ = mPendingEvent;  
  39.                 count--;  
  40.                 numEventReceived++;  
  41.                 mPreviousTemperature = mPendingEvent.temperature;  
  42.                 DEBUG("Current Temp: %d\n",(int)mPendingEvent.temperature);  
  43.             }  
  44.         }else  
  45.             DEBUG("temperature : unknow event...\n");  
  46.         mInputReader.next();  
  47.     }  
  48.     return numEventReceived;  
  49. }  
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

  1. SensorDevice::SensorDevice()  
  2.     :  mSensorDevice(0),  
  3.        mSensorModule(0)  
  4. {  
  5.     status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,  
  6.             (hw_module_t const**)&mSensorModule);  
  7.   
  8.     LOGE_IF(err, "couldn't load %s module (%s)",  
  9.             SENSORS_HARDWARE_MODULE_ID, strerror(-err));  
  10.   
  11.     if (mSensorModule) {  
  12.         err = sensors_open(&mSensorModule->common, &mSensorDevice);  
  13.   
  14.         LOGE_IF(err, "couldn't open device for module %s (%s)",  
  15.                 SENSORS_HARDWARE_MODULE_ID, strerror(-err));  
  16.   
  17.         if (mSensorDevice) {  
  18.             sensor_t const* list;  
  19.             ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);  
  20.             mActivationCount.setCapacity(count);  
  21.             Info model;  
  22.             for (size_t i=0 ; i<size_t(count) ; i++) {  
  23.                 mActivationCount.add(list[i].handle, model);  
  24.                 mSensorDevice->activate(mSensorDevice, list[i].handle, 0);  
  25.             }  
  26.         }  
  27.     }  
  28. }  
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);
            }
        }
    }
}

这里调用了
  1. status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,  
  2.             (hw_module_t const**)&mSensorModule);  
status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,
            (hw_module_t const**)&mSensorModule);

这个函数在哪呢?在这:

hardware/libhardware/hardware.c里的

  1. int hw_get_module(const char *id, const struct hw_module_t **module)   
  2. {  
  3.     int status;  
  4.     int i;  
  5.     const struct hw_module_t *hmi = NULL;  
  6.     char prop[PATH_MAX];  
  7.     char path[PATH_MAX];  
  8.   
  9.   
  10.     /* 
  11.      * Here we rely on the fact that calling dlopen multiple times on 
  12.      * the same .so will simply increment a refcount (and not load 
  13.      * a new copy of the library). 
  14.      * We also assume that dlopen() is thread-safe. 
  15.      */  
  16.   
  17.   
  18.     /* Loop through the configuration variants looking for a module */  
  19.     for (i=0 ; i<HAL_VARIANT_KEYS_COUNT+1 ; i++) {  
  20.         if (i < HAL_VARIANT_KEYS_COUNT) {  
  21.             if (property_get(variant_keys[i], prop, NULL) == 0) {  
  22.                 continue;  
  23.             }  
  24.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
  25.                     HAL_LIBRARY_PATH1, id, prop);  
  26.             if (access(path, R_OK) == 0) break;  
  27.   
  28.   
  29.             snprintf(path, sizeof(path), "%s/%s.%s.so",  
  30.                      HAL_LIBRARY_PATH2, id, prop);  
  31.             if (access(path, R_OK) == 0) break;  
  32.         } else {  
  33.             snprintf(path, sizeof(path), "%s/%s.default.so",  
  34.                      HAL_LIBRARY_PATH1, id);  
  35.             if (access(path, R_OK) == 0) break;  
  36.         }  
  37.     }  
  38.   
  39.   
  40.     status = -ENOENT;  
  41.     if (i < HAL_VARIANT_KEYS_COUNT+1) {  
  42.         /* load the module, if this fails, we're doomed, and we should not try 
  43.          * to load a different variant. */  
  44.         status = load(id, path, module);  
  45.     }  
  46.   
  47.   
  48.     return status;  
  49. }  
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函数:

  1. /** 
  2.  * Load the file defined by the variant and if successful 
  3.  * return the dlopen handle and the hmi. 
  4.  * @return 0 = success, !0 = failure. 
  5.  */  
  6. static int load(const char *id,  
  7.         const char *path,  
  8.         const struct hw_module_t **pHmi)  
  9. {  
  10.     int status;  
  11.     void *handle;  
  12.     struct hw_module_t *hmi;  
  13.   
  14.     /* 
  15.      * load the symbols resolving undefined symbols before 
  16.      * dlopen returns. Since RTLD_GLOBAL is not or'd in with 
  17.      * RTLD_NOW the external symbols will not be global 
  18.      */  
  19.     handle = dlopen(path, RTLD_NOW);  
  20.     if (handle == NULL) {  
  21.         char const *err_str = dlerror();  
  22.         LOGE("load: module=%s\n%s", path, err_str?err_str:"unknown");  
  23.         status = -EINVAL;  
  24.         goto done;  
  25.     }  
  26.   
  27.     /* Get the address of the struct hal_module_info. */  
  28.     const char *sym = HAL_MODULE_INFO_SYM_AS_STR;  
  29.     hmi = (struct hw_module_t *)dlsym(handle, sym);  
  30.     if (hmi == NULL) {  
  31.         LOGE("load: couldn't find symbol %s", sym);  
  32.         status = -EINVAL;  
  33.         goto done;  
  34.     }  
  35.   
  36.     /* Check that the id matches */  
  37.     if (strcmp(id, hmi->id) != 0) {  
  38.         LOGE("load: id=%s != hmi->id=%s", id, hmi->id);  
  39.         status = -EINVAL;  
  40.         goto done;  
  41.     }  
  42.   
  43.     hmi->dso = handle;  
  44.   
  45.     /* success */  
  46.     status = 0;  
  47.   
  48.     done:  
  49.     if (status != 0) {  
  50.         hmi = NULL;  
  51.         if (handle != NULL) {  
  52.             dlclose(handle);  
  53.             handle = NULL;  
  54.         }  
  55.     } else {  
  56.         LOGV("loaded HAL id=%s path=%s hmi=%p handle=%p",  
  57.                 id, path, *pHmi, handle);  
  58.     }  
  59.   
  60.     *pHmi = hmi;  
  61.   
  62.     return status;  
  63. }  
/**
 * 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;
}
  1. handle = dlopen(path, RTLD_NOW);这个函数是用来打开找到的sensor.goldfish.so这个动态库的,然后找到这个库里的一些回调函数,怎么找呢?  
  1. 看下这句话:  
看下这句话:
  1. <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. */  
  2.     const char *sym = HAL_MODULE_INFO_SYM_AS_STR;</pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <p></p>  
  6. <pre></pre>  
  7. <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:  
  8. <pre></pre>  
  9. <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   
  10.   
  11. Symbol table '.dynsym' contains 118 entries:  
  12.    Num:    Value  Size Type    Bind   Vis      Ndx Name  
  13.      0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND   
  14.      1: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr0  
  15.      2: 00001a29    44 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context  
  16.      3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_f2iz  
  17.      4: 00001a5d   364 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context  
  18.      5: 00000000     0 FUNC    GLOBAL DEFAULT  UND poll  
  19.      6: 00000000     0 FUNC    GLOBAL DEFAULT  UND __errno  
  20.      7: 00000000     0 FUNC    GLOBAL DEFAULT  UND strerror  
  21.      8: 00000000     0 FUNC    GLOBAL DEFAULT  UND __android_log_print  
  22.      9: 00000000     0 FUNC    GLOBAL DEFAULT  UND read  
  23.     10: 00001bd1   120 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context  
  24.     11: 00000000     0 FUNC    GLOBAL DEFAULT  UND write  
  25.     12: 00001c51    42 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context  
  26.     13: 00000000     0 FUNC    GLOBAL DEFAULT  UND close  
  27.     14: 00000000     0 FUNC    GLOBAL DEFAULT  UND _ZdlPv  
  28.     15: 00001c95    42 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context  
  29.     16: 00001cc1   216 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context  
  30.     17: 00000000     0 FUNC    GLOBAL DEFAULT  UND _Znwj  
  31.     18: 00002455   124 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorC1Ev  
  32.     19: 00002af1   288 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorC1Ev  
  33.     20: 00002fd5   108 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorC1E  
  34.     21: 00000000     0 FUNC    GLOBAL DEFAULT  UND pipe  
  35.     22: 00000000     0 FUNC    GLOBAL DEFAULT  UND fcntl  
  36.     23: 00000000     0 FUNC    GLOBAL DEFAULT  UND memset  
  37.     24: 00001ded   216 FUNC    GLOBAL DEFAULT    7 _ZN22sensors_poll_context  
  38.     25: 0000432c   132 OBJECT  GLOBAL DEFAULT   16 HMI  
  39.     26: 00001ec5    24 FUNC    GLOBAL DEFAULT    7 _ZNK10SensorBase5getFdEv  
  40.     27: 00001edd     4 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase8setDelayE  
  41.     28: 00001ee1     4 FUNC    GLOBAL DEFAULT    7 _ZNK10SensorBase16hasPend  
  42.     29: 00001ee5    32 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase12close_de  
  43.     30: 00001f05    60 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseD1Ev  
  44.     31: 000040e8    36 OBJECT  GLOBAL DEFAULT   13 _ZTV10SensorBase  
  45.     32: 00001f41    60 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseD2Ev  
  46.     33: 00001f7d   312 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase9openInput  
  47.     34: 00000000     0 FUNC    GLOBAL DEFAULT  UND opendir  
  48.     35: 00000000     0 FUNC    GLOBAL DEFAULT  UND strcpy  
  49.     36: 00000000     0 FUNC    GLOBAL DEFAULT  UND strlen  
  50.     37: 00000000     0 FUNC    GLOBAL DEFAULT  UND open  
  51.     38: 00000000     0 FUNC    GLOBAL DEFAULT  UND ioctl  
  52.     39: 00000000     0 FUNC    GLOBAL DEFAULT  UND strcmp  
  53.     40: 00000000     0 FUNC    GLOBAL DEFAULT  UND readdir  
  54.     41: 00000000     0 FUNC    GLOBAL DEFAULT  UND closedir  
  55.     42: 00000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail  
  56.     43: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __stack_chk_guard  
  57.     44: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_unwind_cpp_pr1  
  58.     45: 000020b5    68 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseC1EPKcS1_  
  59.     46: 000020f9    68 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseC2EPKcS1_  
  60.     47: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_lmul  
  61.     48: 00002141    56 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase12getTimes  
  62.     49: 00000000     0 FUNC    GLOBAL DEFAULT  UND clock_gettime  
  63.     50: 00002179    80 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBase11open_dev  
  64.     51: 000021c9    18 FUNC    GLOBAL DEFAULT    7 _ZN10SensorBaseD0Ev  
  65.     52: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_pure_virtual  
  66.     53: 000021dd     4 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensor8setDelay  
  67.     54: 000021e1    24 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensor6enableEi  
  68.     55: 000021f9    12 FUNC    GLOBAL DEFAULT    7 _ZNK11LightSensor16hasPen  
  69.     56: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_i2f  
  70.     57: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_fcmpeq  
  71.     58: 00002209   432 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensor10readEve  
  72.     59: 00000000     0 FUNC    GLOBAL DEFAULT  UND memcpy  
  73.     60: 000030dd    96 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe  
  74.     61: 000030c5    24 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe  
  75.     62: 000030ad    22 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe  
  76.     63: 000023b9    68 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorD1Ev  
  77.     64: 0000313d    18 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe  
  78.     65: 00004110    36 OBJECT  GLOBAL DEFAULT   13 _ZTV11LightSensor  
  79.     66: 000023fd    18 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorD0Ev  
  80.     67: 00002411    68 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorD2Ev  
  81.     68: 00003165    30 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe  
  82.     69: 000024d1   124 FUNC    GLOBAL DEFAULT    7 _ZN11LightSensorC2Ev  
  83.     70: 0000254d    48 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor6enableEi  
  84.     71: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_fmul  
  85.     72: 0000257d   120 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor12process  
  86.     73: 000025f9   308 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor10readEve  
  87.     74: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_ldivmod  
  88.     75: 00002731   216 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor8setDelay  
  89.     76: 00000000     0 FUNC    GLOBAL DEFAULT  UND fopen  
  90.     77: 00000000     0 FUNC    GLOBAL DEFAULT  UND snprintf  
  91.     78: 00000000     0 FUNC    GLOBAL DEFAULT  UND fwrite  
  92.     79: 00000000     0 FUNC    GLOBAL DEFAULT  UND fclose  
  93.     80: 00002809   628 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensor11getPoll  
  94.     81: 00000000     0 FUNC    GLOBAL DEFAULT  UND strncmp  
  95.     82: 00000000     0 FUNC    GLOBAL DEFAULT  UND strcat  
  96.     83: 00000000     0 FUNC    GLOBAL DEFAULT  UND fread  
  97.     84: 00000000     0 FUNC    GLOBAL DEFAULT  UND strtol  
  98.     85: 00002a7d    48 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorD1Ev  
  99.     86: 00004138    36 OBJECT  GLOBAL DEFAULT   13 _ZTV11AccelSensor  
  100.     87: 00002aad    18 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorD0Ev  
  101.     88: 00002ac1    48 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorD2Ev  
  102.     89: 00002c11   288 FUNC    GLOBAL DEFAULT    7 _ZN11AccelSensorC2Ev  
  103.     90: 00002d31     4 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensor8se  
  104.     91: 00002d35    24 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensor6en  
  105.     92: 00002d4d    12 FUNC    GLOBAL DEFAULT    7 _ZNK17TemperatureSensor16  
  106.     93: 00002d59   488 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensor10r  
  107.     94: 00002f41    64 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorD1E  
  108.     95: 00004160    36 OBJECT  GLOBAL DEFAULT   13 _ZTV17TemperatureSensor  
  109.     96: 00002f81    18 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorD0E  
  110.     97: 00002f95    64 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorD2E  
  111.     98: 00003041   108 FUNC    GLOBAL DEFAULT    7 _ZN17TemperatureSensorC2E  
  112.     99: 00000000     0 FUNC    GLOBAL DEFAULT  UND _ZdaPv  
  113.    100: 00003151    18 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe  
  114.    101: 00000000     0 FUNC    GLOBAL DEFAULT  UND _Znaj  
  115.    102: 00003185    30 FUNC    GLOBAL DEFAULT    7 _ZN24InputEventCircularRe  
  116.    103: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize  
  117.    104: 000043c0     0 NOTYPE  GLOBAL DEFAULT   17 __dso_handle  
  118.    105: 00004000     0 NOTYPE  GLOBAL DEFAULT   11 __INIT_ARRAY__  
  119.    106: 00004008     0 NOTYPE  GLOBAL DEFAULT   12 __FINI_ARRAY__  
  120.    107: 000035dc     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_start  
  121.    108: 0000371c     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_end  
  122.    109: 0000432c     0 NOTYPE  GLOBAL DEFAULT   16 __data_start  
  123.    110: 000043b4     0 NOTYPE  GLOBAL DEFAULT  ABS _edata  
  124.    111: 000043b4     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start  
  125.    112: 000043b4     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start__  
  126.    113: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS _bss_end__  
  127.    114: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_end__  
  128.    115: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS __end__  
  129.    116: 000043d0     0 NOTYPE  GLOBAL DEFAULT  ABS _end  
  130.    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>  
  131. <br>  
  132. 结束语:  
  133. <pre></pre>  
  134. <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>  
  135. <pre></pre>  
  136. <p></p>  
  137. <pre></pre>  
  138. <pre></pre>  


转载地址:http://blog.csdn.net/vv0_0vv/article/details/7225617

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值