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; 
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, { }},   
    //———–  
}; 
/* 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; 

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); 
            } 
        } 
    } 

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); 
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; 

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; 

/**
 * 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這個動態庫的,然後找到這個庫裡的一些回調函數,怎麼找呢? 
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 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;
 
 
 
 
HAL_MODULE_INFO_SYM_AS_STR;是一個宏,被定義在hardware.h中: 
 HAL_MODULE_INFO_SYM_AS_STR;是一個宏,被定義在hardware.h中:<pre name="code" class="cpp">#define HAL_MODULE_INFO_SYM_AS_STR  "HMI" 
<pre name="code" class="cpp">#define HAL_MODULE_INFO_SYM_AS_STR  "HMI"好瞭,就是找HMI這個字串,我們可以用readelf命令查看下sensor.glodfish.so裡面的symbol:
 
<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_lpmod 
    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 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_lpmod
    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層就是填充一些“規則”。 
這裡我隻是大致分析瞭一下這個流程,對於代碼是如何編寫的,大傢可以參考我提供的下載,其實android hal層就是填充一些“規則”。下面一節我們來編寫一個測試apk來抓我們的溫度,之後再來分析framework層,因為到這裡我們sensor的移植就結束瞭,framework層中android已經幫我們把api都寫好瞭,也就是說sensor是android的標準api,我們不需要自己去搭建。   

摘自 zhangjie201412的專欄

發佈留言