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

来源:互联网 发布:淘宝客高佣 编辑:程序博客网 时间:2024/05/21 13:57

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

 for (ssize_t i=0 ; i<count ; i++) {                registerSensor( new HardwareSensor(list[i]) );                switch (list[i].type) {                    case SENSOR_TYPE_ORIENTATION:                        orientationIndex = i;                        break;                    case SENSOR_TYPE_GYROSCOPE:                    case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:                        hasGyro = true;                        break;                    case SENSOR_TYPE_GRAVITY:                    case SENSOR_TYPE_LINEAR_ACCELERATION:                    case SENSOR_TYPE_ROTATION_VECTOR:                        virtualSensorsNeeds &= ~(1<<list[i].type);                        break;                }

Sensor SensorService::registerSensor(SensorInterface* s){    sensors_event_t event;    memset(&event, 0, sizeof(event));    const Sensor sensor(s->getSensor());    // add to the sensor list (returned to clients)    mSensorList.add(sensor);    // add to our handle->SensorInterface mapping    mSensorMap.add(sensor.getHandle(), s);    // create an entry in the mLastEventSeen array    mLastEventSeen.add(sensor.getHandle(), event);    return sensor;}

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


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

 if (hasGyro) {                Sensor aSensor;                // Add Android virtual sensors if they're not already                // available in the HAL                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() );            }

3.6 run("SensorService", PRIORITY_URGENT_DISPLAY);启动sensorService线程,sensorService父类有一个Thread线程,调用run方法会创建线程并调用threadLoop方法。

bool SensorService::threadLoop(){    ALOGD("nuSensorService thread starting...");    // each virtual sensor could generate an event per "real" event, that's why we need    // to size numEventMax much smaller than MAX_RECEIVE_BUFFER_EVENT_COUNT.    // in practice, this is too aggressive, but guaranteed to be enough.    const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;    const size_t numEventMax = minBufferSize / (1 + mVirtualSensorList.size());    SensorDevice& device(SensorDevice::getInstance());    const size_t vcount = mVirtualSensorList.size();    SensorEventAckReceiver sender(this);    sender.run("SensorEventAckReceiver", PRIORITY_URGENT_DISPLAY);    const int halVersion = device.getHalDeviceVersion();    do {        ssize_t count = device.poll(mSensorEventBuffer, numEventMax);        if (count < 0) {            ALOGE("sensor poll failed (%s)", strerror(-count));            break;        }        // Reset sensors_event_t.flags to zero for all events in the buffer.        for (int i = 0; i < count; i++) {             mSensorEventBuffer[i].flags = 0;        }        // Make a copy of the connection vector as some connections may be removed during the        // course of this loop (especially when one-shot sensor events are present in the        // sensor_event buffer). Promote all connections to StrongPointers before the lock is        // acquired. If the destructor of the sp gets called when the lock is acquired, it may        // result in a deadlock as ~SensorEventConnection() needs to acquire mLock again for        // cleanup. So copy all the strongPointers to a vector before the lock is acquired.        SortedVector< sp<SensorEventConnection> > activeConnections;        {            Mutex::Autolock _l(mLock);            for (size_t i=0 ; i < mActiveConnections.size(); ++i) {                sp<SensorEventConnection> connection(mActiveConnections[i].promote());                if (connection != 0) {                    activeConnections.add(connection);                }            }        }        Mutex::Autolock _l(mLock);        // Poll has returned. Hold a wakelock if one of the events is from a wake up sensor. The        // rest of this loop is under a critical section protected by mLock. Acquiring a wakeLock,        // sending events to clients (incrementing SensorEventConnection::mWakeLockRefCount) should        // not be interleaved with decrementing SensorEventConnection::mWakeLockRefCount and        // releasing the wakelock.        bool bufferHasWakeUpEvent = false;        for (int i = 0; i < count; i++) {            if (isWakeUpSensorEvent(mSensorEventBuffer[i])) {                bufferHasWakeUpEvent = true;                break;            }        }        if (bufferHasWakeUpEvent && !mWakeLockAcquired) {            acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);            mWakeLockAcquired = true;        }        recordLastValueLocked(mSensorEventBuffer, count);        // handle virtual sensors        if (count && vcount) {            sensors_event_t const * const event = mSensorEventBuffer;            const size_t activeVirtualSensorCount = mActiveVirtualSensors.size();            if (activeVirtualSensorCount) {                size_t k = 0;                SensorFusion& fusion(SensorFusion::getInstance());                if (fusion.isEnabled()) {                    for (size_t i=0 ; i<size_t(count) ; i++) {                        fusion.process(event[i]);                    }                }                for (size_t i=0 ; i<size_t(count) && k<minBufferSize ; i++) {                    for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {                        if (count + k >= minBufferSize) {                            ALOGE("buffer too small to hold all events: "                                    "count=%zd, k=%zu, size=%zu",                                    count, k, minBufferSize);                            break;                        }                        sensors_event_t out;                        SensorInterface* si = mActiveVirtualSensors.valueAt(j);                        if (si->process(&out, event[i])) {                            mSensorEventBuffer[count + k] = out;                            k++;                        }                    }                }                if (k) {                    // record the last synthesized values                    recordLastValueLocked(&mSensorEventBuffer[count], k);                    count += k;                    // sort the buffer by time-stamps                    sortEventBuffer(mSensorEventBuffer, count);                }            }        }        // handle backward compatibility for RotationVector sensor        if (halVersion < SENSORS_DEVICE_API_VERSION_1_0) {            for (int i = 0; i < count; i++) {                if (mSensorEventBuffer[i].type == SENSOR_TYPE_ROTATION_VECTOR) {                    // All the 4 components of the quaternion should be available                    // No heading accuracy. Set it to -1                    mSensorEventBuffer[i].data[4] = -1;                }            }        }        // Map flush_complete_events in the buffer to SensorEventConnections which called        // flush on the hardware sensor. mapFlushEventsToConnections[i] will be the        // SensorEventConnection mapped to the corresponding flush_complete_event in        // mSensorEventBuffer[i] if such a mapping exists (NULL otherwise).        for (int i = 0; i < count; ++i) {            mMapFlushEventsToConnections[i] = NULL;            if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {                const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;                SensorRecord* rec = mActiveSensors.valueFor(sensor_handle);                if (rec != NULL) {                    mMapFlushEventsToConnections[i] = rec->getFirstPendingFlushConnection();                    rec->removeFirstPendingFlushConnection();                }            }        }        // Send our events to clients. Check the state of wake lock for each client and release the        // lock if none of the clients need it.        bool needsWakeLock = false;        size_t numConnections = activeConnections.size();        for (size_t i=0 ; i < numConnections; ++i) {            if (activeConnections[i] != 0) {                activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,                        mMapFlushEventsToConnections);                needsWakeLock |= activeConnections[i]->needsWakeLock();                // If the connection has one-shot sensors, it may be cleaned up after first trigger.                // Early check for one-shot sensors.                if (activeConnections[i]->hasOneShotSensors()) {                    cleanupAutoDisabledSensorLocked(activeConnections[i], mSensorEventBuffer,                            count);                }            }        }        if (mWakeLockAcquired && !needsWakeLock) {            release_wake_lock(WAKE_LOCK_NAME);            mWakeLockAcquired = false;        }    } while (!Thread::exitPending());    ALOGW("Exiting SensorService::threadLoop => aborting...");    abort();    return false;}

3.6.1 首先是调用device.poll(mSensorEventBuffer, numEventMax);来获取sensor数据。这里调用的是前面open_sensors函数初始化的 dev->device.poll            = poll__poll;

static int poll__poll(struct sensors_poll_device_t *dev,        sensors_event_t* data, int count) {    sensors_poll_context_t *ctx = (sensors_poll_context_t *)dev;    return ctx->pollEvents(data, count);}

可以看到最后调用的是pollEvents函数:

int sensors_poll_context_t::pollEvents(sensors_event_t * data, int count){int nbEvents = 0;int n = 0;int polltime = -1;do {// see if we have some leftover from the last poll()for (int i = 0; count && i < numSensorDrivers; i++) {SensorBase *const sensor(mSensors[i]);if ((mPollFds[i].revents & POLLIN)    || (sensor->hasPendingEvents())) {int nb = sensor->readEvents(data, count);if (nb < count) {// no more data for this sensormPollFds[i].revents = 0;}#ifndef ORI_NULLif ((0 != nb) && (acc == i)) {((OriSensor *) (mSensors[ori]))->    setAccel(&data[nb - 1]);}#endifcount -= nb;nbEvents += nb;data += nb;}}if (count) {// we still have some room, so try to see if we can get// some events immediately or just wait if we don't have// anything to returndo {n = poll(mPollFds, numFds, nbEvents ? 0 : polltime);} while (n < 0 && errno == EINTR);if (n < 0) {ALOGE("poll() failed (%s)", strerror(errno));return -errno;}if (mPollFds[wake].revents & POLLIN) {char msg;int result = read(mPollFds[wake].fd, &msg, 1);ALOGE_IF(result < 0, "error reading from wake pipe (%s)", strerror(errno));ALOGE_IF(msg != WAKE_MESSAGE, "unknown message on wake queue (0x%02x)", int (msg));mPollFds[wake].revents = 0;}}// if we have events and space, go read them} while (n && count);return nbEvents;}

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

int STKLightSensor::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;    while (count && mInputReader.readEvent(&event)) {        int type = event->type;        if (type == EV_ABS) {            if (event->code == ABS_MISC) {                mPendingEvent.light = (float)event->value;            }        } else if (type == EV_SYN) {            mPendingEvent.timestamp = timevalToNano(event->time);            if (mEnabled) {                *data++ = mPendingEvent;                count--;                numEventReceived++;            }        } else {            ALOGE("STKLightSensor: unknown event (type=%d, code=%d)",                    type, event->code);        }        mInputReader.next();    }    return numEventReceived;}

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


ssize_t InputEventCircularReader::fill(int fd){size_t numEventsRead = 0;if (mFreeSpace) {const ssize_t nread =    read(fd, mHead, mFreeSpace * sizeof(input_event));if (nread < 0 || nread % sizeof(input_event)) {// we got a partial event!!return nread < 0 ? -errno : -EINVAL;}numEventsRead = nread / sizeof(input_event);if (numEventsRead) {mHead += numEventsRead;mFreeSpace -= numEventsRead;if (mHead > mBufferEnd) {size_t s = mHead - mBufferEnd;memcpy(mBuffer, mBufferEnd,       s * sizeof(input_event));mHead = mBuffer + s;}}}return numEventsRead;}ssize_t InputEventCircularReader::readEvent(input_event const **events){*events = mCurr;ssize_t available = (mBufferEnd - mBuffer) - mFreeSpace;return available ? 1 : 0;}void InputEventCircularReader::next(){mCurr++;mFreeSpace++;if (mCurr >= mBufferEnd) {mCurr = mBuffer;}}

SensorBase::SensorBase(        const char* dev_name,        const char* data_name)    : dev_name(dev_name), data_name(data_name),      dev_fd(-1), data_fd(-1){    if (data_name) {        data_fd = openInput(data_name);    }}


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


int SensorBase::openInput(const char* inputName) {    int fd = -1;    const char *dirname = "/dev/input";    char devname[PATH_MAX];    char *filename;    DIR *dir;    struct dirent *de;    dir = opendir(dirname);    if(dir == NULL)        return -1;    strcpy(devname, dirname);    filename = devname + strlen(devname);    *filename++ = '/';    while((de = readdir(dir))) {        if(de->d_name[0] == '.' &&                (de->d_name[1] == '\0' ||                        (de->d_name[1] == '.' && de->d_name[2] == '\0')))            continue;        strcpy(filename, de->d_name);        fd = open(devname, O_RDONLY);        if (fd>=0) {            char name[80];            if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {                name[0] = '\0';            }            if (!strcmp(name, inputName)) {                strcpy(input_name, filename);                break;            } else {                close(fd);                fd = -1;            }        }    }    closedir(dir);    ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);    return fd;

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

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

至此sensorservice的启动就讲完了,下一篇将从sensor APP端讲述sensor APP的工作流程。

0 0
原创粉丝点击