Sensor框架理解
来源:互联网 发布:win7重置网络命令 编辑:程序博客网 时间:2024/05/06 22:41
在这个系列的文章我们只是为了讲清楚Sensor框架的设计和工作原理基于4.0,4.0以下的代码有所区别,尤其是2.2以下根本就没有Binder架构,不讲驱动,也不讲具体的某一个应用该怎么处理Sensor的数据。
一、整体的架构:
从这个图来看Sensor的架构还是非常的清淅,
黄色部分表示硬件,它要挂在I2C总线上
红色部分表示驱动,把驱动注册到Kernel的Input Subsystem上,然后通过Event Device把Sensor数据传到HAL层,准确说是HAL从Event读
绿色部分表示动态库,它封装了整个Sensor的IPC机制,如SensorManager是客户端,SensorService是服务端,而HAL部分是封装了服务端对Kernel的直接访问
蓝色部分就是我们的Framework和Application了,JNI负责访问Sensor的客户端,而Application就是具体的应用程序,用来接收Sensor返回的数据,并处理实现对应的UI效果,如屏幕旋转,打电话时灭屏,自动调接背光(这三个功能的具体实现会在以后分析)
相关代码:
从HAL到Framework:
Framework部分:
frameworks/base/core/java/android/hardware/SensorManager.java
frameworks/base/core/jni/android_hardware_sensorManager.cpp
下面的代码会生成到:libgui.so
frameworks/base/libs/gui/SensorManager.cpp
frameworks/base/libs/gui/SensorEventQueue.cpp
frameworks/base/libs/gui/SensorChannel.cpp
frameworks/base/libs/gui/Sensor.cpp
下面的代码会生成:libsensorservice.so
frameworks/base/services/sensorservice/SensorService.cpp
frameworks/base/services/sensorservice/SensorDevice.cpp
HAL部分:这部分代码最终会生成 sensor.default.so 到/system/lib/hw/
hardware/libhardware/include/hardware/Sensors.h
device/qcom/msm7627a/libsensors/Sensors.cpp
device/qcom/msm7627a/libsensors/SensorBase.h
device/qcom/msm7627a/libsensors/AccSensor.cpp
device/qcom/msm7627a/libsensors/ProximitySensor.cpp
device/qcom/msm7627a/libsensors/LightSensor.cpp
device/qcom/msm7627a/libsensors/TmdSensor.cpp
device/qcom/msm7627a/libsensors/MagnetoSensor.cpp
device/qcom/msm7627a/libsensors/GyroSensor.cpp
device/qcom/msm7627a/libsensors/InputEventRead.h
device/qcom/msm7627a/libsensors/InputEventRead.cpp
Drivers:
P-Sensor:
device/qcom/msm7627a/libsensors/Tmd2771.h
kernel/drivers/misc/Tmd2771.c
(从这个代码路径大家可以看出我用来分析的代码是高通7627a平台的,
和Google原生代码没什么差别,而MTK的代码差别就大了,从HAL层开始完全不一样。)
我们还是列一下Android一般有哪些Sensor吧!
AccelerometerSensor
MagneticSensor
OrientationSensor
ProximitySensor
LightSensor
Gyro
这是我们最常见手机上有的Sensor,不过一般低端手机是没有Gyro的,而A Sensor用的并不是三轴的而是两轴。
二、应用举例:
三、SensorService
服务程序启动,它是由SystemManager启动起来的:
frameworks/base/cmds/system_server/library/system_init.cpp
整个C/S通信的架构图:
需要特别说明的是,BpSensorServer并没有在系统中被用到,如果你从ISensorServer.cpp中把它删除也不会对Sensor的工作有任何影响。
它的工作被SensorManager.cpp所取代,ServiceManager直接获取上面System_init文件中添加的SensorService对像。
四、创建SensorManager
1. new SensorManager
它有两个地方去创建这个Sensor client Object,一个就是ContextImpl,另一个就是PowerManagerService中,contextImpl大家都明白是为了应用程序很方便的获取Service,PowerManager中为什么要创建这个对象我们后面再分析。
2.natvieClassInit
它在SensorManager(JAVA)的构造函数中被调用,作用就是创建一个Sensor.java类的实例对象。
3.sensors_module_init()
它也是在SensorManager(JAVA)的构造函数中被调用的,它的作用就是初始华SensorManager(cpp)。
通过getInstance()就可以知道它是一个单件类,实例的创建由其父类Singleton<SensorManager>,SensorManager只需要在实现文件调用以下的代码:
ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager)
接着是SensorManager(cpp)的构造函数也没有做什么就是通过ServiceManager获取了SensorService的实例对象。
4. onFirstRef的实例
其实SensorService在添加实例到ServiceManager的时候就已经实例化过后了,因为在Binder.c中就会保存对它的引用,而RefBase的意思就是用来管理对像的引用,所以它会在对象第一次被引用的时候就调用onFirstRef。
接下来我们看看SensorService::onFirstRef里面做了哪些工作。
5. 创建SensorDevice
SensorDevice的构造函数:
这句话的意思是JNI加载HAL的库文件,并创建SensorModle的对象,Sensor的库文件通常是sensor.default.so上图接下来是sensors_open,这个函数并没有在SensorDevice中实现,而是调用的HAL层的函数,相关代码路径已在上面列出。
我们看new sensors_poll_device_t(); 这部分代码就创建HAL和Kernel Event通信的类,还有Sensor数据读写管道的创建。返回open_sensors再看剩下的代码,就是创建sensors_poll_device_t对象并把sensor控制的相关函数指针赋值给它。
6. SensorDevice 调用get_sensors_list
这个方法还是调用到了HAL中,而HAL中的这个函数也就是返回以下数组:
我们需要特别关组的是第4,5个参数,第4参数Handle是对kernel而言的,如激活,读写event,代码中的说明: /* handle that identifies this sensors. This handle is used to activate
* and deactivate this sensor. The value of the handle must be 8 bits
* in this version of the API.
*/
而第五个参数是相对于上层代码而言。
7. mSensorDevice->activate
在获取到Sensor列表以后,我们就去激活每一个Sensor:
mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
从上面的sensors_poll_context_t()中sensors[]的定义我们可以找到Sensors[acc]对应的值为AccSensor。
mSensors[index]->enable(handle,enabled)目的就是打开这个Sensor,里面如何打开的?linux上面不是一切兼为文件吗?就是打开对应的驱动文件嘛,所以里面的东西我们就不看了,HAL我们只分析到Sensors.cpp。
8. 扩展Sensor list
好SensorDevice里面的初始化代码走完了,回到SensorService。
省去了很多的代码,从上面的代码可以看出如果有Gyro在Sensor List中,那么它就会注册RotationVector,Gravity,LinearAcceleration,Orientation,CorrectedGyro这些虚拟Sensor。这些Sensor又是如何与Kernel通信的呢,我们在第七节会来分析。
最后这个run方法不得不介绍,其实SensorService是继承了Thread,而线程函数就是threadLoop,这个threadLoop在干什么呢?我们也放到第七节来讲吧!
好SensorService的初始化工作也看完了。
9、返回到SensorManager(Java)
首先它也会获取Sensor列表。
然后创建SensorEventPool和SensorThread,但这儿还没有用到,在第六节会用到。
五、获取Sensor
这个很简单就不用解释了。六、注册SensorLisenter
1. new ListenerDelegate(SensorEventListener listener, Sensor sensor, Handler handler)
这儿要特别说明一下,在这个构造函数中会创建一个Handler,它会在获取到Sensor数据的时候被调用。
2. sensors_create_queue要注意一下SensorEventConnection的构造
SensorChannel构造://这部分还没有搞懂,这个管道的具体功能,接着往下分析希望能搞明白 3. sensors_data_poll七、Sensor的数据处理流程
八、校准
初始化校准
它都是把校准数据写在一些文件里的,qcom 7627a的路径是:
/persist/GsensorCalibrationData
/persist/MsensorCalibrationData
/persist/PSensorCalibrateData
然后在Hal中对应的Sensor的构造函数中去读数据,如P-sensor对应的TmdSensor
发ioctl到Tmd驱动程序中去,其实这个功能比较的简单,从TaosProxcalibateData的定义可以看出就是传一个大值和一个小值。- Sensor框架理解
- Sensor框架理解
- Sensor框架理解
- Sensor框架理解
- Sensor框架理解
- <3>Sensor框架理解
- SENSOR框架理解
- Sensor框架理解
- sensor框架解析
- Android Sensor底层框架
- Android Sensor 框架
- android5.0 sensor 框架
- MTK sensor 框架
- mtk 新sensor框架
- MTK sensor 框架
- android sensor 框架分析---sensor数据流分析
- android sensor 框架分析---sensor native分析
- android sensor 框架分析---sensor 总结
- Linux SD卡驱动开发
- Message Flood
- 软件工程——整体篇
- 开发一个android app需要的技术
- mysql 多个字段拼接 concat
- Sensor框架理解
- 进程和线程关系
- 初学者 java学习 关于static main的疑惑
- Ubuntu中SVN客户端安装+使用
- 【STM8S】STM8S之电量采集
- Servlet 3.0 新特性详解
- java中重写的hascode中的31是怎么来的
- 牛顿迭代法 c语言实现
- CNN卷积神经网络---反向传播(1,全链接bp算法)