Android Sendor框架介绍

来源:互联网 发布:新域名紧急升级访问 编辑:程序博客网 时间:2024/06/08 07:35

1    Sensors介绍

1.1      Android Sensors简介

       每一部搭载Android智能操作系统的设备都具有一系列传感器,用于测量运动,方向,和各种环境条件。如果你想要监测装置或三维运动定位,或者你想要监测在附近的一个设备的周围环境的变化,那么这些传感器能够提供原始数据供你分析和使用。例如,一个游戏可能从重力传感器得来的数据来推断用户的手势和动作,如倾斜,震动,旋转,或摆动。同样,一个天气应用程序可能使用温度传感器和湿度传感器来计算和报告天气情况,或一个旅游应用程序可以使用地磁传感器和加速度计的报告一个罗盘方位。

 

  Android平台支持传感器三大类:

  运动传感器

  这一类包括加速度计,重力传感器,陀螺仪,和旋转矢量传感器,步伐检测传感器,步数传感器。

  环境传感器

   如环境空气温度、压力和湿度,光照。这一类包括气压计,光度计,温度计。

   位置传感器

   这一类包括定位传感器和磁力计。

 

    这些传感器有的是基于硬件的,有的是基于软件的。

    基于硬件的传感器的物理组件内置到手机或平板设备。他们获得他们的数据,通过直接测量特定的环境性能,如加速度,地磁场强度,或角的变化。

    基于软件的传感器没有物理设备,他们获得的数据是从一个或多个硬件传感器计算出来的,线性加速度传感器和重力传感器。有时基于软件的传感器也被称为虚拟传感器或综合传感器。

    这篇文章中我们主要针对运动传感器作分析。其他sensors的详细介绍可以参考http://developer.android.com/guide/topics/sensors/sensors_overview.html。

1.2      Android sensors框架图

      

类别

名称

代码

用户空间

JAVA应用程序

用户实现

Java framework框架层

SensorManager.java

SensorListener.java

SensorEvent.java

...

JNI层

Andorid_hardware_SensorManager.cpp

Native层

SensorService.cpp

SensorDevice.cpp

SensorFusion.cpp

...

HAL硬件抽象层

用户实现sensor.c

内核空间

设备驱动程序

用户实现


















2    Android4.4 Sensors流程详细介绍

2.1     应用Application开发步骤

(1)获取传感器的管理器

     mSensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);

(2)获取想要使用传感器

       mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

(3)定义事件监听器,以便获取sensor数据

     mEventListener=new SensorEventListener();

       public void onSensorChanged(SensorEventevent){

            float[]values = event.values;

              mTextView.setText("Accekerometer:"+values[0]+","+values[1] + ", "+values[2]);

       }

(4)注册事件监听器

       mSensorManager.registerListener(mEventListener,mSenso,

                                                        rateUs,maxBatchReportLatencyUs);

(5)卸载事件监听器

       mSensorManager.registerListener(mEventListene 

2.2     SensorService的工作原理

      

   在android4.3时,Sensor Service 最为一个轻量级的线程,附属在system Servier 进程上启动。

这一点和anroid4.4不同。android4.4上。System Server不再使用。SensorServce作为一个独立的进程存在。

      SensorDevice::poll(): 调用HAL接口读取数据;如果应用注册了一个虚拟sensor,例如gravity sensor或者linear-acc sensor.那么poll取到数据后还要通过SensorFusion进行虚拟sensor数据的计算,

        count = device.poll(buffer,numEventMax);

        recordLastValue(buffer, count);

 

        // handle virtual sensors

        if (count && vcount) {

                 SensorFusion& fusion(SensorFusion::getInstance());

            for (size_t i=0 ; i<size_t(count) ;i++) {

                  fusion.process(event[i]);

            }

 ensorEventConnection::sendEvents():往消息队列中写入消息。应用通过监听读取数据。

2.3     SensorDevice对HAL的访问

      

       说明:Google为Sensor提供了统一的HAL接口,不同的硬件厂商需要根据该接口来实现并完成具体的硬件抽象层,

 

       Android中对获取sensor的接口定义在hardware/libhardware/include/hardware/hardware.h

其中里面有定义:inthw_get_module(const char *id, const struct hw_module_t **module);

 

       hw_get_module()会加载HAL模块,并返回HAL入口数据结构(hw_module_t)。HAL_MODULE_INFO_SYM默认是“HAL”,在hw_get_module中用dlsym获取。

在用户自己实现的sensor,c中,一定有如下类似的定义,以便被找到。

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: "Invensense module",

                author: "Invensense Inc.",

                methods: &sensors_module_methods,

                dso: NULL,

                reserved: {0}

        },

        get_sensors_list: sensors__get_sensors_list,

};

 

       Android中Sensor的HAL接口定义在:hardware/libhardware/include/hardware/sensors.h。不同厂商实现Sensor的HAL接口时,都是实现的此接口。在ingenic中,实现sensors,h的文件是sensors.c 。在invensense中。实现sensors.h的文件是sensors_mpl.cpp.

 

       上图中对HAL实现的就是invensense的代码流程。

 

    在invensense中,会创建一个sensor device实例,并把sensors_poll_device_t的接口暴露给SensorDevice.

 

    activate()即为触发。开始使用一个sensor或者关闭一个sensor都要调用此函数。即sensorservice中的enable()或者disable()都会调用此函数实现相关功能。

      

       batch()即为android4.4新增加的接口,用于低功耗下对sensor的支持,目前invensense对batch 支持的sensor有 :硬件的Acc、Gyro、Compress,和软件的GRV(GameRotationVector)、Step_Detector. 如果你的当前设备还不支持batch模式,那么你可以在调用batch函数时,设置batchms 为0。

      

       poll( )函数用来获取底层数据,并把结果放置在sensors_event_t中。对sensors_event_t的结构定义如下:

typedef struct sensors_event_t {

    /* must be sizeof(struct sensors_event_t) */

    int32_t version;

    int32_t sensor;

    int32_t type;

    int64_t timestamp;

    union {

        union {

            float           data[16];

            sensors_vec_t   acceleration;

            sensors_vec_t   magnetic;

            sensors_vec_t   orientation;

            sensors_vec_t   gyro;

            .....

    };

    uint32_t reserved1[4];

} sensors_event_t;

sensorservice和应用都是基于此结构辨别出一个event是哪种sensor的数据。从而读出里面的timestamp和原始数据

 

2.4     invensense 对sensor HAL数据读取的实现


在ensors_mpl中,poll()所检测的文件,是设备驱动负责写入,在invensense中,这些文件名称经常是/dev/iio:device** 。**代表了iio_device_num。sensor_mpl中获取这些文件的代码如下:

    mPollFds[mpl].fd = ((MPLSensor*)mSensor)->getFd();

    mPollFds[dmpOrient].fd = ((MPLSensor*)mSensor)->getDmpOrientFd();

    mPollFds[dmpSign].fd = ((MPLSensor*)mSensor)->getDmpSignificantMotionFd();

    mPollFds[dmpPed].fd = ((MPLSensor*)mSensor)->getDmpPedometerFd();

    mPollFds[compass].fd =mCompassSensor->getFd();

  libmllite为invensensor的数据处理库。包括对上述文件读取后的滤波处理、有倾斜后的数据处理、虚拟sensor的数据计算。源码在/hardware/invensense/65xx/libsensors_iio/software/core/mllite。所以在readEvents()之前会有一个 buildMpuEvent()的调用。

 

 

 


3    Android4.4 新技术点

       Android 4.4 支持两个新的传感器:测步器(Step Detector) 和计步器( Step Counter),同时支持Batching功能。这些可能都为穿戴时设备或低功耗作考虑

 

3.1     测步器(Step Detector)和计步器( Step Counter)

       Android4.4在框架上对这两种类型的支持,没有改动太多的代码。和其他的虚拟sensor一样。在sensors.h中仅仅新添加了宏定义而已。以便应用层找到此sensor,读出相关数据。

#define SENSOR_TYPE_STEP_DETECTOR                   (18)

#define SENSOR_TYPE_STEP_COUNTER                    (19)

 

真正对这两个sensors的实现是由用户完成的。在android4.4的HAL层,有invensense厂商对此的实现方法。在invensense的MPU6xxx/9xxx系列芯片中,新添加了DMP(DigitalMotion Processor)模块,在此模块内,完成了计步的功能。

       Step Detector:当用户迈开一步时,主要是分析加速度计的数据来判断用户是否有迈开步子的动作,如果有,就会触发一个event,以后的每一步都会触发一下event。

       Step Counter:从设备reboot开始,dmp一直统计所有的步数,写入到文件,下次reboot后,步数会清0。

 sensors_mpl读取step counts或者 step Detector 代码如下:

    nb = poll(mPollFds, numFds, polltime);

    if (nb > 0) {

        for (int i = 0; count && i < numSensorDrivers; i++) {

            if (i == mpl) {

                    ((MPLSensor*) mSensor)->buildMpuEvent();

            } else if (i == dmpPed) {

               LOGI("HAL: dmpPed interrupt");

               nb = ((MPLSensor*) mSensor)->readDmpPedometerEvents(data, count,

                       ID_P, SENSOR_TYPE_STEP_DETECTOR, 0);

            }

            nb = ((MPLSensor*) mSensor)->readEvents(data, count);    

      }

 

 

3.2     batch功能

       Android4.4 在框架上支持batching功能。

struct sensors_poll_device_t_1 {

    struct hw_device_t common;

    int (*activate)(struct sensors_poll_device_t *dev,

            int handle, int enabled);

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

    int (*batch)(struct sensors_poll_device_1* dev,

            int handle, int flags, int64_t period_ns, int64_t timeout);

    int (*flush)(struct sensors_poll_device_1* dev, int handle);

};

 

此功能的实现也是由用户在HAL层实现。在invensense中,batch 支持的sensor:硬件的Acc、Gyro、Compress,和软件的GRV(GameRotationVector)、Step_Detector

 


0 0
原创粉丝点击