android系统之sensor学习.docx_第1页
android系统之sensor学习.docx_第2页
android系统之sensor学习.docx_第3页
android系统之sensor学习.docx_第4页
android系统之sensor学习.docx_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

android系统之sensor学习 Sensor作为Android系统的一个输入设备,对Android设备来说是必不可少的。Sensor主要包括G-Sensor、 LightsSensor、ProximitySensor、TemperatureSensor等。这里主要对G-Sensor模块进行解析。我的平台是AML8276,android系统是4.0.4,kernel是3.0,所用的gsensor是kionix_accel;整个sensor的工作包括driver, HAL, framework(c/c+, java)和application层;首先我们从驱动driver开始,然后一层层向上看;一, 驱动层在驱动层,内核需要增加和修改的部分包括: 1,相应硬件模块驱动代码,包括两个文件,这里是kionix_accel.h,kionix_accel.c,分别将kionix_accel.h放到kernel/common/customer/include/linux/中,将kionix_accel.c放到kernel/customer/drivers/misc/中; 2,编译目录(kernel/customer/drivers/misc/)下的Makefie 和KConfig,在KConfig中增加:config SENSORS_KXTJ2 tristate KXTJ2 accelerometer sensor driver depends on I2C help Say yes here to support Kionixs KXTJ2 accelerometer sensor在MakeFile 下增加:obj-$(CONFIG_SENSORS_KXTJ2) += kionix_accel.o 3, 在平台编译配置文件中(也就是make menuconfig生成的),增加:CONFIG_SENSORS_KXTJ2=y-指定编译到内核中,如果是m则编译成ko; 4,在平台模块代码文件中(kernel/customer/boards/board-m6g17-t069.c),在相应的i2c配置中,增加此模块:static struct i2c_board_info _initdata aml_i2c_bus_info_b = .#ifdef CONFIG_SENSORS_KXTJ2 I2C_BOARD_INFO(kionix_accel, KIONIX_ACCEL_I2C_ADDR), /.irq = INT_GPIO_1, .platform_data = (void *) &kionix_accel_pdata, ,#endif经过以上几步操作以后,就可以将此模块驱动编译到内核中。G-sensor driver工作的大致流程:系统开机后,内核会先加载i2c总线驱动,然后再加载设备驱动,在设备驱动中的init函数中通过调用 i2c_add_driver(&kionix_accel_driver)注册i2c_driver;此函数将driver注册到 i2c_bus_type的总线上,此总线的匹配规则是利用i2c_client的名称和i2c_driver中id_table中的名称作匹配。其中 i2c_client是系统自动创建的,board-m6g17-t069.c文件中的结构变量static struct i2c_board_info _initdata aml_i2c_bus_info_b中需要添加G-sensor的设备信息。当匹配成功时,i2c_driver中的probe()函数开始执行。module_init(kionix_accel_init)-i2c_add_driver(&kionix_accel_driver)-static struct i2c_driver kionix_accel_driver = .driver = .name = KIONIX_ACCEL_NAME, .owner = THIS_MODULE, , .probe = kionix_accel_probe, .remove = _devexit_p(kionix_accel_remove), .id_table = kionix_accel_id,; Probe()函数kionix_accel_probe()主要完成以下功能:1.从i2c_client结构中得到初始化信息2.创建G-sensor的工作队列2.注册input_device设备3.读取Chip ID4.设置寄存器,使能G-sensor5.设置并启动中断当G-sensor上报数据的时候会触发中断,然后在中断处理函数中提交一个报值的任务到队列中并禁止中断。在工作队列中读数G-sensor的数据并上报到input子系统中,最后使能中断。系统启动后,驱动会在/sys/class/input/inputX下生成相应的设备文件,里面name节点包含有相应的模块名;shellcapabilitiesdeviceevent4idmodaliasnamephyspowerpropertiessubsystemueventuniq同时会在/dev/input/里面也会生成inputX的节点,它是用来实际读取数据的。驱动在工作的时候,主要分两部分:数据的采集及上报、设备的控制;1,数据的采集主要是指通过I2C从硬件设备读取相关的数据并把数据上报,读取数据有两种方式,一种是通过中断,当有数据时,设备会发出中断信号给驱动,驱动去采集,另一种就是采用定时器不断的去定时采集数据;由于sensor也属于输入设备(还有TouchScreen,Keyboard,Mouse,Sensor等),所以上报的时候,也要报到linux kernel的输入子系统里面,上层通过相应的子系统设备节点读取数据。上报数据的过程:static void report_abs(void) shortx,y,z,tilt; if(read_data(&x,&y,&z,&tilt) != 0) /* report the absulate sensor data to input device */input_report_abs(idev, ABS_X, y); input_report_abs(idev, ABS_Y, x); input_report_abs(idev, ABS_Z, z); input_sync(idev);2,设备的控制包括打开、关闭、设置参数和使能等,一般上层会通过ioctl方式来交互二, HAL层android的HAL层,相当于它的应用层中的驱动,HAL与内核硬件驱动密切相关,由于硬件模块的差别性,HAL代码的编写也各有差别,特别是关于sensor的HAL代码基本上都要自己去实现,但基本架构是一样的。sensor的HAL结构基本分两部分,一部分是控制操作,一部分是数据操作;1,首先在androidhardwarelibhardwareinclude hardware目录下,有sensors.h文件,定义了struct sensors_module_t(sensor模块对象结构,如get_list),struct sensor_t(具体sensor设备对象结构,如名字,类型),struct sensors_poll_device_t(每个设备操作数据结构,如激活、设置参数、poll等), typedef struct sensors_event_t(sensor的事件结构,如类型、数据), 同时也定义了所有传感器的类型:/* Sensor types*/#define SENSOR_TYPE_ACCELEROMETER 1#define SENSOR_TYPE_MAGNETIC_FIELD 2#define SENSOR_TYPE_ORIENTATION 3#define SENSOR_TYPE_GYROSCOPE 4#define SENSOR_TYPE_LIGHT 5#define SENSOR_TYPE_PRESSURE 6#define SENSOR_TYPE_TEMPERATURE 7 / deprecated#define SENSOR_TYPE_PROXIMITY 8#define SENSOR_TYPE_GRAVITY 9#define SENSOR_TYPE_LINEAR_ACCELERATION 10#define SENSOR_TYPE_ROTATION_VECTOR 11#define SENSOR_TYPE_RELATIVE_HUMIDITY 12#define SENSOR_TYPE_AMBIENT_TEMPERATURE 13在android/hardware/amlogic/sendsors/aml_gsensor目录是特定平台实际HAL的代码存放的位置,当然也有的平台只会给一个so的文件,不给源码。在sensor_aml.cpp中,首先要定义HAL_MODULE_INFO_SYM,这个是每个HAL模块必须的,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: Sensors module, author: Amlogic, methods: &sensors_module_methods, , get_sensors_list: sensors_get_sensors_list,;static int sensors_get_sensors_list(struct sensors_module_t* module, struct sensor_t const* list) *list = sSensorList; return ARRAY_SIZE(sSensorList);/* The SENSORS Module */static const struct sensor_t sSensorList = BMA250 3-axis Accelerometer, Bosch, 1, SENSORS_ACCELERATION_HANDLE, SENSOR_TYPE_ACCELEROMETER, 4.0f*9.81f, (4.0f*9.81f)/1024.0f, 0.2f, 0, ,#ifdef ENABLE_LIGHT_SENSOR Light sensor, (none), 1, SENSORS_LIGHT_HANDLE, SENSOR_TYPE_LIGHT, 5000.0f, 1.0f, 1.0f, 20000, ,#endif;可以看出在事先定义当前支持的sensor模块,android通过module-get_sensors_list获取。获取module后,利用open_sensors();得到hw_device_t sensors_poll_device_tsensors_poll_context_t-device mSensor结构对象,这个结构对象在初始化时会创建相应的sensor对象,且它们都是以SensorBase为基础类,sensors_poll_context_t:sensors_poll_context_t() mSensorsaml_accel = new GSensor(); mPollFdsaml_accel.fd = mSensorsaml_accel-getFd(); mPollFdsaml_accel.events = POLLIN; mPollFdsaml_accel.revents = 0;#ifdef ENABLE_LIGHT_SENSOR mSensorsaml_light = new LightSensor(); mPollFdsaml_light.fd = mSensorsaml_light-getFd(); mPollFdsaml_light.events = POLLIN; mPollFdsaml_light.revents = 0;#endif通过mSensor对象就可以调用activate、setDelay、poll进行激活读取数据处理了。mSensorsaml_accel = new GSensor();在创建GSensor对象时会对/sys/class/input/inputX目录下的name读取,通过对比名称判断当前sensor到底是在哪个目录并记录下path,在后面对设备进行设置,也就是控制部分会用到这个目录下的结点;同时由于GSensor 是继承sensorBase的,所以在构造sendsorBase的时候会找到相应的/dev下的inputX设备open得到设备fd,用于后面读取数据,也就是数据部分。HAL层准备好后,最后会编译成一个库,这里为sensor.amlogic.so三, Framework层对于每一个模块,framework层是最复杂的,它涉及到java部分和C+部分,且根据功能,又可分为service部分和manager部分,它们之间是通过binder进行通信的。frameworks/base/libs/gui/ISensorServer.cppclass ISensorServer : public IInterfacepublic: DECLARE_META_INTERFACE(SensorServer); virtual Vector getSensorList() = 0; virtual sp createSensorEventConnection() = 0;在Android中,和Sensor相关的几个类是:SensorManager : 通过它实现系统对Sensor的相关调用。SensorEvent :对各个Sensor数据的封装,具体可以参考Android的开发文档。SensorEventListener :对Sensor数据的监视,一旦有数据,就会调相应的函数。Sensor : 对Sensor的封装。对于service部分:它是负责与HAL层建立联系并处理实际数据的服务。frameworks/base/services/sensorservice/sensorService.cpp , 它继承了public BnSensorServer系统启动时会执行systemProcess,同时会加载sensorService.java进程,在sensorService.java的构造函数中调用JNI方法_sensor_control_init()。sensorService.cpp中SensorService:onFirstRef()会被执行,会创建 SensorDevice& dev(SensorDevice:getInstance()对象,通过SensorService:threadLoop()里就对各个 sensor进行poll并将数据发送到对应的申请connection中connection-sendEvents(buffer, count, scratch);SensorDevice是一个单一对象类,故SensorDevice:getInstance()会在同一进程中只保留一个对 象,SensorDevice:SensorDevice()通过hardware.c中读取HAL层生成的sensor.amlogic.so库。对于manager部分:它是负责给应用程序提供接口的,与sensorserivce通过binder进行交互数据与控制。frameworks/base/core/java/android/hardware/SensorManager.javaframeworks/base/core/jni/android_hardware_SensorManager.cppframeworks/base/libs/gui/sensorManager.cppandroid_hardware_SensorManager.cpp:static JNINativeMethod gMethods = nativeClassInit, ()V, (void*)nativeClassInit , sensors_module_init,()I, (void*)sensors_module_init , sensors_module_get_next_sensor,(Landroid/hardware/Sensor;I)I, (void*)sensors_module_get_next_sensor , sensors_create_queue, ()I, (void*)sensors_create_queue , sensors_destroy_queue, (I)V, (void*)sensors_destroy_queue , sensors_enable_sensor, (ILjava/lang/String;II)Z, (void*)sensors_enable_sensor , sensors_data_poll, (IFIJ)I, (void*)sensors_data_poll ,;sensors_module_init()-SensorManager:getInstance();由于SensorManager也是单一对象类,这里生成实体对象;sensors_create_queue()-SensorManager& mgr.createEventQueue():sp SensorManager:createEventQueue() sp queue; Mutex:Autolock _l(mLock); while (assertStateLocked() = NO_ERROR) sp connection = mSensorServer-createSensorEventConnection(); if (connection = NULL) / SensorService just died. LOGE(createEventQueue: connection is NULL. SensorService died.); continue; queue = new SensorEventQueue(connection); break; return queue;通过创建一个connection来建立queuece,其实就是利用connection中与sensorService建立的channel:mSensorChannel = mSensorEventConnection-getSensorChannel();通过循环获取sensor list中的各个对象的属性:sensors_module_get_next_sensor()-sensorManager:getSensorList()-SensorManager:assertStateLocked()-mSensorServer-getSensorList() 通过binder从sensorService获取sensorlist;使能某一sensor对象:sensors_enable_sensor()-queue-enableSensor(sensor, delay)-mSensorEventConnection-setEventRate(handle, us2ns(us)-通过ISensorEventConnection对象与sensorService:SensorEventConnection进行交互-SensorService:SensorEventConnection:enableDisable(int handle, bool enabled)- SensorService:enable()-mActiveConnections.add(connection)只是将 connection加入到激活数组中,而并非直接使能或关闭硬件;循环监听事件:sensorChannel用一对pipe来sensorService到sensorEventQueue的事件信息。sensors_data_poll()-queue-read(&event, 1)-mSensorChannel-read()-通过pipe-SensorChannel:write()write() -SensorService:SensorEventConnection:sendEvents() send

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论