android系统之sensor学习
- 格式:docx
- 大小:40.16 KB
- 文档页数:8
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_KXTJ2tristate "KXTJ2 accelerometer sensor driver"depends on I2ChelpSay yes here to support Kionix's KXTJ2 accelerometer sensor在MakeFile 下增加:obj-$(CONFIG_SENSORS_KXTJ2) += kionix_accel.o3,在平台编译配置文件中(也就是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 __initdataaml_i2c_bus_info_b中需要添加G-sensor的设备信息。
当匹配成功时,i2c_driver中的probe()函数开始执行。
module_init(kionix_accel_init)---->i2c_add_driver(&kionix_accel_driver)----->st atic 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节点包含有相应的模块名;shell@capabilitiesdeviceevent4idmodaliasnamephyspowerpropertiessubsystemueventuniq同时会在/dev/input/里面也会生成inputX的节点,它是用来实际读取数据的。
驱动在工作的时候,主要分两部分:数据的采集及上报、设备的控制;1,数据的采集主要是指通过I2C从硬件设备读取相关的数据并把数据上报,读取数据有两种方式,一种是通过中断,当有数据时,设备会发出中断信号给驱动,驱动去采集,另一种就是采用定时器不断的去定时采集数据;由于sensor也属于输入设备(还有TouchScreen,Keyboard,Mouse,Sensor等),所以上报的时候,也要报到linux kernel的输入子系统里面,上层通过相应的子系统设备节点读取数据。
上报数据的过程:static void report_abs(void){short x,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,首先在android\hardware\libhardware\include \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获取。