Android sensor架構分析


  一.其主要框架如下圖所示:

 
 
二.sensor的JNI層:android_hardware_SensorManager.cpp (frameworks\base\core\jni)
注冊JNI:
    register_android_hardware_SensorManager
        jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager", gSystemSensorManagerMethods, NELEM(gSystemSensorManagerMethods));           
        jniRegisterNativeMethods(env, "android/hardware/SystemSensorManager$BaseEventQueue", gBaseEventQueueMethods, NELEM(gBaseEventQueueMethods));
 
static JNINativeMethod gSystemSensorManagerMethods[] = {
            (void*)nativeClassInit },
                    nativeClassInit  :這函數的作用
                        jclass sensorClass = _env->FindClass("android/hardware/Sensor"); //得到Sensor.java (frameworks\base\core\java\android\hardware)的class引用
                        sensorOffsets.name        = _env->GetFieldID(sensorClass, "mName",      "Ljava/lang/String;"); //得到sensor的的引用值,這里應該是可以直接把數據傳遞到framework
                        sensorOffsets.vendor      = _env->GetFieldID(sensorClass, "mVendor",    "Ljava/lang/String;");
                        sensorOffsets.version     = _env->GetFieldID(sensorClass, "mVersion",   "I");
 
            (void*)nativeGetNextSensor }, 
                    size_t count = mgr.getSensorList(&sensorList); //得到sensor列表,返回sensor個數
                        *list = mSensorList; //在SensorManager.cpp (frameworks\native\libs\gui)
                        return mSensors.size();
                    env->SetObjectField(sensor, sensorOffsets.name,      name);  //獲得sensor的信息,就是nativeClassInit 中需要得到的
                    env->SetObjectField(sensor, sensorOffsets.vendor,    vendor);
};
 
static JNINativeMethod gBaseEventQueueMethods[] = {
            (void*)nativeInitSensorEventQueue },
                      sp<SensorEventQueue> queue(mgr.createEventQueue()); 
                              queue = new SensorEventQueue(connection); //構造 SensorEventQueue
                                mRecBuffer = new ASensorEvent[MAX_RECEIVE_BUFFER_EVENT_COUNT]; //生成一些 ASensorEvent,用了記錄sensor的信息
                      android_os_MessageQueue_getMessageQueue //得到 _MessageQueue

            (void*)nativeEnableSensor },
                         receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,  reservedFlags); //enable sensor
                              enableSensor  //在 SensorEventQueue.cpp (frameworks\native\libs\gui)
                                   mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),  us2ns(maxBatchReportLatencyUs), reservedFlags); 
                                            
            (void*)nativeDisableSensor }, //關閉sensor
 
            (void*)nativeDestroySensorEventQueue },
 
            (void*)nativeFlushSensor },
};
 
    實現SensorManager.java中的native函數,它主要調用SenrsorManager.cpp和SensorEventQueue.cpp中的類來完成相關的工作。
    SenrsorManager.cpp與SensorService.cpp主要以binder通信
 
 

三.SensorService.cpp

       SensorService作為一個輕量級的system service,它運行於SystemServer內,即在system_init<system_init.cpp>調用SensorService::instantiate();

      SensorService主要功能如下:
          1) SensorService::instantiate創建實例對象,並增加到ServiceManager中,且創建並啟動線程,並執行threadLoop
          2) threadLoop從sensor驅動獲取原始數據,然后通過SensorEventConnection把事件發送給客戶端
          3) BnSensorServer的成員函數負責讓客戶端獲取sensor列表和創建SensorEventConnection

 在addService時,第一次構建sp強引用對象時,會調用onFirstRef函數 
void SensorService::onFirstRef()  
       SensorDevice& dev(SensorDevice::getInstance()); // 獲取SensorDevice實例, 也就是調用下面的SensorDevice::SensorDevice()。    
      ssize_t count = dev.getSensorList(&list);  調用SensorDevice.getSensorList獲取sensor_t列表 
     //虛擬的sensor,也就是沒有硬件,通過其他硬件計算出來的。
        uint32_t virtualSensorsNeeds = (1<<SENSOR_TYPE_GRAVITY) | (1<<SENSOR_TYPE_LINEAR_ACCELERATION) | (1<<SENSOR_TYPE_ROTATION_VECTOR); 
        registerSensor( new HardwareSensor(list[i]) ); //根據硬件sensor_t創建HardwareSensor,然后加入mSensorList(Sensor),和mSensorMap(HardwareSensor)中 
        mUserSensorList = mSensorList; // build the sensor list returned to users
        /* 這里加入的前提是hasGyro,也就是需要陀螺儀 ,才能加入虛擬sensor*/
         aSensor = registerVirtualSensor( new RotationVectorSensor() );   //根據硬件sensor_t創建對應的senosr(如GravitySensor), 根據硬件sensor_t創建對應的senosr(如GravitySensor), 
         if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
                    mUserSensorList.add(aSensor);     //加入UserSensorList,這里RotationVectorSensor,GravitySensor,LinearAccelerationSensor, OrientationSensor, CorrectedGyroSensor
           }
        / *后面有一些關於batching的sensor的設置,batching sensor也就是支持批處理的sensor,有fifo */
         Looper = new Looper(false);  //消息循環的線程和沒有消息循環的線程,有消息循環的線程一般都會有一個Looper
        mSensorEventBuffer = new sensors_event_t[minBufferSize]; //sensors_event用於藏消息
        mSensorEventScratch = new sensors_event_t[minBufferSize];
        run("SensorService", PRIORITY_URGENT_DISPLAY); // run("SensorService", PRIORITY_URGENT_DISPLAY);運行線程,並執行threadLoop
 
 
bool SensorService::threadLoop()
    ssize_t count = device.poll(mSensorEventBuffer, numEventMax);  //調用SensorDevice.poll獲取sensors_event_t事件 
  fusion.process(event[i]);對每一個事件,執行SensorFusion.process 
   activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch, mMapFlushEventsToConnections); 調用SensorService::SensorEventConnection::sendEvents,把事件發送給所有的listener
 
status_t SensorService::SensorEventConnection::enableDisable
    err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,  reservedFlags);
        SensorService::enable
             err = sensor->activate(connection.get(), true); //使能sensor
 
 
 
 
四.sensor上層調用中間層的入口
SensorDevice.cpp (frameworks\native\services\sensorservice)
 

SensorDevice::SensorDevice()

    1.hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); //這個在Sensors.c (vendor\mediatek\proprietary\hardware\sensor)
  
  2.err = sensors_open_1(&mSensorModule->common, &mSensorDevice); 打開sensor
   
3.err = pressure_sensors_open(&mSensorDevicePressure); //這里我們加入的溫度氣壓傳感器
  
  4. mSensorModule->get_sensors_list(mSensorModule, &list); //得到sensor列表,Sensors.c (vendor\mediatek\proprietary\hardware\sensor)
  
  5.for (i=0; i<size_t(count-PRES_TEMP_SENSORS_CNT); i++) {
                 mActivationCount.add(list[i].handle, model); //把sensor加入到一個vector,handle是sensor唯一的標志 , Hwmsen_chip_info.c (vendor\mediatek\proprietary\hardware\sensor)
                mSensorDevice->activate(reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), list[i].handle, 0);  //激活sensor
            }
    6.for (; i<size_t(count); i++) {
          mActivationCount.add(list[i].handle, model);
          mSensorDevicePressure->activate(mSensorDevicePressure, list[i].handle, 0);
 
 
sensor的重要結構體
        Sensor設備結構體sensors_poll_device_t,對標准硬件設備hw_device_t結構體的擴展,主要完成讀取底層數據,並將數據存儲在struct sensors_poll_device_t結構體中,poll函數用來獲取底層數據,調用時將被阻塞定義如下:

struct sensors_poll_device_t {

struct hw_device_t common;

//Activate/deactivate one sensor

    int (*activate)(struct sensors_poll_device_t *dev,

            int handle, int enabled);

    //Set the delay between sensor events in nanoseconds for a given sensor.

    int (*setDelay)(struct sensors_poll_device_t *dev,

            int handle, int64_t ns);

    //獲取數據

    int (*poll)(struct sensors_poll_device_t *dev,

            sensors_event_t* data, int count);

};

 
 

 

  1. typedef struct hw_device_t {  
  2.     /** tag must be initialized to HARDWARE_DEVICE_TAG */  
  3.     uint32_t tag;  
  4.   
  5.     /** version number for hw_device_t */  
  6.     uint32_t version;  
  7.   
  8.     /** reference to the module this device belongs to */  
  9.     struct hw_module_t* module;  
  10.   
  11.     /** padding reserved for future use */  
  12.     uint32_t reserved[12];  
  13.   
  14.     /** Close this device */  
  15.     int (*close)(struct hw_device_t* device);  
  16.   
  17. } hw_device_t;  
     
     
         
 
  1. typedef struct sensors_event_t {  
  2.     /* must be sizeof(struct sensors_event_t) */  
  3.     int32_t version;  
  4.   
  5.     /* sensor identifier */  
  6.     int32_t sensor;  
  7.   
  8.     /* sensor type */  
  9.     int32_t type;  
  10.   
  11.     /* reserved */  
  12.     int32_t reserved0;  
  13.   
  14.     /* time is in nanosecond */  
  15.     int64_t timestamp;  
  16.   
  17.     union {  
  18.         float           data[16];  
  19.   
  20.         /* acceleration values are in meter per second per second (m/s^2) */  
  21.         sensors_vec_t   acceleration;  
  22.   
  23.         /* magnetic vector values are in micro-Tesla (uT) */  
  24.         sensors_vec_t   magnetic;  
  25.   
  26.         /* orientation values are in degrees */  
  27.         sensors_vec_t   orientation;  
  28.   
  29.         /* gyroscope values are in rad/s */  
  30.         sensors_vec_t   gyro;  
  31.   
  32.         /* temperature is in degrees centigrade (Celsius) */  
  33.         float           temperature;  
  34.   
  35.         /* distance in centimeters */  
  36.         float           distance;  
  37.   
  38.         /* light in SI lux units */  
  39.         float           light;  
  40.   
  41.         /* pressure in hectopascal (hPa) */  
  42.         float           pressure;  
  43.   
  44.         /* relative humidity in percent */  
  45.         float           relative_humidity;  
  46.     };  
  47.     uint32_t        reserved1[4];  
  48. } sensors_event_t;  
    來源: 
     
 
 
struct pollfd {
int fd;        /* 文件描述符 */
short events; /* 等待的事件 */
short revents; /* 實際發生了的事件 */
};

 
 
 
五.詳解四中每一步
    第1步
. hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); 
          根據 SENSORS_HARDWARE_MODULE_ID得到 Sensors.c (vendor\mediatek\proprietary\hardware\sensor)中的HAL層代碼
               struct sensors_module_t HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,  
        .version_major = 1,
        .version_minor = 0,
        .id = SENSORS_HARDWARE_MODULE_ID,
        .name = "MTK SENSORS Module",
        .author = "Mediatek",
        .methods = &sensors_module_methods,
    },
    .get_sensors_list = sensors__get_sensors_list,
};
 

這里主要函數是
    sensors__get_sensors_list

        *list = sSensorList; //得到sensorlist
               struct sensor_t sSensorList[MAX_NUM_SENSOR] ={};   Hwmsen_chip_info.c (vendor\mediatek\proprietary\hardware\sensor)中,我推測是apk判斷是否支持某種sensor的依據 
               #ifdef CUSTOM_KERNEL_ACCELEROMETER   //這個與ProjectConfig.mk這個相對應
     {
        .name       = ACCELEROMETER,
        .vendor     = ACCELEROMETER_VENDER,
        .version    = 3,
.handle     = ID_ACCELEROMETER+ID_OFFSET,  //這個在Hwmsensor.h (kernel-3.10\include\linux)中定義,是標示各種sensor的唯一值,調用的時候使用
 
        .type       = SENSOR_TYPE_ACCELEROMETER,  //這個在Hwmsensor.h (kernel-3.10\include\linux)中定義,標示sensor的類型
        .maxRange   = ACCELEROMETER_RANGE,//32.0f,  
        .resolution = ACCELEROMETER_RESOLUTION,//4.0f/1024.0f ,上報的精度在4.0f---1024f
        .power      = ACCELEROMETER_POWER,//130.0f/1000.0f,  //估計上電用的時間
        .minDelay   = 10000, //最少的上報時間=10ms
.maxDelay   = 1000000, //1s,最大上報時間
        .reserved   = {}
     },
   #endif
 
 

第2步:

         
 
第3步:
     pressure_sensors_open(&mSensorDevicePressure); //這里我們加入的溫度氣壓傳感器
          sensors__open_sensors((struct hw_device_t**)device); //打開sensor
        sensors_poll_context_t *dev = new sensors_poll_context_t(); 
              mSensors[pre] = new PresSensor();
             
                   PresSensor::PresSensor() //進入構造函數
                        SensorBase(NULL, "lps331ap_prs") //在PresSensor.cpp (frameworks\native\services\sensorservice)
                               data_fd = openInput(data_name); //data_name = lps331ap_prs
                                       dir = opendir(dirname);  //dirname=/dev/input
                                       readdir(dir) //循環讀取dir下每一個文件,找到lps331ap_prs這個文件,pressure_presence_flag = 1
                         
                    mEnabled(1),
                    mEnabledP(1),
                    mEnabledT(1),
                    currHzPollFreq(10.0f),
                    mInputReader(4)
                             mPendingEventP //設置mPendingEventP結構體,他一個sensors_event_t變量   
                   property_get("ro.hardware.accsensor", buffer, INPUT_SYSFS_PATH_PRES); //得到INPUT_SYSFS_PATH_PRES "/sys/class/input/input5/device/"
                   getCompenseParam(); //得到補償參數
                        LPS331AP_InitializeLibrary(calvalues); //算法相關的
        dev->device.activate        = poll__activate; //填充結構體
        dev->device.setDelay        = poll__setDelay; 
        dev->device.poll            = poll__poll;
 
 
第4步:
     mSensorModule->get_sensors_list(mSensorModule, &list); //得到sensor列表,Sensors.c (vendor\mediatek\proprietary\hardware\sensor)
    
 
第5步:
 
 
第六步:
       6.for (; i<size_t(count); i++) {
          mActivationCount.add(list[i].handle, model);  //把sensor加入到一個vector,handle是sensor唯一的標志 , Hwmsen_chip_info.c 
          mSensorDevicePressure->activate(mSensorDevicePressure, list[i].handle, 0);   
                  dev->device.activate        = poll__activate; //在pressure_sensors_open里面賦值了這個函數指針
                    poll__activate //在Sensors.cpp (frameworks\native\services\sensorservice)中
                        ctx->activate(handle, enabled); //進行enable                   
                            sensors_poll_context_t::activate;Sensors.cpp (frameworks\native\services\sensorservice)
                         index = handleToDriver(handle);        //這里返回0
                         err =  mSensors[index]->enable(handle, enabled);                             
                             PresSensor::enable       //在 PresSensor.cpp (frameworks\native\services\sensorservice)              
                                 fd = open(input_sysfs_path, O_RDWR); //打開/得到INPUT_SYSFS_PATH_PRES "/sys/class/input/input5/device/enable"
                                 err = write(fd, buf, sizeof(buf)); // 寫入1,打開sensor
                         write(mWritePipeFd, &wakeMessage, 1);//寫一個W到pipe,pipe在open的時候創建
      
創建pipe:Sensors.cpp (frameworks\native\services\sensorservice)的sensors_poll_context_t::sensors_poll_context_t()
    int wakeFds[2];
    int result = pipe(wakeFds);  //創建pipe
    ALOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
    fcntl(wakeFds[0], F_SETFL, O_NONBLOCK); // 設置文件的flags為O_NONBLOCK
    fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
    mWritePipeFd = wakeFds[1]; //寫管道
    mPollFds[wake].fd = wakeFds[0]; //讀管道
    mPollFds[wake].events = POLLIN;
    mPollFds[wake].revents = 0;
 
 
 
6.sensor數據的讀取
    
bool SensorService::threadLoop()  //
SensorService.cpp (frameworks\native\services\sensorservice)
            ssize_t count = device.poll(mSensorEventBuffer, numEventMax);
                    SensorDevice::poll(sensors_event_t* buffer, size_t count) //SensorDevice.cpp (frameworks\native\services\sensorservice)
                        c_pressure = mSensorDevicePressure->poll(mSensorDevicePressure, buffer, PRES_TEMP_SENSORS_CNT);
        //ALOGE( "SensorDevice::poll, mSensorDevicePressure return = %d\n", c_pressure);
        c = mSensorDevice->poll(reinterpret_cast<struct sensors_poll_device_t *> (mSensorDevice), buffer+PRES_TEMP_SENSORS_CNT, count-PRES_TEMP_SENSORS_CNT);
                                return ctx->pollEvents(data, count);  //Nusensors.cpp (vendor\mediatek\proprietary\hardware\sensor)
                                        int nb = sensor->readEvents(data, count);  //Sensors.cpp (frameworks\native\services\sensorservice)
                                                 int Hwmsen::readEvents(sensors_event_t* data, int count) //Hwmsen.cpp (vendor\mediatek\proprietary\hardware\sensor)
                                                        n = mInputReader.fill(mdata_fd);  //后面有些細節沒有深究了
                                         n = poll(mPollFds, numFds, nbEvents ? 0 : -1);  //poll,等待事件
 
 
 
 
7.虛擬sensor的讀取過程
注冊過程
SensorService::onFirstRef
     ssize_t count = dev.getSensorList(&list); //得到sensorlist
    if (hasGyro) { //注冊各種sensor
         aSensor = registerVirtualSensor( new RotationVectorSensor() );
                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
                    mUserSensorList.add(aSensor);
                }
 
                aSensor = registerVirtualSensor( new GravitySensor(list, count) );
                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {
                    mUserSensorList.add(aSensor);
                }
 
                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );
                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {
                    mUserSensorList.add(aSensor);
                }
 
                aSensor = registerVirtualSensor( new OrientationSensor() );
                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {
                    // if we are doing our own rotation-vector, also add
                    // the orientation sensor and remove the HAL provided one.
                    mUserSensorList.replaceAt(aSensor, orientationIndex);
                }
 
                // virtual debugging sensors are not added to mUserSensorList
                registerVirtualSensor( new CorrectedGyroSensor(list, count) );
                registerVirtualSensor( new GyroDriftSensor() );       
}
 
enable過程
    //SensorService.cpp (frameworks\native\services\sensorservice)
    SensorService::enable
        SensorInterface* sensor = mSensorMap.valueFor(handle); //得到sensor的接口,虛擬sensor的interface
        mActiveVirtualSensors.add(handle, sensor);  //加入到mActiveVirtualSensors鏈
        err = sensor->activate(connection.get(), true); //調用active
        SensorFusion::activate(void* ident, bool enabled) //調用SensorFusion.cpp (frameworks\native\services\sensorservice)
             mSensorDevice.activate(ident, mAcc.getHandle(), enabled); //使能加速度傳感器
            mSensorDevice.activate(ident, mMag.getHandle(), enabled); //使能磁傳感器
            mSensorDevice.activate(ident, mGyro.getHandle(), enabled); //使能陀螺儀
                 SensorDevice::activate //SensorDevice.cpp (frameworks\native\services\sensorservice) //這里就是開始使能實體sensor
 
 
獲取數據過程
     SensorService::threadLoop() //
        count = device.poll(mSensorEventBuffer, numEventMax); //這里獲取實體sensor的數據
             // handle virtual sensors
              if (count && vcount) { //如果是虛擬sensor
                    SensorFusion& fusion(SensorFusion::getInstance());
                    fusion.isEnabled() //如果使能
                fusion.process(event[i]); //調用process
                  SensorFusion::process //調用SensorFusion.cpp (frameworks\native\services\sensorservice),這里傳入的是實體sensor獲取來的數據
                     mFusion.handleGyro(vec3_t(event.data), dT); //處理各自的數據
             mFusion.handleMag(mag);
                    mFusion.handleAcc(acc); 
    SensorInterface* si = mActiveVirtualSensors.valueAt(j); //得到虛擬sensor的接口
    if (si->process(&out, event[i])) { //獲取計算好的值
           mSensorEventBuffer[count + k] = out;}
         // record the last synthesized values
          recordLastValueLocked(&mSensorEventBuffer[count], k);
          // sort the buffer by time-stamps
          sortEventBuffer(mSensorEventBuffer, count); //給這些event排序
  activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,),通過activeConnections發送到上層
 
注意:
如果加速度,磁傳感器,陀螺儀的數據不正常可能導致虛擬傳感器沒有數據!!
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM