码迷,mamicode.com
首页 > 移动开发 > 详细

android中的计步问题及计步传感器分析

时间:2015-02-04 18:46:26      阅读:2493      评论:0      收藏:0      [点我收藏+]

标签:

今天打开博客,才发现居然有一年多没有写博客了。。。


最近由于公司要分析android上的计步问题,顺便把计步器在android上的实现跟踪了一下。结果发现悲催的是,android的api19上,是用的硬件本身的计步实现了。


android源码中的流程追踪如下:

frameworks/base/core/java/android/hardware/Sensor.java 中定义了TYPE_STEP_DETECTOR和TYPE_STEP_COUNTER。 请注意,detector启动后,确认了,才启动counter.

然后在jni以下查到调用。

frameworks/base/core/jni/android_hardware_SensorManager.cpp

    virtual int handleEvent(int fd, int events, void* data) {
        JNIEnv* env = AndroidRuntime::getJNIEnv();
        sp<SensorEventQueue> q = reinterpret_cast<SensorEventQueue *>(data);
        ssize_t n;
        ASensorEvent buffer[16];
        while ((n = q->read(buffer, 16)) > 0) {
            for (int i=0 ; i<n ; i++) {

                if (buffer[i].type == SENSOR_TYPE_STEP_COUNTER) {
                    // step-counter returns a uint64, but the java API only deals with floats
                    float value = float(buffer[i].u64.step_counter);
                    env->SetFloatArrayRegion(mScratch, 0, 1, &value);
                } else {
                    env->SetFloatArrayRegion(mScratch, 0, 16, buffer[i].data);
                }

可以看到,如果是计步器,直接从q里面读出的原生值。其中q被转化成了SensorEventQueue.查找转化方法:

frameworks/native/libs/gui/SensorEventQueue.cpp

ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
    if (mAvailable == 0) {
        ssize_t err = BitTube::recvObjects(mSensorChannel,
                mRecBuffer, MAX_RECEIVE_BUFFER_EVENT_COUNT);
        if (err < 0) {
            return err;
        }   
        mAvailable = err;
        mConsumed = 0;
    }   
    size_t count = numEvents < mAvailable ? numEvents : mAvailable;
    memcpy(events, mRecBuffer + mConsumed, count*sizeof(ASensorEvent));
    mAvailable -= count;
    mConsumed += count;
    return count;
}
也就是说,SensorEvent是保存在ASensorEvent的结构中。查找原型。

frameworks/native/include/android/sensor.h

/* NOTE: Must match hardware/sensors.h */
typedef struct ASensorEvent {
    int32_t version; /* sizeof(struct ASensorEvent) */
    int32_t sensor;
    int32_t type;
    int32_t reserved0;
    int64_t timestamp;
    union {
        union {
            float           data[16];
            ASensorVector   vector;
            ASensorVector   acceleration;
            ASensorVector   magnetic;
            float           temperature;
            float           distance;
            float           light;
            float           pressure;
            float           relative_humidity;
            AUncalibratedEvent uncalibrated_gyro;
            AUncalibratedEvent uncalibrated_magnetic;
            AMetaDataEvent meta_data;
        };  
        union {
            uint64_t        data[8];
            uint64_t        step_counter;
        } u64;
    };  
    int32_t reserved1[4];
} ASensorEvent;
这时数据出来了。。。。直接调用硬件上的计步器实现。

hal层的相关文件。

./hardware/libhardware/include/hardware/sensors.h

#define SENSOR_TYPE_STEP_DETECTOR                   (18)
...
#define SENSOR_TYPE_STEP_COUNTER                    (19)
OK。这时候查找hal层的使用方法。

invensense/65xx/libsensors_iio/sensors_mpl.cpp

202 int sensors_poll_context_t::pollEvents(sensors_event_t *data, int count)
203 {
204     VHANDLER_LOG;
205 
206     int nbEvents = 0;
207     int nb, polltime = -1;
208 
209     polltime = ((MPLSensor*) mSensor)->getStepCountPollTime();
210 
211     // look for new events
212     nb = poll(mPollFds, numFds, polltime);
213     LOGI_IF(0, "poll nb=%d, count=%d, pt=%d", nb, count, polltime);
214     if (nb > 0) {
215         for (int i = 0; count && i < numSensorDrivers; i++) {
216             if (mPollFds[i].revents & (POLLIN | POLLPRI)) {               
217                 LOGI_IF(0, "poll found=%d", i);
218                 nb = 0;
219                 if (i == mpl) {
220                     ((MPLSensor*) mSensor)->buildMpuEvent();
221                     mPollFds[i].revents = 0;
222                 } else if (i == compass) {
223                     ((MPLSensor*) mSensor)->buildCompassEvent();
224                     mPollFds[i].revents = 0;
....
268         if(((MPLSensor*) mSensor)->hasStepCountPendingEvents() == true) {
269             nb = 0;
270             nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(data, count, ID_SC, SENSOR_TYPE_STEP_COUNTER, 0);
271             LOGI_IF(HANDLER_DATA, "sensors_mpl:readStepCount() - nb=%d, count=%d, nbEvents=%d, data->timestamp=%lld, data->data[0]=%f,",
272                           nb, count, nbEvents, data->timestamp, data->data[0]);
273             if (nb > 0) {
274                 count -= nb;
275                 nbEvents += nb;
276                 data += nb;
277             }
278         }                    
可以看出,270行把数据读出来了。。。


顺便查了一下android中的sensor的实现方法。

https://source.android.com/devices/sensors/sensor-stack.html  官方的介绍。sensor层次的介绍,不是很详细。

https://docs.google.com/file/d/0B2IJqxU5nzCyQWZ1TzhGd3FUWlNCQjhqV0psV1l3dw/edit  2012的文档,现在的实现有变化,大致可以参考一下。

http://processors.wiki.ti.com/index.php/Android_Sensor_PortingGuide  内核层的更改方法。


手上没有nexus5的内核源码,所以暂时没有跟n5中的step counter的内核中的驱动实现。不过这个跟踪过程比较简单了。





android中的计步问题及计步传感器分析

标签:

原文地址:http://blog.csdn.net/wfing/article/details/43488181

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!