概述
1 硬件工作原理
1.1 G-sensor主要管脚定义
上图是LIS3DHTR在TD_100中的原理图
l 电压:VDD:sensor的供电电源。
VDD_IO:sensor的IO电源。
l 中断:ACCEL_INT1
ACCEL_INT2:sensor的中断pin脚
l I2C:I2C_SCL
I2C_SDA:sensor和处理器通过I2C总线用I2C协议通信。
硬件上的正确连接才能确保sensor的正常工作。
具体详细的定义见原理图和datasheet。
1.2 Gsensor的工作原理
芯片会把感知的重力加速度分解在XYZ三个方向,经过模数转换通过I2C总线和处理器通信。
1.3 datasheet中Gsensor的重要寄存器
主要的是一些配置寄存器,需要通过他们来实现sensor在不同模式下的转换和一些功能设置。Gsensor的寄存器不是太多,可以参考datasheet。
2 软件目录结构
2.1 java层
Java层sensor的状态控制有SesnorService来负责, 它的java代码和JNI代码分别位于
l frameworks/base/services/java/com/android/server/SensorService.java
l frameworks/base/services/jni/com_android_server_SensorService.cpp
在java层Sensor的数据控制有SensorManager来负责,它的java代码和JNI代码分别位于:
l frameworks/base/core/java/android/hardware/SensorManager.java
l frameworks/base/core/jni/android_hardware_SensorManager.cpp
2.2 hardware层
Android对于Sensor的API定义在hardware/libhardware/include/hardware/sensor.h中,要求在sensor.so提供8个API函数(在第四部分会详细说明)
2.3 HAL层
l Vendor/marvell/dkb/libsensor目录下有lib_sensor.c和Android.mk
l vendor/marvell/generic/sensors-hal目录下有marvell sensors HAL层的实现
这一层的实现代码最后会在编译的过程中生成一个sensor.default.so.放在system/lib/hw下。
2.4 内核驱动层
Kernel/kernel/driver/hwmon目录下有sensors(例如:重力加速度计,陀螺仪,磁力计,光与距离传感器等)的驱动文件。
3 移植新模块
3.1 HAL层
在sensor的HAL代码已经实现的情况下,只要在sensor的信息列表的结构体中添加新的sensor信息就可以,以marvell的代码为例,只需要在结构体
sensor_info_t sensors[] = {
{
.name = "accelerometer",
.vendor = "ST",
.version = 1,
.type = SENSOR_TYPE_ACCELEROMETER,
.max_range = 2.0f * GRAVITY_EARTH,
.resolution = GRAVITY_EARTH/2048,
.power = 0,
.minDelay = 20,
.convert = &(convert_accelerometor),
},
};
中添加新的sensor信息就可以。
3.2 内核层
在kernel/kernel/driver/hwmon的目录下添加sensor的驱动文件(lis3dh_acc.c),如果有.h文件放在相应的目录下,使驱动中包含的头文件可以在编译时被找到,以lis3dh为例。
l 在kernel/kernel/driver/hwmon下添加驱动文件lis3dh_acc.c,在kernel/include/linux/I2C下添加lis3dh.h。
l 在kernel/kernel/driver/hwmon下的Kconfig和Makefile修改如下:
n config SENSORS_LIS3DH
tristate "STMicroelectronics LIS3DH Accelerometer Sensor"
depends on I2C
n config SENSORS_LIS3DH_POSITION
int "LIS3DH_ACCELELEROMETER Mounting Position on Board"
depends on SENSORS_LIS3DH
default "0"
help
Chip mounting position (pin 1).
0: top. upper-left
1: top. upper-right
2: top. lower-right
3: top. lower-left
4: bottom. upper-left
5: bottom. upper-right
6: bottom. lower-right
7: bottom. lower-left
n obj-$(CONFIG_SENSORS_LIS3DH) += lis3dh_acc.o
l 在版文件中添加并把编译开关打开
n 在板文件中要传的平台数据
#ifdef CONFIG_SENSORS_LIS3DH
static struct lis3dh_acc_platform_data lis3dh_pdata = {
.poll_interval = 10,
.min_interval = 10,
.axis_map_x = 0,
.axis_map_y = 1,
.axis_map_z = 2,
.negate_x = 1,
.negate_y = 0,
.negate_z = 1,
.gpio_int1 = 51,
.gpio_int2 = 52,
};
#endif
n 在板文件中添加lis3dh的驱动
static struct i2c_board_info ttc_dkb_i2c_info[] = {
{
.type = "88PM860x",
.addr = 0x34,
.platform_data = &ttc_dkb_pm8607_info,
.irq = IRQ_PXA910_PMIC_INT,
},
#if defined(CONFIG_SENSORS_LIS3DH)
{
.type = "lis3dh_acc",
.addr = 0x18,
.platform_data = &lis3dh_pdata,
},
#endif
};
n 在kernel/kernel/arch/arm/configs/pxa910_config文件中添加
CONFIG_SENSORS_LIS3DH=y
CONFIG_SENSOR_LIS3DH_POSITION=0
4 模块核心代码分析
4.1 Android上层应用APK到G-sensor driver的大致流程:
4.1.1 java层
l Java层sensor的状态控制有SesnorService来负责, 它的java代码和JNI代码分别位于 :
frameworks/base/services/java/com/android/server/SensorService.java
frameworks/base/services/jni/com_android_server_SensorService.cpp
l 在java层Sensor的数据控制有SensorManager来负责,它的java代码和JNI代码分别位于:
frameworks/base/core/java/android/hardware/SensorManager.java
frameworks/base/core/jni/android_hardware_SensorManager.cpp
l Android framework中与sensor通信的是sensorService.java和sensorManager.java
n sensorService.java的具体通信是通过JNI调用sensorService.cpp中的方法实现的。
n sensorManager.java的具体通信是通过JNI调用sensorManager.cpp中的方法实现的.
l sensorService.cpp 和 sensorMansger.cpp通过hardware.c与sensor.default.so通信。其中sensorService.cpp实现对sensor的状态控制,sensorManager.cpp实现对sensor的数据控制。sensor.default.so通过Ioctl控制sensor driver的状态,通过打开sensor driver对应的设备文件读取G-sensor采集的数据。
l Android SDK提供了4个类用于sensor通信,分别为sensor, sensorEvent, sensorEventListener,sensorManager。其中sensorEventListener用来在sensorManager中注册需要监听的sensor类型。
l sensorManager.java提供register(),unregister()接口供sensorEventListener使用。sensorManager.java不断轮询从sensor.default.so中取数据,取到数据后送给负责监听此类型sensor的sesnorEventListener.java,,sesnorEventListener.java通过在sensorManager.java中注册可以监听特定类型的sensor传来的数据。
l 系统启动时执行systemProcess,会启动sensorService.java, 在sensorService.java的构造函数中调用JNI方法_sensor_control_init()。senosrService.cpp中相应的方法android_int()会被执行。该函数会调用hardware.c中的方法hw_get_module()此函数又通过load()函数在system/lib/hw下查找sensor.default.so。查找时会根据hardware.c中定义好的sensor.*.so的扩展名的顺序查找,找到第一匹配的时候即停止,并将该sensor.default.so中定义好的一个全局变量HAL_MODULE_INFO_SYM带回。该变量包含的一个重要信息是它的一个成员结构变量中包含的一个函数指针open,该指针所指函数会对一个device结构变量赋值,从而带出sensorService.cpp和sensorManager.cpp与sensor通信所需要的全部信息。Device结构变量有两种变体分别供sensorService.cpp和sensorManager.cpp使用。其中主要是一些函数指针指向与sensor通信的函数。sensorService.cpp和sensorManager.cpp在得到HAL_MODULE_INFO_SYM结构后都会调用sensor.h的inline函数open()通过HAL_MODULE_INFO_SYM的open函数指针将所需的device信息取回。
系统在启动activityManager.java时,它会启动sensorManager.java,它也会调用hardware.c中的方法hw_get_module()带回HAL_MODULE_INFO_SYM。
4.1.2 硬件抽象层
Android对于Sensor的API定义在hardware/libhardware/include/hardware/sensor.h中,要求在sensor.so提供以下8个API函数
控制方面:
Int(*open_data_source)(struct sensor_control_device_t *dev);
Int(*activate)(struct sensor_control_device_t *dev, int handle, int enable);
Int(*set_delay)(struct sensor_control_device_t *dev, int32_t ms);
Int(*wake)(struct sensor_control_device_t *dev);
数据方面:
Int(*data_open)(struct sensor_data_device_t *dev, int fd);
Int(*data_close)(struct sensor_data_device_t *dev);
Int(*poll)(struct sensor_data_device_t *dev, sensor_data_t *data);
模块方面
Int(*get_sensor_list)(struct sensors_module_t *module, struct sensor_t const**list);
4.2 G-sensor driver工作的大致流程:
系统开机后。先加载i2c总线驱动,然后加载设备驱动。
在设备驱动中的init函数中通过i2c_add_driver(&lis3dh_i2c_driver)注册i2c_driver;此函数将driver注册到i2c_bus_type的总线上,此总线的匹配规则是利用i2c_client的名称和i2c_driver中id_table中的名称做匹配。其中i2c_client是注册版载信息是系统自动创建的,注册板载信息的过程就是在kernel/kernel/arch./arm/mach-mmp/tty_dkb.c文件中的结构变量中添加G-sensor的设备信息(前面已讲过)。当匹配成功时, I2c_driver中的probe()函数开始执行。
Probe()函数主要完成以下功能:
l 创建G-sensor的工作队列
l 注册input_devices设备
l 读取chip ID
l 设置寄存器,使能G-sensor
l 设置并启动中断
当G-sensor上报数据的时候会触发中断,然后在中断处理函数中提交一个报值的任务到队列中并禁止中断。在工作队列中读数G-sensor的数据并上报到input子系统中,最后使能中断。
5 调试
5.1 软硬件调试
驱动的调试一般要从硬件和软件两方面来调试,确定问题是处在软件还是硬件方面,不过sensor的硬件方面的连接不如一些设备(比如摄像头)那么复杂。
硬件方面:
l 测量电压,还有一些频脚的高低电平(这些要根据datasheet判断是否正确)
软件方面:
l 可以根据串口打印出的LOG判断驱动是否加载成功,在那些地方有错。
5.2 调试过程中的具体问题
l Gsesnor的i2c地址不对,如果i2c的地址不正确在系统起来时内核会有log出来,可以参考datasheet中的I2C的写地址,可以问厂商是否需要移位。
l 创建设备属性问题
在驱动中需要创建设备文件系统的节点,驱动中创建的节点要和HAL层要打开的设备节点路径匹配,才能够实现两层之间的调用。
l 没有数据读出问题。
在驱动中有数据上报,而在HAL层却没有数据读出,对驱动中数据处理的方式不对,这个参考datasheet,在驱动或HAL层做相应处理就可以在HAL层读到数据。
l 数据的正负不正确的问题
有时gsensor会出现转屏不正常,这可能是sensor上报的数据的有问题,在sensor的datasheet中有说明,sensor在板子上的放置方式会影响到sensor三轴数据的正负,驱动中要根据sensor在板子上的放置方式和上层的数据要求确定数据的方向。
l hal层的问题
在HAL层要添加sensor的设备信息,如果需要要在HAL层实现数据转换。
最后
以上就是震动黑裤为你收集整理的android 移植 距离感应,Android sensors移植文档的全部内容,希望文章能够帮你解决android 移植 距离感应,Android sensors移植文档所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复