资讯详情

Android sensors移植文档

1 硬件工作原理

1.1 G-sensor管脚的主要定义

上图是LIS3DHTR在TD_100中的原理图

l电压:VDD:sensor供电电源。

VDD_IO:sensor的IO电源。

l中断:ACCEL_INT1

ACCEL_INT2:sensor的中断pin脚

lI2C: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代码分别位于

lframeworks/base/services/java/com/android/server/SensorService.java

lframeworks/base/services/jni/com_android_server_SensorService.cpp

在java层Sensor数据控制有SensorManager负责,它的java代码和JNI代码分别位于:

lframeworks/base/core/java/android/hardware/SensorManager.java

lframeworks/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层

lVendor/marvell/dkb/libsensor目录下有lib_sensor.c和Android.mk

lvendor/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修改如下:

nconfig SENSORS_LIS3DH

tristate "STMicroelectronics LIS3DH Accelerometer Sensor"

depends on I2C

nconfig 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

nobj-$(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.1java层

lJava层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代码分别位于:

framworks/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层实现数据转换。

标签: lis3dh陀螺仪传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台