Android Sensor传感器系统架构初探
Android 浅谈Sensor工作流程(一)

Android 浅谈Sensor工作流程(一)我们使用sensor 接口一般只要注册一下SensorListener 像下面这样ApiDemo:mGraphView = new GraphView(this); mSensorManager.registerListener(mGraphView,....);这里的listener 是因为sensor 状态变化要产生变化的控件,然后在控件里重载on SensorChanged 和onAccuracyChanged 方法public void onSensorChanged(int sensor, float[] values) publicvoid onAccuracyChanged(int sensor, int accuracy) SensorManager Sensor 主体代码和流程在frameworks/base/core/java/android/hardware/SensorMan ager.java 里面 1.registerListener 其实是调用registerLegacyListener:java代码:public boolean registerListener(SensorListener listener, int sensors, int rate) {result = registerLegacyListener(...);}复制代码2. registerLegacyListener 其实就是构造一个LegacyListener 对象并将其加入HashMap 中去java代码:private boolean registerLegacyListener(int legacyType, int type,SensorListener listener, int sensors, intrate){legacyListener = newLegacyListener(listener);mLegacyListenersMap.put(listene r, legacyListener); //private HashMap< p> LegacyListener> mLegacyListenersMap}复制代码3. LegacyListener 做了2 件事一个是调用我们重载的那2 个接口还有一个就是将sensor 的数据刷到我们的设备显示界面上去java代码:private class LegacyListener implements SensorEventListener{LegacyListener(SensorListener target) {mTarget = target;mSensors = 0;}public voidonSensorChanged(SensorEvent event) {mapSensorDataToWindow();mTarget.onSensorChanged( ...);//private SensorListener mTarget;}public void onAccuracyChanged(Sensor sensor, int accuracy) {}}复制代码。
轻松学Android开发之Android传感器Sensor精品PPT课件

12.2.5 亮度传感器
亮度传感器(Light),主要用来检测设备周围光线 强度。光强单位是勒克斯(lux),其物理意义是照 射到单位面积上的光通量。
【示例12-5】下面通过一个具体的案例来演示亮度 传感器的开发。
12.3 小结
12.2.3 方向传感器
方向传感器(Orientation)简称为O-sensor,主要感应方位的变化。现在已 经被SensorManager.getOrientation()所取代,我们可以通过磁力计 MagneticField和加速度传感器Accelerometer来获得方位信息。该传感器同 样捕获三个参数,分别代表手机沿传感器坐标系的X轴、Y轴和Z轴转过的 角度。
本章内容主要讲解了Android系统中,常用传感器的 开发及应用。本章重点在于如何在真机上测试自己 开发的应用程序,我们开发的程序最终都是运行在 真机上,掌握真机测试十分重要。读者可以在掌握 了这些传感器的使用之后,自主开发一些传感器小 应用程序,更加深入地学习传感器的应用。
为方便学习与使用课件内容,
values[2]:roll旋转角,围绕Y轴的旋转角。由静止状态开始,左右翻转, 取值范围为-90度到90度。
【示例12-3】下面通过一个具体的案例来演示方向传感器的开发。
12.2.4 重力传感器
重力传感器(Gravity)简称GV-sensor,主要用于输 出重力数据。在地球上,重力数值为9.8,单位是 m/s^2。坐标系统与加速度传感器坐标系相同。当设 备复位时,重力传感器的输出与加速度传感器相同。
registerListener(SensorEventListener listener, Sensor sensor, int rate)方法注册监听。 rate支持的参数如下: Sensor.manager.SENSOR_DELAY_FASTEST:延迟0ms,; Sensor.manager.SENSOR_DELAY_GAME:延迟20ms,适合游戏的频率; Sensor.manager.SENSOR_DELAY_UI:延迟60ms,适合普通界面的频率; Sensor.manager.SENSOR_DELAY_NORMAL:延迟200ms,正常频率; (4)实现SensorEventListener接口中下列两个方法,监听并取得传感器Sensor的状态。
AndroidSensor传感器系统架构初探

Android Sensor 传感器系统架构初探分类:Android系统2010-10-15 10:19 5438 人阅读评论(16)收藏举报1.体系结构2.数据结构3.四大函数本文以重力感应器装置G-sensor为例探索Android的各层次结构。
1.体系结构Android的体系结构可分为4个层次。
•第一层次底层驱动层,包括标准Linux , Android核心驱动,Android相关设备驱动,G-sensor的设备驱动程序即存在于此•第二层次Android标准C/C++库,包括硬件抽象层,Android各底层库,本地库,JNI•第三层次Android Java Framwork 框架层•第四层次Java应用程序本文重点关注硬件抽象层,JNI以及Framework 。
1.1硬件抽象层硬件抽象层通过例如open(), read(), write(), ioctl(), poll() 等函数调用的方式,与底层设备驱动程序进行交互,而这些函数调用是底层设备驱动程序事先准备好的。
用于交互的关键是文件描述符fd , fd通过open()打开G-sensor设备节点而得到,即fd=open ("/dev/bma220", O_RDONLY); 而/dev/bma220 这个设备节点是在底层设备驱动中注册完成的。
其他的函数调用如read(), write()等都通过该文件描述符fd对G-sensor设备进行操作。
1.2JNI (Java Native Interface)JNI层可以认为是整个体系结构中的配角,概括地讲,它就完成了一项任务,既实现从C++语言到Java语言的转换。
JNI层为Java Framework 层提供一系列接口,而这些接口函数的具体实现中,利用例如module->methods->open(), sSensorDevice->data_open(), sSensorDevice->poll() 等回调函数与硬件抽象层进行交互。
android驱动程序之-sensor

android驱动程序之-sensor上图是android系统架构图,从中可以得知,sensor必贯穿架构的各个层次。
按照架构层次,下⾯从五个⽅⾯来分析sensor架构:1. sensor架构之App层;2. sensor架构之Framework层;3. sensor架构之Libraries层;4. sensor架构之HAL层;5. sensor架构之Driver。
1. sensor架构之App层下⾯以g-sensor为例,写⼀个简单的apk,看⼀下sensor在App层到底是如何⼯作的,⼀般需要下⾯四个步骤来实现⼀个sensor应⽤。
Step1:通过getSystemService获取sensor服务,其实就是初始化⼀个SensorManager实例;1 SensorManager mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);Step2:通过SensorManager的getDefaultSensor⽅法获取指定类型的传感器的sensor对象;1 Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); // 重⼒感应Step3:实现SensorEventListener接⼝的onSensorChanged和onAccuracyChanged⽅法;1 SensorEventListenerlsn = new SensorEventListener() {2public void onSensorChanged(SensorEvent e) {3//当传感器的值发⽣变化时,会执⾏这⾥4 }56public void onAccuracyChanged(Sensor s, int accuracy) {7//当传感器的精度变化时,会执⾏这⾥8 }9 };Step4:通过SensorManager的registerListener⽅法注册监听,获取传感器变化值。
androidsensor框架分析

androidsensor框架分析5,sensor数据流分析前面几章做了很多准备和铺垫,这章终于可以分析sensor数据的传输流程了。
主要步骤如下,1,服务端通过HAL从驱动文件节点中获取sensor数据。
2,服务端通过管道发送数据。
3,客户端通过管道读取数据。
4,客户端吐出数据。
5.1服务端获取数据启动sensor服务之后,就会调用SensorService.cpp的threadLoop方法,该方法首先不断调用SensorDevice.cpp的poll方法获取sensor数据,1.do {2.ssize_t count = device.poll(mSensorEventBuffer, numEventMax);然后遍历activeConnections变量,向每一个客户端发送一份sensor数据。
1.for (size_t i=0 ; i < numConnections; ++i) {2.if (activeConnections[i] != 0) {3.activeConnections[i]->sendEvents(mSensorEventBuffer, count, mSensorEventScratch,4.mMapFlushEventsToConnections);poll方法调用流程图如下,这些方法都很简单,没什么可论述的。
加速度sensor的readEvents调用流程图如下,1,fill方法Accelerometer.cpp 的readEvents中调用fill方法如下,ssize_t n = mInputReader.fill(data_fd);传入的data_fd是NativeSensorManager.h的SensorContext 结构体的变量。
见第二章2.1.2 小节。
fill方法如下,1.ssize_t InputEventCircularReader::fill(int fd)2.{3.size_t numEventsRead = 0;4.if (mFreeSpace) {5.const ssize_t nread = read(fd, mHead, mFreeSpace * sizeof(input_event));6.if (nread<0 || nread % sizeof(input_event)) {7.// we got a partial event!!8.return nread<0 ? -errno : -EINVAL;9.}10.numEventsRead = nread / sizeof(input_event);11.if (numEventsRead) {12.mHead += numEventsRead;13.mFreeSpace -= numEventsRead;14.if (mHead > mBufferEnd) {15.size_t s = mHead - mBufferEnd;16.memcpy(mBuffer, mBufferEnd, s * sizeof(input_event));17.mHead = mBuffer + s;18.}19.}20.}21.return numEventsRead;22.}1.struct input_event* const mBuffer;2.struct input_event* const mBufferEnd;3.struct input_event* mHead;4.struct input_event* mCurr;5.ssize_t mFreeSpace;mBuffer表示未读事件;mHead表示未读事件的第一个,初始为缓冲区首部.mBufferEnd表示未读事件的最后一个,初始为缓冲区尾部.mCurr表示当前未读事件struct input_event结构体定义在kernel/include/uapi/linux/input.h中,1.struct input_event {2.struct timeval time;3.__u16 type;//类型,比如sensor,按键事件等4.__u16 code;5.__s32 value;//具体的数值6.};2,获取sensor值,1.while (count && mInputReader.readEvent(&event)) {2.int type = event->type;3.if (type == EV_ABS) {4.float value = event->value;5.if (event->code == EVENT_TYPE_ACCEL_X) {6.mPendingEvent.data[0] = value * CONVERT_ACCEL_X;7.} else if (event->code == EVENT_TYPE_ACCEL_Y) {8.mPendingEvent.data[1] = value * CONVERT_ACCEL_Y;9.} else if (event->code == EVENT_TYPE_ACCEL_Z) {10.mPendingEvent.data[2] = value * CONVERT_ACCEL_Z;11.}12.} else if (type == EV_SYN) {13.switch (event->code){14.case SYN_TIME_SEC:15.{16.mUseAbsTimeStamp = true;17.report_time = event->value*1000000000LL;18.}19.break;20.case SYN_TIME_NSEC:21.{22.mUseAbsTimeStamp = true;23.mPendingEvent.timestamp = report_time+event->value;24.}25.break;26.···27.mInputReader.next();首先获取加速度sensor三个方向上的值,然后获取对应的时间。
Android感应检测Sensor(简单介绍)

Android感应检测Sensor(简单介绍)2、Android感应检测管理----SensorManager感应检测功能:1、取得SensorManager使用感应检测Sensor首要先获取感应设备的检测信号,你可以调用Context.getSysteService(SENSER_SERVICE)方法来取得感应检测的服务2、实现取得感应检测Sensor状态的监听功能实现以下两个SensorEventListener方法来监听,并取得感应检测Sensor状态:1.//在感应检测到Sensor的精密度有变化时被调用到。
2.public void onAccuracyChanged(Senso sensor,int accurac y);3.//在感应检测到Sensor的值有变化时会被调用到。
4.public void onSensorChanged(SensorEvent event);3、实现取得感应检测Sensor目标各类的值实现下列getSensorList()方法来取得感应检测Sensor的值;1.List<Sensor> sensors = sm.getSensorList(Sensor.TYPE_TE MPERATURE);4、注册SensorListener1.sm.regesterListener(SensorEventListener listener, Sensor sensor, int rate);第一个参数:监听Sensor事件,第二个参数是Sensor目标种类的值,第三个参数是延迟时间的精度密度。
延迟时间的精密度参数如下:因为感应检测Sensor的服务是否频繁和快慢都与电池参量的消耗有关,同时也会影响处理的效率,所以兼顾到消耗电池和处理效率的平衡,设置感应检测Sensor的延迟时间是一门重要的学问,需要根据应用系统的需求来做适当的设置。
感应检测Sensor的硬件检测组件收不同的厂商提供。
Android 系统Gsensor系统架构

Android 系统Gsensor系统架构一、首先建立这样一个全局的观念:Android中sensor在Android系统架构中的位置及其工作。
方框图如下:从以上方框图中,可以看出Android中sensor在系统分为四层:驱动层(Sensor Driver)、硬件抽象层(Native)、中间层(Framework)、应用层(Java)。
硬件抽象层与中间层可以合并一起作为Framework层。
针对我们xx这里一个具体的Gsensor,下面将以具体的源码形式来讲解以上的这个系统框图。
二、驱动层(Sensor Driver Layer)芯片ADXL345为GSensor,至于硬件的具体工作原理,须分析ADXL345的DataSheet。
驱动源码位于:xx\custom\common\kernel\accelerometer\adxl345目录。
由于ADXL345是以I2C形式接口挂接到Linux系统,因此同时需要分析Linux的I2C子系统架构(略)。
其源码位于:1、xx\platform\xx\kernel\drivers\i2c2、kernel\drivers\i2c查看ADXL345.c文件,分析针对于其硬件工作原理的几个函数。
硬件初始化:[cpp] view plaincopystatic int adxl345_init_client(structi2c_client *client, int reset_cali) { structadxl345_i2c_data *obj = i2c_get_clientdata(client);int res = 0; adxl345_gpio_config();//配置GPIO口,这里由于不使用中断,所以将中断引脚配置成输入输出口。
res =ADXL345_CheckDeviceID(client); //检测设备ID,通过读ADXL345的DEVID寄存器if(res !=ADXL345_SUCCESS) { returnres; } res =ADXL345_SetPowerMode(client, false);//设置电源模式,ADXL345有几种电源模式,这里设置false值指不让芯片处于messure模式if(res != ADXL345_SUCCESS) { return res; }res = ADXL345_SetBWRate(client,ADXL345_BW_100HZ);//设置带宽,100Hz if(res != ADXL345_SUCCESS ) //0x2C->BW=100Hz{ return res; } //设置数据格式,具体见datasheet res =ADXL345_SetDataFormat(client,ADXL345_FULL_RES|ADXL345_RANGE_2G);if(res != ADXL345_SUCCESS) //0x2C->BW=100Hz{ return res; }gsensor_gain.x = gsensor_gain.y = gsensor_gain.z =obj->reso->sensitivity; //设置中断寄存器,关闭中断res = ADXL345_SetIntEnable(client, 0x00);//disable INT if(res !=ADXL345_SUCCESS) { return res; } if(0 != reset_cali){ /*reset calibration only in power on*/res = ADXL345_ResetCalibration(client);if(res != ADXL345_SUCCESS){ return res; } }#ifdef CONFIG_ADXL345_LOWPASSmemset(&obj->fir, 0x00, sizeof(obj->fir));#endif return ADXL345_SUCCESS; } 函数的分析都注释在原理里,红色部分。
Android系统下sensor驱动架构简介及使用说明

Sensor驱动架构简介及使用说明版本日期描述作者审核V1.02012-6-10针对各种sensor的共性与差异编写的统罗伟一架构,支持挂接重力传感器、地磁传感器、陀螺仪、光感、距离感应、温度感应等设备,可以很方便地兼容不同厂家的各种sensor。
V1.12012-8-9增加SENSOR自动兼容,所有SENSOR均可以同时选上,SENSOR自动探测和识别。
1.sensor架构简介1.1编写目的到目前为止,sensor的android硬件抽象层已经统一,但是各种产品和项目中仍用到了各种形形色色的传感器,并且驱动基本上是重新编写和调试一遍,然后重新解决一轮BUG。
调试的时间少则一天,多则数天,如果驱动写的不好,容易引入BUG。
鉴于这种情况,对所有sensor的共性与差异进行思考后发现,其实不同的sensor工作原理是相似的,仅有部分有差异,例如初始化、寄存器地址、上报方式、IOCTL等几个,其他的大部分都是相同的。
因此花了数天时间设计和编写了这套sensor架构,该架构特别注意以下几点:兼容性好、使用简单、结构清晰、可读性强。
1.2结构图整个代码存放于文件夹sensors下,包括两个主文件sensor-dev.c和sensor-i2c.c,几个芯片级文件夹accel、compass、gyro、lsensor、psensor、temperature。
其中,sensor-dev.c对sensor操作进行统一处理,包括驱动挂载、中断或轮训处理、IOCTL 处理、差异性接口的统一回调处理等,sensor-i2c.c是所有sensor的i2C操作接口,包括带寄存器和不带寄存器两种;accel目录下存放不同类型的gsensor;compass 目录下存放不同类型的地磁传感器;gyro目录下存放不同类型的陀螺仪;lsensor 目录下存放不同类型的光传感器;psensor目录下存放不同类型的距离传感器;temperature目录下存放不同类型的温度传感器。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
∙第一层次底层驱动层,包括标准Linux,Android核心驱动,Android相关设备驱动,G-sensor的设备驱动程序即存在于此∙第二层次Android标准C/C++库,包括硬件抽象层,Android各底层库,本地库,JNI∙第三层次Android Java Framwork框架层∙第四层次Java应用程序本文重点关注硬件抽象层,JNI以及Framework。
1.1 硬件抽象层硬件抽象层通过例如open(), read(), write(), ioctl(), poll()等函数调用的方式,与底层设备驱动程序进行交互,而这些函数调用是底层设备驱动程序事先准备好的。
用于交互的关键是文件描述符fd,fd通过open()打开G-sensor设备节点而得到,即fd = open ("/dev/bma220", O_RDONLY);而/dev/bma220这个设备节点是在底层设备驱动中注册完成的。
其他的函数调用如read(), write()等都通过该文件描述符fd对G-sensor设备进行操作。
1.2 JNI (Java Native Interface)JNI层可以认为是整个体系结构中的配角,概括地讲,它就完成了一项任务,既实现从C++语言到Java语言的转换。
JNI层为Java Framework层提供一系列接口,而这些接口函数的具体实现中,利用例如module->methods->open(),sSensorDevice->data_open(), sSensorDevice->poll()等回调函数与硬件抽象层进行交互。
而这些open(), poll()回调函数在硬件抽象层中具体实现。
1.3 Java FrameworkFramework层提供各种类和类的对象,可作为系统的守护进程运行,也可供上层应用程序的使用。
例如类SensorManager,它作为系统的守护进程在初始化的时候开始运行,其子类SensorThread中的子类SensorThreadRunnable通过sensors_data_poll()实现了对G-sensor数据的轮训访问,而sensors_data_poll()通过JNI层转换到硬件抽象层去具体实现poll()。
2 数据结构一般境况下,硬件抽象层对硬件的描述都分为control和data两大类。
2.1 sensors_control_context_tstruct sensors_control_context_t {struct sensors_control_device_t device;int fd;};struct sensors_control_device_t {struct hw_device_t common;int (*open_data_source)(struct sensors_control_device_t *dev);int (*activate)(struct sensors_control_device_t *dev, int handle, int enabled); int (*set_delay)(struct sensors_control_device_t *dev, int32_t ms);int (*wake)(struct sensors_control_device_t *dev);};2.2 sensors_data_context_tstruct sensors_data_context_t {struct sensors_data_device_t device;int fd;};struct sensors_data_device_t {struct hw_device_t common;int (*data_open)(struct sensors_data_device_t *dev, int fd);int (*data_close)(struct sensors_data_device_t *dev);int (*poll)(struct sensors_data_device_t *dev,sensors_data_t* data);}struct hw_device_t {uint32_t tag; uint32_t version;struct hw_module_t* module;int (*close)(struct hw_device_t* device);};struct hw_module_t {uint32_t tag; uint16_t version_major; uint16_t version_minor;const char *id; const char *name; const char *author;struct hw_module_methods_t* methods;};struct hw_module_methods_t {int (*open)(const struct hw_module_t* module, const char* id,struct hw_device_t** device);};下文将通过对(*open), (*open_data_source), (*data_open)和(*poll)的代码分析,探索Android的各层次架构。
3 四大函数3.1 module->methods->open()1) FrameworkSensorService作为系统守护进程运行,其类的构造函数实现_sensors_control_init()。
2) JNI为_sensors_control_init()提供接口android_init(),并执行回调函数module->methods->open();3) 硬件抽象层具体实现(*open),该函数为所有G-sensor回调函数的指针赋值。
3.2 sSensorDevice->open_data_source()1) FrameworkSensorService作为系统守护进程运行,其类的一个公有成员ParcelFileDescriptor通过实现_sensors_control_open()得到设备的文件描述符。
2) JNI为_sensors_control_open()提供接口android_open(),并执行回调函数sSensorDevice->open_data_source();3) 硬件抽象层具体实现(*open_data_source),该函数通过打开G-sensor的设备节点得到文件描述符fd = open ("/dev/bma220", O_RDONLY);4) 设备驱动层通过misc_register()对G-sensor设备进行注册,建立设备节点。
3.3 sSensorDevice->data_open()1) FrameworkSensorManager作为系统守护进程运行,其子类SensorThreadRunnable的行为函数run()实现sensors_data_open()。
2) JNI为sensors_data_open()提供接口sensors_data_open(),并执行回调函数sSensorDevice->data_open();3) 硬件抽象层具体实现(*data_open),该函数的功能就是将已经得到的文件描述符fd复制一份到sensors_data_context结构体中的dev->fd,以便为处理数据的回调函数如(*poll)使用。
3.4 sSensorDevice->poll()1) FrameworkSensorManager作为系统守护进程运行,其子类SensorThreadRunnable的行为函数run()实现sensors_data_poll(values, status, timestamp),其目的是通过此函数得到从底层传上来的有关G-sensor的数据values, status和timestamp,再通过此类的一个行为函数listener.onSensorChangedLocked(sensorObject, values, timestamp, accuracy);为上层应用程序提供了得到G-sensor设备数据的接口函数。
2) JNI为sensors_data_poll()提供接口sensors_data_poll(),并执行回调函数sSensorDevice->poll(sSensorDevice, &data);其中,得到的data就是从底层传上来的G-sensor数据,然后通过下图的方式将data中对应的数据分别赋给values, status和timestamp。
3) 硬件抽象层具体实现(*poll),该函数通过ioctl()实现与底层驱动程序的交互。
ioctl(dev->fd, BMA220_GET_ORIENTATION, &orient_value);其中,dev->fd即刚才由(*data_open)得到的文件描述符,BMA220_GET_ORIENTATION 为ioctl的一个命令,具体实现由底层驱动程序完成,orient_value即得到的G-sensor数据,它通过下图的方式将相对应的数据赋给了data结构体中的values, status和time,从而最终实现了从底层到上层的数据通信。
4) 设备驱动层与硬件抽象层交互的read(), write(), ioctl()函数由设备驱动实现。
以ioctl()的一条命令BMA220_GET_ORIENTATION为例,通过bma220_get_orientation(data)得到G-sensor的数据data,然后将其从内核空间上传到用户空间的arg.。