• (OK) android-5.0 sensor工作原理—sensorservice的启动(二)



    http://blog.csdn.net/zsj100213/article/details/48287023


    3.2 dev.getSensorList(&list);获取厂商在HAL层初始化的sensor_t类型结构体的sSensorList,并返回sensor device的数目。

    3.3 registerSensor( new HardwareSensor(list[i]) );在for循环中注册这些sensor。根据硬件sensor_t创建HardwareSensor,然后加入mSensorList(Sensor) 和mSensorMap(HardwareSensor)中,后面的switch是判断是否存在电子罗盘,GYRO以及GYRO对应所需要的对应的一些所对应的一些虚拟sensor

    1. for (ssize_t i=0 ; i<count ; i++) {  
    2.                registerSensor( new HardwareSensor(list[i]) );  
    3.                switch (list[i].type) {  
    4.                    case SENSOR_TYPE_ORIENTATION:  
    5.                        orientationIndex = i;  
    6.                        break;  
    7.                    case SENSOR_TYPE_GYROSCOPE:  
    8.                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:  
    9.                        hasGyro = true;  
    10.                        break;  
    11.                    case SENSOR_TYPE_GRAVITY:  
    12.                    case SENSOR_TYPE_LINEAR_ACCELERATION:  
    13.                    case SENSOR_TYPE_ROTATION_VECTOR:  
    14.                        virtualSensorsNeeds &= ~(1<<list[i].type);  
    15.                        break;  
    16.                }  

    1. Sensor SensorService::registerSensor(SensorInterface* s)  
    2. {  
    3.     sensors_event_t event;  
    4.     memset(&event, 0, sizeof(event));  
    5.   
    6.     const Sensor sensor(s->getSensor());  
    7.     // add to the sensor list (returned to clients)  
    8.     mSensorList.add(sensor);  
    9.     // add to our handle->SensorInterface mapping  
    10.     mSensorMap.add(sensor.getHandle(), s);  
    11.     // create an entry in the mLastEventSeen array  
    12.     mLastEventSeen.add(sensor.getHandle(), event);  
    13.   
    14.     return sensor;  
    15. }  

    3.4 mUserSensorList = mSensorList;将mSensorList传感器列表赋值给mUserSensorList,mSensorList是由registerSensor初始化的,mUserSensorList是要提交给Java框架层的传感器列表。


    3.5 如果有GYRO就注册这样一些上面提到的三种虚拟sensor来实现GYRO的功能,此处我是这么理解的。

    1. if (hasGyro) {  
    2.                Sensor aSensor;  
    3.   
    4.                // Add Android virtual sensors if they're not already  
    5.                // available in the HAL  
    6.   
    7.                aSensor = registerVirtualSensor( new RotationVectorSensor() );  
    8.                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {  
    9.                    mUserSensorList.add(aSensor);  
    10.                }  
    11.   
    12.                aSensor = registerVirtualSensor( new GravitySensor(list, count) );  
    13.                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_GRAVITY)) {  
    14.                    mUserSensorList.add(aSensor);  
    15.                }  
    16.   
    17.                aSensor = registerVirtualSensor( new LinearAccelerationSensor(list, count) );  
    18.                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_LINEAR_ACCELERATION)) {  
    19.                    mUserSensorList.add(aSensor);  
    20.                }  
    21.   
    22.                aSensor = registerVirtualSensor( new OrientationSensor() );  
    23.                if (virtualSensorsNeeds & (1<<SENSOR_TYPE_ROTATION_VECTOR)) {  
    24.                    // if we are doing our own rotation-vector, also add  
    25.                    // the orientation sensor and remove the HAL provided one.  
    26.                    mUserSensorList.replaceAt(aSensor, orientationIndex);  
    27.                }  
    28.   
    29.                // virtual debugging sensors are not added to mUserSensorList  
    30.                registerVirtualSensor( new CorrectedGyroSensor(list, count) );  
    31.                registerVirtualSensor( new GyroDriftSensor() );  
    32.            }  

    3.6 run("SensorService", PRIORITY_URGENT_DISPLAY);启动sensorService线程,sensorService父类有一个Thread线程,调用run方法会创建线程并调用threadLoop方法。
    1. bool SensorService::threadLoop()  
    2. {  
    3.     ALOGD("nuSensorService thread starting...");  
    4.   
    5.     // each virtual sensor could generate an event per "real" event, that's why we need  
    6.     // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.  
    7.     // in practice, this is too aggressive, but guaranteed to be enough.  
    8.     const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;  
    9.     const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());  
    10.   
    11.     SensorDevice& device(SensorDevice::getInstance());  
    12.     const size_t vcount = mVirtualSensorList.size();  
    13.   
    14.     SensorEventAckReceiver sender(this);  
    15.     sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);  
    16.     const int halVersion = device.getHalDeviceVersion();  
    17.     do {  
    18.         ssize_t count = device.poll(mSensorEventBuffer, numEventMax);  
    19.         if (count < 0) {  
    20.             ALOGE("sensor poll failed (%s)", strerror(-count));  
    21.             break;  
    22.         }  
    23.   
    24.         // Reset sensors_event_t.flags to zero for all events in the buffer.  
    25.         for (int i = 0; i < count; i++) {  
    26.              mSensorEventBuffer[i].flags = 0;  
    27.         }  
    28.   
    29.         // Make a copy of the connection vector as some connections may be removed during the  
    30.         // course of this loop (especially when one-shot sensor events are present in the  
    31.         // sensor_event buffer). Promote all connections to StrongPointers before the lock is  
    32.         // acquired. If the destructor of the sp gets called when the lock is acquired, it may  
    33.         // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for  
    34.         // cleanup. So copy all the strongPointers to a vector before the lock is acquired.  
    35.         SortedVector< sp<SensorEventConnection> > activeConnections;  
    36.         {  
    37.             Mutex::Autolock _l(mLock);  
    38.             for (size_t i=0 ; i < mActiveConnections.size(); ++i) {  
    39.                 sp<SensorEventConnection> connection(mActiveConnections[i].promote());  
    40.                 if (connection != 0) {  
    41.                     activeConnections.add(connection);  
    42.                 }  
    43.             }  
    44.         }  
    45.   
    46.         Mutex::Autolock _l(mLock);  
    47.         // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The  
    48.         // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,  
    49.         // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should  
    50.         // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and  
    51.         // releasing the wakelock.  
    52.         bool bufferHasWakeUpEvent = false;  
    53.         for (int i = 0; i < count; i++) {  
    54.             if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {  
    55.                 bufferHasWakeUpEvent = true;  
    56.                 break;  
    57.             }  
    58.         }  
    59.   
    60.         if (bufferHasWakeUpEvent && !mWakeLockAcquired) {  
    61.             acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);  
    62.             mWakeLockAcquired = true;  
    63.         }  
    64.         recordLastValueLocked(mSensorEventBuffer, count);  
    65.   
    66.         // handle virtual sensors  
    67.         if (count && vcount) {  
    68.             sensors_event_t const * const event = mSensorEventBuffer;  
    69.             const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();  
    70.             if (activeVirtualSensorCount) {  
    71.                 size_t k = 0;  
    72.                 SensorFusion& fusion(SensorFusion::getInstance());  
    73.                 if (fusion.isEnabled()) {  
    74.                     for (size_t i=0 ; i<size_t(count) ; i++) {  
    75.                         fusion.process(event[i]);  
    76.                     }  
    77.                 }  
    78.                 for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {  
    79.                     for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {  
    80.                         if (count + k >= minBufferSize) {  
    81.                             ALOGE("buffer too small to hold all events: "  
    82.                                     "count=%zd, k=%zu, size=%zu",  
    83.                                     count, k, minBufferSize);  
    84.                             break;  
    85.                         }  
    86.                         sensors_event_t out;  
    87.                         SensorInterface* si = mActiveVirtualSensors.valueAt(j);  
    88.                         if (si->process(&out, event[i])) {  
    89.                             mSensorEventBuffer[count + k] = out;  
    90.                             k++;  
    91.                         }  
    92.                     }  
    93.                 }  
    94.                 if (k) {  
    95.                     // record the last synthesized values  
    96.                     recordLastValueLocked(&mSensorEventBuffer[count], k);  
    97.                     count += k;  
    98.                     // sort the buffer by time-stamps  
    99.                     sortEventBuffer(mSensorEventBuffer, count);  
    100.                 }  
    101.             }  
    102.         }  
    103.   
    104.         // handle backward compatibility for RotationVector sensor  
    105.         if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {  
    106.             for (int i = 0; i < count; i++) {  
    107.                 if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {  
    108.                     // All the 4 components of the quaternion should be available  
    109.                     // No heading accuracy. Set it to -1  
    110.                     mSensorEventBuffer[i].data[4] = -1;  
    111.                 }  
    112.             }  
    113.         }  
    114.   
    115.         // Map flush_complete_events in the buffer to SensorEventConnections which called  
    116.         // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the  
    117.         // SensorEventConnection mapped to the corresponding flush_complete_event in  
    118.         // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).  
    119.         for (int i = 0; i < count; ++i) {  
    120.             mMapFlushEventsToConnections[i] = NULL;  
    121.             if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {  
    122.                 const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;  
    123.                 SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);  
    124.                 if (rec != NULL) {  
    125.                     mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();  
    126.                     rec->removeFirstPendingFlushConnection();  
    127.                 }  
    128.             }  
    129.         }  
    130.   
    131.         // Send our events to clients. Check the state of wake lock for each client and release the  
    132.         // lock if none of the clients need it.  
    133.         bool needsWakeLock = false;  
    134.         size_t numConnections = activeConnections.size();  
    135.         for (size_t i=0 ; i < numConnections; ++i) {  
    136.             if (activeConnections[i] != 0) {  
    137.                 activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,  
    138.                         mMapFlushEventsToConnections);  
    139.                 needsWakeLock |= activeConnections[i]->needsWakeLock();  
    140.                 // If the connection has one-shot sensors, it may be cleaned up after first trigger.  
    141.                 // Early check for one-shot sensors.  
    142.                 if (activeConnections[i]->hasOneShotSensors()) {  
    143.                     cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,  
    144.                             count);  
    145.                 }  
    146.             }  
    147.         }  
    148.   
    149.         if (mWakeLockAcquired && !needsWakeLock) {  
    150.             release_wake_lock(WAKE_LOCK_NAME);  
    151.             mWakeLockAcquired = false;  
    152.         }  
    153.     } while (!Thread::exitPending());  
    154.   
    155.     ALOGW("Exiting SensorService::threadLoop => aborting...");  
    156.     abort();  
    157.     return false;  
    158. }  

    3.6.1 首先是调用device.poll(mSensorEventBuffer, numEventMax);来获取sensor数据。这里调用的是前面open_sensors函数初始化的 dev->device.poll            = poll__poll;
    1. static int poll__poll(struct sensors_poll_device_t *dev,  
    2.         sensors_event_t* data, int count) {  
    3.     sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;  
    4.     return ctx->pollEvents(data, count);  
    5. }  

    可以看到最后调用的是pollEvents函数:
    1. int sensors_poll_context_t::pollEvents(sensors_event_t * data, int count)  
    2. {  
    3.     int nbEvents = 0;  
    4.     int n = 0;  
    5.     int polltime = -1;  
    6.   
    7.     do {  
    8.         // see if we have some leftover from the last poll()  
    9.         for (int i = 0; count && i < numSensorDrivers; i++) {  
    10.             SensorBase *const sensor(mSensors[i]);  
    11.             if ((mPollFds[i].revents & POLLIN)  
    12.                 || (sensor->hasPendingEvents())) {  
    13.                 int nb = sensor->readEvents(data, count);  
    14.                 if (nb < count) {  
    15.                     // no more data for this sensor  
    16.                     mPollFds[i].revents = 0;  
    17.                 }  
    18. #ifndef ORI_NULL  
    19.                 if ((0 != nb) && (acc == i)) {  
    20.                     ((OriSensor *) (mSensors[ori]))->  
    21.                         setAccel(&data[nb - 1]);  
    22.                 }  
    23. #endif  
    24.                 count -= nb;  
    25.                 nbEvents += nb;  
    26.                 data += nb;  
    27.             }  
    28.         }  
    29.   
    30.         if (count) {  
    31.             // we still have some room, so try to see if we can get  
    32.             // some events immediately or just wait if we don't have  
    33.             // anything to return  
    34.             do {  
    35.                 n = poll(mPollFds, numFds,  
    36.                      nbEvents ? 0 : polltime);  
    37.             } while (n < 0 && errno == EINTR);  
    38.             if (n < 0) {  
    39.                 ALOGE("poll() failed (%s)", strerror(errno));  
    40.                 return -errno;  
    41.             }  
    42.             if (mPollFds[wake].revents & POLLIN) {  
    43.                 char msg;  
    44.                 int result = read(mPollFds[wake].fd, &msg, 1);  
    45.                 ALOGE_IF(result < 0,  
    46.                      "error reading from wake pipe (%s)",  
    47.                      strerror(errno));  
    48.                 ALOGE_IF(msg != WAKE_MESSAGE,  
    49.                      "unknown message on wake queue (0x%02x)",  
    50.                      int (msg));  
    51.                 mPollFds[wake].revents = 0;  
    52.             }  
    53.         }  
    54.         // if we have events and space, go read them  
    55.     } while (n && count);  
    56.   
    57.     return nbEvents;  
    58. }  

    这里首先调用的是sensor->readEvents(data, count);也就是各个sensor对应的读取sensor event的方法。readEvents()函数先调用fill函数将所要读的sensor的input_event事件读取到一个环形缓冲区,然后在while循环中mInputReader.readEvent(&event)读取当前指针所指向的事件,mInputReader.next();将指针指向环形队列下一条事件来读取下一条事件。

    1. int STKLightSensor::readEvents(sensors_event_t* data, int count){  
    2.     if (count < 1)  
    3.         return -EINVAL;  
    4.   
    5.     if (mHasPendingEvent) {  
    6.         mHasPendingEvent = false;  
    7.         mPendingEvent.timestamp = getTimestamp();  
    8.         *data = mPendingEvent;  
    9.         return mEnabled ? 1 : 0;  
    10.     }  
    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.   
    19.     while (count && mInputReader.readEvent(&event)) {  
    20.         int type = event->type;  
    21.         if (type == EV_ABS) {  
    22.             if (event->code == ABS_MISC) {  
    23.                 mPendingEvent.light = (float)event->value;  
    24.             }  
    25.         } else if (type == EV_SYN) {  
    26.             mPendingEvent.timestamp = timevalToNano(event->time);  
    27.             if (mEnabled) {  
    28.                 *data++ = mPendingEvent;  
    29.                 count--;  
    30.                 numEventReceived++;  
    31.             }  
    32.         } else {  
    33.             ALOGE("STKLightSensor: unknown event (type=%d, code=%d)",  
    34.                     type, event->code);  
    35.         }  
    36.         mInputReader.next();  
    37.     }  
    38.   
    39.     return numEventReceived;  
    40. }  

    fill函数的参数data_fd是在前面sensors_poll_context_t()函数中的new STKLightSensor();进行初始化的,其主要是SensorBase(NULL, "lightsensor-level"),这里主要是openInput动作来获得一个fd从而从这个fd的文件中获取sensor event。


    1. ssize_t InputEventCircularReader::fill(int fd)  
    2. {  
    3.     size_t numEventsRead = 0;  
    4.     if (mFreeSpace) {  
    5.         const ssize_t nread =  
    6.             read(fd, mHead, mFreeSpace * sizeof(input_event));  
    7.         if (nread < 0 || nread % sizeof(input_event)) {  
    8.             // we got a partial event!!  
    9.             return nread < 0 ? -errno : -EINVAL;  
    10.         }  
    11.   
    12.         numEventsRead = nread / sizeof(input_event);  
    13.         if (numEventsRead) {  
    14.             mHead += numEventsRead;  
    15.             mFreeSpace -= numEventsRead;  
    16.             if (mHead > mBufferEnd) {  
    17.                 size_t s = mHead - mBufferEnd;  
    18.                 memcpy(mBuffer, mBufferEnd,  
    19.                        s * sizeof(input_event));  
    20.                 mHead = mBuffer + s;  
    21.             }  
    22.         }  
    23.     }  
    24.   
    25.     return numEventsRead;  
    26. }  
    27.   
    28. ssize_t InputEventCircularReader::readEvent(input_event const **events)  
    29. {  
    30.     *events = mCurr;  
    31.     ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace;  
    32.     return available ? 1 : 0;  
    33. }  
    34.   
    35. void InputEventCircularReader::next()  
    36. {  
    37.     mCurr++;  
    38.     mFreeSpace++;  
    39.     if (mCurr >= mBufferEnd) {  
    40.         mCurr = mBuffer;  
    41.     }  
    42. }  

    1. SensorBase::SensorBase(  
    2.         const char* dev_name,  
    3.         const char* data_name)  
    4.     : dev_name(dev_name), data_name(data_name),  
    5.       dev_fd(-1), data_fd(-1)  
    6. {  
    7.     if (data_name) {  
    8.         data_fd = openInput(data_name);  
    9.     }  
    10. }  


    openInput()实际上是打开各个sensor对应于/dev/input/event*文件节点最后返回的是sensor对应文件节点的fd,也就是上面fill函数的参数data_fd,在adb shell,然后getevent命令也是获取位于/dev/input/下所有的event事件。


    1. int SensorBase::openInput(const char* inputName) {  
    2.     int fd = -1;  
    3.     const char *dirname = "/dev/input";  
    4.     char devname[PATH_MAX];  
    5.     char *filename;  
    6.     DIR *dir;  
    7.     struct dirent *de;  
    8.     dir = opendir(dirname);  
    9.     if(dir == NULL)  
    10.         return -1;  
    11.     strcpy(devname, dirname);  
    12.     filename = devname + strlen(devname);  
    13.     *filename++ = '/';  
    14.     while((de = readdir(dir))) {  
    15.         if(de->d_name[0] == '.' &&  
    16.                 (de->d_name[1] == '' ||  
    17.                         (de->d_name[1] == '.' && de->d_name[2] == '')))  
    18.             continue;  
    19.         strcpy(filename, de->d_name);  
    20.         fd = open(devname, O_RDONLY);  
    21.         if (fd>=0) {  
    22.             char name[80];  
    23.             if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {  
    24.                 name[0] = '';  
    25.             }  
    26.             if (!strcmp(name, inputName)) {  
    27.                 strcpy(input_name, filename);  
    28.                 break;  
    29.             } else {  
    30.                 close(fd);  
    31.                 fd = -1;  
    32.             }  
    33.         }  
    34.     }  
    35.     closedir(dir);  
    36.     ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);  
    37.     return fd;  

    在获取完数据之后就要通过 activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,mMapFlushEventsToConnections);调用write函数将数据放到一个管道里面,sensor APP将数据取走。

    1. ssize_t size = SensorEventQueue::write(mChannel,  
    2.                                 reinterpret_cast<ASensorEvent const*>(scratch), count);  

    至此sensorservice的启动就讲完了,下一篇将从sensor APP端讲述sensor APP的工作流程。
  • 相关阅读:
    Failed to load resource: the server responded with a status of 413 (Request Entity Too Large)
    钱能解决的都是小事——北漂18年(78)
    mysql 排序
    innodb和myisam表排序
    perl 内部字节字符转换
    encode_json 转换给定的perl数据结构为一个UTF-8编码的 2进制字符串 decode_json把UTF-8字节转换成字符
    perl /g
    perl 循环截取字符串
    eclipse报错:Compilation unit name must end with .java, or one of the registered Java-like exten
    用 Flask 来写个轻博客 (30) — 使用 Flask-Admin 增强文章管理功能
  • 原文地址:https://www.cnblogs.com/ztguang/p/12645159.html
Copyright © 2020-2023  润新知