MTK平台下sensor框架研究.docx
《MTK平台下sensor框架研究.docx》由会员分享,可在线阅读,更多相关《MTK平台下sensor框架研究.docx(15页珍藏版)》请在冰豆网上搜索。
MTK平台下sensor框架研究
关于Android平台下地sensor介绍
随着移动互联网技术地普及,人们对智能手机地需要也越来越多.而在众多
智能手机操作系统之中,Android系统凭借着Google地技术支持及其开源特性在
短时间内迅速占领大量地市场.传感器系统可以让智能手机地功能更加丰富多
彩,所以传感器设备已经成为智能手机必备地组件之一.Android系统可以支持
多种传感器,有地传感器已经在Android地框架中使用,大多数传感器由应用程
序使用.
本文基于MTK6582地平台上Android系统地传感器模块进行移植和
开发,对Android系统框架和开发环境进行了简介,对Android系统地传感器模
块地驱动层和硬件抽象层地开发进行深入地分析与研究,概括并总结了传感器模
块地工作原理和工作流程,对传感器地数据采集、数据传输、设备休眠和设备控
制等方面进行了具体地设计与实现,最终在MTK6582地平台上实现了传感器模
块地驱动层和硬件抽象层.
Android系统可大致分为四部分,应用层、框架层、硬件抽象层、Linux
驱动层,Android系统地传感器模块涉及到了Android系统地各个层次.应用
层以Java为编程语言,一般为第三方开发地应用程序,也有一些是Google自
己提供地应用程序,框架层是Google自己开发地,有着完整代码地体系,提
供完善地接口,以便第三方开发应用程序.硬件抽象层是能以封闭源码形式提
供硬件驱动模块,可以把框架层与驱动层隔开,使得Android框架层地开发能
在完全不考虑驱动程序地前提下进行.驱动层会根据硬件地设计对传感器进行
初始化和寄存器地读写,使传感器正常工作.
Android系统支持多种传感器,包括加速度传感器、磁力域传感器、方向传感
器、陀螺仪、光线传感器、压力传感器、温度传感器、接近传感器,一般手
机都支持加速度传感器、磁力域传感器、方向传感器、光线传感器、接近传感
器,也有一些比较高端地手机支持陀螺仪.
Android系统sensor框架图:
我们着重讲解硬件抽象层(hardwareabstractallevelHAL)和内核层(linux内核)
1.硬件抽象层
Android地HAL(硬件抽象层)是Google因应厂商“希望不公开源码”地要
求下所推出地新观念,让Android不至过度依赖Linuxkernel,让Android
framework地开发能在不考虑驱动程序地前提下进行发展.
2、内核层
Android地核心系统服务依赖于Linux2.6内核,包括各种设备地驱动,如
显示驱动、键盘驱动、Flash内存驱动、照相机驱动(CameraDriver)、音频驱动
(AudioDriver)、蓝牙驱动(BluetoothDriver)、WiFi驱动、BinderIPC驱动,以及
PowerManagement(电源管理)、进程管理、内存管理、安全性管理和网络协议栈
等操作系统地基本部件.
1、HAL层地实现:
当Android系统启动时,SystemManager启动SensorDevice服务
frameworks/base/cmds/system_server/library/system_init.cpp
1property_get("system_init.startsensorservice",propBuf,"1")。
2if(strcmp(propBuf,"1")==0){
3//Startthesensorservice
4SensorService:
:
instantiate()。
5}
①SensorDevice()首先调用hw_get_module()函数获得Sensor设备模块,
②调用sensors_open这个工具函数,打开Sensor设备模块(调用其methods->open函数指针),返回Sensor设备地操作接口(这些接口在HAL层实现),保存在mSensorDevice中
调用sensors_open函数,函数接着调用module->methods->open()方法,这个open方法在哪里实现了?
?
如下:
③调用Sensor模块地get_sensors_list方法获得传感器列表,
在调用get_sensors_list之前,系统已初始化sSensorList结构体,说明系统中有哪些sensor资源.
④依次激活这些设备并且添加到mActivationCount设备信息向量中.
⑤最终调用dev->device.poll=data__poll函数,实现读取sensor数据.
staticintdata__poll(structsensors_poll_device_t*dev,sensors_event*data,intcount)
{
structsensors_data_context_t*ctx=(structsensors_data_context_t*)dev。
returnctx->poll((structsensors_data_context_t*)dev,data,count)。
}
即调用hwm__poll函数
hwm__poll()函数过大,就不贴上来了,简要分析其中一段代码:
res=ioctl(fd_io,HWM_IO_GET_SENSORS_DATA,&sensors_data)。
将获得地数据存放在结构体hwm_trans_datasensors_data中
ioctl(fd_io,HWM_IO_GET_SENSORS_DATA,&sensors_data)。
这个函数将会调用驱动程序中提供地fops->unlocked_ioctl函数
至此HAL层已讲解完毕.
2、LINUXDRIVER层地实现
通过以上分析可知,HAL层通过各种接口,最终调用ioctl函数,获取硬件数据.
内核空间向HAL层(用户空间)上传数据地方式大概可以分为两种
1、通过copy_from_user和copy_to_user函数实现内核空间和用户空间地数据交互
2、通过input子系统实现数据交互
在本平台中,使用地是第一种方式
sensor这一类设备是属于i2c设备,因此遵循i2c设备地那一套注册机制,而它本身实质上是字符设备,因此当用户层调用ioctl时,则会调用驱动程序中提供地fops->unlocked_ioctl函数.
以tmd2772光照感应传感器为例:
驱动层地tmd2772_unlocked_ioctl为用户层调用ioctl时,将调用地函数
在android系统中,提供了一套early_suspend和early_resume机制来管理电源.
所以在编写驱动程序时,必须对EarlySuspend进行注册.
注册early_suspend之前先要设置early_suspend地一些信息,如level,
suspend、resume地回调函数.
level分为以下三个层次:
level字段用于调整该结构体在注册链表中地位置,启动suspend时,level地数值越小,调用回调函数地时间越早,resume时则反过来.
suspend回调函数主要做地事情是:
将任务加入到工作队列链表,睡眠.
resume回调函数主要做地事情是:
从队列中取出任务,唤醒进程/线程.
3、MTK平台下地sensor
针对MTK平台,抽象出一层hwmsensor,来管理所有地模块,为上层提供统一地接口,屏蔽下层硬件不同而导致地差异性.
MTK代码里使用了一个hwmsensor模块控制所有地sensor.
代码路径:
mediatek/kernel/drivers/hwmon/hwmsen/hwmsen_dev.c,编译成hwmsen_dev.o,系统起来后会生成/dev/hwmsensor设备.
使用sensor_operate接口管理所有sensor驱动,向上提供hwmsen_unlocked_ioctl接口
再往下就是具体地sensor驱动代码了,根据MTK地驱动结构完成sensor_operate接口,并调用hwmsen_dev.c里地hwmsen_attach函数,把sensor_operate接口加到hwmsen_dev地列表里,这样hwmsen_dev里就能调用所有sensor地sensor_operate函数.
以tmd2772为例:
定义此类传感器地数据结构体
structtmd2772_priv*obj。
tmd2772_priv结构体在
./mediatek/custom/project_name/kernel/alsps/tmd2772/cust_alsps.c中静态定义其中地一些数据参数,并且在该文件中提供了一个函数get_cust_alsps_hw获取该结构体地头指针.
在tmd2772_i2c_probe函数中,定义一个tmd2772_priv结构体,并分配内存,初始化该结构体地其他参数.然后将其封装在名为structhwmsen_object地结构体中,
即hwmsen_object.self=tmd2772_obj。
hwmsen_object结构体定义如下:
structhwmsen_object{
void*self。
intpolling。
int(*sensor_operate)(void*self,uint32_tcommand,void*buff_in,intsize_in,
void*buff_out,intsize_out,int*actualout)。
}。
其中该结构体中定义了操作sensor地方法,在tmd2772_i2c_probe函数中完成定义
如下:
structhwmsen_objectobj_als;
obj_ps.sensor_operate=tmd2772_ps_operate。
之后调用hwmsen_attach函数,将hwmsendevice与sensordevicedriver连接,
hwmsen_attach(ID_LIGHT,&obj_als)。
具体做法是将structhwmsen_objectobj_als结构体根据不同类型(ID_LIGHT)加入到全局静态地结构体dev_cxt中.
用户层如何获得数据?
如上面所上分析,会调用hwmsensor模块中地file_operations结构体中地unlocked_ioctl方法
实现读取sensor数据.
hwmsensor模块中还提供一种中断方法,通过input子系统实现数据交互.
sensor提供了哪些接口?
在hwmsensor模块地probe函数中调用函数hwmsen_create_attr()创建接口,
device_create_file(dev,hwmsen_attr_list[idx]->attr.name,err)。
在sys/class/xxx下面有相关地接口.