在人机交互过程中,G-sensor起着非常重要的作用,gsensor作为输入设备,能感知当前G-sensor传感器所处的空间状态,附着在pad上配合使用,能测量出pad在空间上的坐标状态,从而获知pad用户的操作意图:横竖屏切换,转弯等。
目前G-sensor与HOST的连接有4个pin脚,分别为VCC,GND,SDA,SCL。引脚正常工作时候的高电平均为3.3V。
G-sensor的调试中,首先确认硬件的正确性。硬件调试中,需要确认下列项:
(1)、确认各个引脚与HOST连接的正确性。
(2)、电源电压是不是正常的,VCC是否为3.3V,GND是否为0。
(3)、I2C引脚电平是否匹配。
(4)、确认设备使用的I2C地址,特别是设备可以设置为多个地址时。
G-sensor驱动源码位于如下两个目录中。
mma7660,mma8452,mma865x,afa750,kxtik的源码位于linux-3.4\drivers\hwmon中。
bma250,lis3de,lis3dh,dmard10,mxc622x的源码位于linux-3.4\drivers\gsensor中。
linux-3.4
drivers/hwmon/
├── mma7660.c
├── mma8452.c
├── mma865x.c
├── afa750.c
├── kxtik.c
drivers/G-sensor/
├── bma250.c
├── lis3de_acc.c
├── lis3dh_acc.c
├── dmard10.c
├── mxc622x.c
(1)Gsensor 使用配置
配置文件的位置:\lichee\tools\pack\chips\sun7i\configs\android\wing-XXX目录下。
配置文件sys_config.fex中关于G-sensor的配置项如下:
--------------------------------------------------------------------------------
G sensor configuration
gs_twi_id --- TWI ID for controlling G-sensor (0: TWI0, 1: TWI1, 2: TWI2)
--------------------------------------------------------------------------------
[G-sensor_para]
G-sensor_used = 1
G-sensor_twi_id = 2
G-sensor_int1 =
G-sensor_int2 =
文件配置说明如下:
配置项 |
配置项含义 |
G-sensor_used=xx |
是否支持G-sensor |
G-sensor_twi_id =xx |
I2C的BUS控制选择,0:TWI0;1:TWI1;2:TWI2 |
G-sensor_int1=xx |
中断1的GPIO配置,目前暂不使用 |
G-sensor_int2=xx |
中断2的GPIO配置,目前暂不使用 |
目前G-sensor采用轮询工作方式,在sysconfig中只需指定如下两个信息即可:
G-sensor_used设为1,代表启用G-sensor;
G-sensor_twi_id根据具体的电路,选择对应的I2C;
(2)gsensor自动检测配置
使用自动检测功能时,需要增加以下配置信息,增加设备的可选择性。
如果gsensor_used 设置为0 则将退出gsensor的自动检测。
;--------------------------------------------------------------------------------
; G sensor automatic detection configuration
;gsensor_detect_used --- Whether startup automatic inspection function. 1:used,0:unused
;Module name postposition 1 said detection, 0 means no detection.
;--------------------------------------------------------------------------------
[gsensor_list_para]
gsensor_det_used = 1 //设置为1时,启动自动检测,设置为0时,退出自动检测。
bma250 = 1 //设置为1,该模块支持的I2C地址添加到扫描列表
mma8452 = 1
mma7660 = 1
mma865x = 1
afa750 = 1
lis3de_acc = 1
lis3dh_acc = 1
Kxtik = 1
dmard10 = 0 //设置为0,该模块支持的I2C地址从扫描列表中剔除
dmard06 = 1
mxc622x = 1
fxos8700 = 0
lsm303d = 0
当gsensor_det_used 设置为1时,启用自动检测,将设置为0时,退出自动检测。模块的名称后面写 1表示添加到自动检测扫描列表,写0表示剔除自动检测扫描列表。
gsensor_list_para列表中的名称顺序必须与 sw_device.c中gsensors的名称顺序一一对应。
对于G-sensor的的内核配置,可通过命令make ARCH=arm menuconfig进入配置主界面,并按以下步骤操作:
首先,选择Device Drivers选项进入下一级配置,如图2所示:
进入Device Drivers配置后,如果需要配置mma7660,mma8452,mma865x,afa750等,选择Hardware Monitoring support,如图3所示:
Hardware Monitoring support选项配置下的驱动如下图所示:
进入Device Drivers配置后,如果需要配置bma250,lis3de,lis3dh等,选择G-sensor support,如图5所示:
最后,选择相应的G-sensor模块驱动选项,可选择直接编译进内核,也可以选择编译成模块。如图6所示:
G-sensor模块的体系结构图,如图6所示。
G-sensor设备为使用I2C总线进行通信的输入设备,G-sensor driver通过调用I2C驱动的相应接口来实现对G-sensor设备的控制、通信,如G-sensor driver对G-sensor设备硬件各寄存器的读写访问等。
G-sensor driver将底层硬件对用户输入访问的响应转换为标准的输入事件,再通过核心层(Input Core)提交给事件处理层;而核心层对下提供了G-sensor driver的编程接口,对上又提供了事件处理层的编程接口;而事件处理层(input Event Driver)就为我们用户空间的应用程序提供了统一访问设备的接口和驱动层提交来的事件处理。用户空间将根据设备的节点进行数据的读取以及相应的处理。
bma250_driver:该变量会注册到i2c_driver中,driver.name为匹配设备名,probe为设备的侦测函数,address_list为I2C的scan地址,suspend 与resume为注册进内核的休眠唤醒函数。
static struct i2c_driver bma250_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.owner = THIS_MODULE,
.name = SENSOR_NAME,
},
.id_table = bma250_id,
.probe = bma250_probe,
.remove = bma250_remove,
#ifdef CONFIG_HAS_EARLYSUSPEND
#else
#ifdef CONFIG_PM
.suspend = bma250_suspend,
.resume = bma250_resume,
#endif
#endif
.address_list = normal_i2c,
};
struct bma250_data :代表了G-sensor驱动所需要的信息的集合,用于帮助实现对采样信息的处理。
struct bma250_data {
struct i2c_client *bma250_client;
atomic_t delay;
atomic_t enable;
unsigned char mode;
struct input_dev *input;
struct bma250acc value;
struct mutex value_mutex;
struct mutex enable_mutex;
struct mutex mode_mutex;
struct delayed_work work;
struct work_struct irq_work;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
unsigned char range_state;
unsigned char bandwidth_state;
#endif
};
struct bma250acc用于记录采样时获得的x轴,y轴,z轴的坐标信息。
struct bma250acc{
s16 x,
y,
z;
} ;
struct sensor_config_info用于记录读取到的sysconfig.fex中gsensor的相关信息。
input_type 为gsensor设备的类型,gsensor使用GSENSOR_TYPE。
sensor_used 为sysconfig.fex 中的 gsensor_used 值。
twi_id为sysconfig.fex 中的 gsensor_twi_id 值。
struct sensor_config_info{
enum input_sensor_type input_type;
int sensor_used;
__u32 twi_id;
};
G-sensor驱动作为硬件与软件的一个桥梁,实现对G-sensor控制器硬件初始化,获取G-sensor控制器采集到的位置坐标信息(必要时,对数据进行滤波和用户操作意图识别),上报用户操作相关信息于操作系统,经上层系统处理后,正确响应用户的意图。
G-sensor驱动在系统中必须满足如下要求:
l 接口:G-sensor驱动,不应自行决定是否上报,上报频率等,应提供接口,供上层应用控制驱动的运行和数据上报:包括使能控制Enable, 上报时延delay等;通常通过sys文件系统提供,这部分实现,遵循标准的linux规范;
l 上报数据的方式:或者提供接口供上层访问(eg: ioctl),或者挂接在input系统子系统上,使用input系统子系统的接口,供上层使用(eg: input core);
驱动的移植中主要需要关注点为如何获取sys_config.fex中的配置信息,detect函数,suspend以及resume函数等。以下将以bma250系列驱动移植过程为例进行说明。源码路径为:\lichee\linux-3.4\drivers\G-sensor\bma250.c
这部分接口是linux INPUT子系统对外提供的接口,G-sensor driver使用这些接口,向input 子系统注册设备和上报数据。
(1)申请input_dev结构:
struct input_dev *input_allocate_device(void)
(2)注册输入设备,并和对应的handler处理函数挂钩:
int input_register_device(struct input_dev *dev)
(3)注销Input设备:
int input_unregister_device(struct input_dev *dev)
(4)上报坐标值(绝对值):
static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value)
(5)上报坐标结束时同步信号:
static inline void input_sync(struct input_dev *dev)
目前G-sensor设备驱动使用的都是I2C总线进行通信,关键的接口如下所示:
(1)i2c_set_clientdata
将设备驱动的私有数据连接到设备client中。
(2)i2c_get_clientdata
获取设备client的设备驱动的私有数据。
(3)i2c_add_driver
通过I2C核心的i2c_add_driver()函数添加i2c_driver,使用到的关键数据结构为i2c_driver,注意i2c_driver中使用的name 需与 INPUT中的 input_dev name一致,否则有会出现找不到设备的情况。在bma250.c驱动中的i2c_driver变量为bma250_driver,其具体定义在4.1节中已经给出。
(4)i2c_del_driver
通过I2C核心的i2c_del_driver()函数删除i2c_driver。
(5)sysfs_create_group
sysfs接口,使用如下格式进行创建:
sysfs_create_group(&pdev->dev.kobj, &dev_attr_grp);
移植新的设备驱动时,需要设置一些跟平台相关的关键的变量,如表所示:
名称 |
含义 |
使用位置 |
debug_mask |
设置打印等级变量 |
在module_para_name 中使用 |
normal_i2c |
I2C总线扫描地址数组 |
i2c_driver结构体中,注册设备地址 |
i2c_address |
I2C总线detect函数扫描地址数组 |
gsensor_detect函数扫描地址 |
Gsensor驱动中需要包含头文件:
#include <linux/init-input.h>
这个头文件中包含使用的 struct sensor_config_info 结构体以及读取sysconfig.fex的相关调用接口与打印等级的定义。
该文件的具体实现:\lichee\linux-3.4\drivers\input\sw_device.c
可查阅文档“A20平台input 初始化文档.doc”
在G-sensor驱动中I2C地址有四个,均放置在扫描地址数组normal_i2c。
normal_i2c地址以固定的形式存在于设备驱动中。存放设备地址的数组必须以I2C_CLIENT_END标致结束。如下所示:
static const unsigned short normal_i2c[] = {0x18,0x19,0x38,0x08,I2C_CLIENT_END};
G-sensor驱动中的gsensor_detect函数实现硬件检测功能,它会遍历此驱动支持所有芯片的I2C地址,如果某个I2C地址能够正常通信并读到了正确的chip_id,则dectect成功,继续加载驱动。否则此驱动支持的芯片没有链接在电路中,驱动模块加载失败。bma_250的detect函数如下。
static int gsensor_detect(struct i2c_client *client, struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int ret , i = 0 ,retry = 2;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
if (twi_id == adapter->nr) {
while(retry--) {
for (i2c_num = 0; i2c_num < (sizeof(i2c_address)/sizeof(i2c_address[0]));i2c_num++) {
i = 0;
client->addr = i2c_address[i2c_num];
ret = i2c_smbus_read_byte_data(client,BMA250_CHIP_ID_REG);
dprintk(DEBUG_INIT, "%s:addr = 0x%x, i2c_num:%d, Read ID value is :%d\n",
__func__, client->addr, i2c_num, ret);
while((chip_id_value[i++]) && (i < 5)){
dprintk(DEBUG_INIT, "chip:%d\n", chip_id_value[i - 1]);
if((ret & 0x00FF) == chip_id_value[i - 1]){
strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);
return 0;
}
}
}
}
dprintk(DEBUG_INIT, "%s:Bosch Sensortec Device not found,\
maybe the other gsensor equipment! \n",__func__);
return -ENODEV;
} else {
return -ENODEV;
}
}
i2c_address数组存储了此驱动支持的所有的I2C地址,对每个I2C地址读取chip_id,如果读取成功,且为驱动支持的chip_id,则detect成功。
如果设备没有chip id的可以进行i2c检测设备是否存在。如下所示:以mma7660.c de detect为例子如下所示:
static int gsensor_detect(struct i2c_client *client, struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
int ret;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
if(config_info.twi_id == adapter->nr){
dprintk(DEBUG_INIT, "%s: addr= %x\n",__func__,client->addr);
ret = gsensor_i2c_test(client);
if(!ret){
dprintk(DEBUG_INIT, "%s:I2C connection might be something wrong or\
maybe the other gsensor equipment! \n",__func__);
return -ENODEV;
}else{
strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);
return 0;
}
}else{
return -ENODEV;
}
}
该函数中主要任务为调用input_fetch_sysconfig_para函数获取sys_config.fex中的配置信息;接着将gsensor_detect函数赋值给i2c_driver,调用接口注册i2c设备驱动。如下所示:
static int __init BMA250_init(void)
{
int ret = -1;
dprintk(DEBUG_INIT, "bma250: init\n");
if(input_fetch_sysconfig_para(&(config_info.input_type))){
printk("%s: err.\n", __func__);
return -1;
}
if(config_info.sensor_used == 0){
printk("*** used set to 0 !\n");
printk("*** if use sensor,please put the sys_config.fex gsensor_used set to 1. \n");
return 0;
}
bma250_driver.detect = gsensor_detect;
ret = i2c_add_driver(&bma250_driver);
return ret;
}
(1)super standby 中suspend以及resume的处理
super standby就是关掉除AVCC和DRAM_VCC电源以外的所有电源,因此在休眠时gsensor会被断电,在resume时,需要重新初始化gsensor的一些寄存器。
以bma250为例,其suspend函数及resume函数如下。在suspend时判断休眠类型是否为super standby,如果是,则保存当前gsensor的一些寄存器信息。在resume时,判断是否为super standby,如果是,则将suspend时保存的寄存器信息重新写入gsensor。
static void bma250_early_suspend(struct early_suspend *h)
{
struct bma250_data *data = container_of(h, struct bma250_data, early_suspend);
dprintk(DEBUG_SUSPEND, "bma250: early suspend\n");
if (NORMAL_STANDBY == standby_type) {
………………
} else if (SUPER_STANDBY == standby_type) {
if (bma250_get_bandwidth(data->bma250_client, &data->bandwidth_state) < 0)
printk("suspend: read bandwidth err\n");
if (bma250_get_range(data->bma250_client, &data->range_state) < 0)
printk("suspend: read range err\n");
………………
}
}
static void bma250_late_resume(struct early_suspend *h)
{
struct bma250_data *data = container_of(h, struct bma250_data, early_suspend);
dprintk(DEBUG_SUSPEND, "bma250: late resume\n");
if (NORMAL_STANDBY == standby_type) {
………………
} else if (SUPER_STANDBY == standby_type) {
if (bma250_set_bandwidth(data->bma250_client,
data->bandwidth_state) < 0)
printk("suspend: write bandwidth err\n");
if (bma250_set_range(data->bma250_client, data->range_state) < 0)
printk("suspend: write range err\n");
………………
}
}
(2)使用input_polled_dev的设备suspend以及resume需要关注点
gsensor驱动注册为input_polled_dev,此类驱动的轮询延时工作队列为input-polldev.c自动管理的。在休眠时,此轮询延时工作队列并未关闭,会导致系统无法进入休眠。如mma7660, mma8452, mma865x等。这些驱动需要在suspend函数自己去关需要调用函数:
input_polled_dev->input->close(struct input_dev *dev)
将设备关闭,否则将可以导致设备无法进入休眠。以mma8452为例子进行说明。字体加粗部分即为打开与关闭轮询延时工作队列的函数调用。
static void mma8452_early_suspend(struct early_suspend *h)
{
………………
mutex_lock(&enable_mutex);
atomic_set(&mma8452_suspend_id, 1);
mma8452_idev->input->close(mma8452_idev->input);
mutex_unlock(&enable_mutex);
……………………
}
static void mma8452_late_resume(struct early_suspend *h) //(struct i2c_client *client)
{
………………
mutex_lock(&enable_mutex);
atomic_set(&mma8452_suspend_id, 0);
mma8452_idev->input->open(mma8452_idev->input);
mutex_unlock(&enable_mutex);
………………
}
有些G-sensor在初始化时,初始化寄存器后,需要一定的延时才能正常工作。一般这个延时都是忙等待,这样在加载驱动及super standby唤醒时,相当耗时,影响用户体验。现在进行了优化。思路是采用工作队列线程将寄存器初始化部分单独延后执行,不影响主进程的运行。以mma8452为例,它在初始化寄存器时有一个100ms的延时。因此,在其休眠唤醒时的resume函数中进行了相应的优化,其源码如下,在休眠唤醒时resume函数如下。
static void mma8452_late_resume(struct early_suspend *h) //(struct i2c_client *client)
{
int result;
dprintk(DEBUG_SUSPEND, "mma8452 late resume");
if (NORMAL_STANDBY == standby_type) {
………………
} else if (SUPER_STANDBY == standby_type) {
queue_work(mma8452_resume_wq, &mma8452_resume_work);
}
dprintk(DEBUG_SUSPEND, "mma8452 late resume end");
return ;
}
字体加黑的部分为启动工作队列线程来将mma8452的寄存器初始化延后执行。mma8452_resume_work对应的执行函数为mma8452_resume_events,其源码如下。
static void mma8452_resume_events (struct work_struct *work)
{
mma8452_init_client(mma8452_i2c_client);
………………
}
mma8452_init_client为初始化mma8452寄存器函数,其中有一个100ms的忙等待延时。这部分的总体实现请参考mma8452.c源码。
模块卸载时,注意probe函数与init函数中申请的资源,要依照申请的顺序进行释放,后申请的先释放。如果申请的资源没有释放,或没有按照顺序释放,在模块卸载时,会卸载失败,甚至导致死机。
同时,在卸载时,注意要调用i2c_set_clientdata(client, NULL);函数。否则驱动自己是可以正常卸载的,但卸载后,向此I2C加载其它gsensor驱动时会出现I2C通讯不成功问题。
Gsensor 驱动中,需要提供使能控制以及上报时延等基本接口,通常通过sysfs文件系统提供,sensors的驱动中,使能控制统一命名为enable,上报时延为delay,如果名字变换,将可能造成hal层将无法向驱动层中写入使能控制以及时延,造成设备不工作或者是数据上报慢,影响体验效果。
(1)函数宏DEVICE_ATTR
DEVICE_ATTR 宏声明有四个参数,分别是名称、权限位、读函数、写函数。其中读函数和写函数是读写功能函数的函数名。需要注册的使能控制的名称应该设置为 enable;上报时延的名称应该设置为delay。基本函数为enable以及delay,如需要进行相关的调试,可以增加其他的接口。如下所示:
......
static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP,
bma250_delay_show, bma250_delay_store);
static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP,
bma250_enable_show, bma250_enable_store);
......
(2)attribute 结构体的填充
将DEVICE_ATTR 声明的接口填充到attribute结构体中,如下所示:
static struct attribute *bma250_attributes[] = {
......
&dev_attr_delay.attr,
&dev_attr_enable.attr,
NULL
};
该结构体必须以NULL结束。
(3)attribute_group结构体的填充
完成了attribute结构体的填充后,将实现attribute_group结构体的填充,如下所示:
static struct attribute_group bma250_attribute_group = {
.attrs = bma250_attributes
};
(4)sysfs接口的注册
调用系统提供函数,进行注册,如下:
err = sysfs_create_group(&data->input->dev.kobj,
&bma250_attribute_group);
添加一个新的G-sensor驱动需要修改Kconfig文件和Makefile文件以使得能够在menuconfig中选中G-sensor驱动并编译生成模块或者是直接编译进内核。现bma250.c为例,将源码拷贝到目录: ..\exdroid\lichee\linux-3.4\drivers\gsensor 下,按照文件Kconfig与Makefile 的形式,将G-sensor的驱动注册进去,如下:
Kconfig文件:
config SENSORS_BMA250
tristate "BMA250 acceleration sensor support"
depends on I2C
help
If you say yes here you get support for Bosch Sensortec's
acceleration sensors BMA250
Makefile文件:
obj-$(CONFIG_SENSORS_BMA250) += bma250.o
两个文件中设置的名字必须一致,即“CONFIG_SENSORS_BMA250”需一致,编译之后会自动的生成.Ko文件。添加之后可以到系统中查看是否添加成功,在编译服务器上,目录为workspace\exdroid\lichee\linux-3.4上,输入命令:
make ARCH=arm menuconfig
进入目录Device Drivers\gsensor support即可看到添加的驱动。
为了实现动态开关打印信息,在input子系统的驱动模块中加入一个模块参数debug_mask。驱动中所有的打印printk前加一个if条件判断语句,进行打印等级与debug_mask的按位与,debug_mask相应等级位为真(1),则打印此printk,为假(0)则关闭此打印。
在G-sensor代码bma250.c中,打印消息设置如下。
在文件开头,首先定义打印等级,模块参数,及打印函数,示例代码如下:
static u32 debug_mask = 0;
#define dprintk(level_mask, fmt, arg...) if (unlikely(debug_mask & level_mask)) \
printk(KERN_DEBUG fmt , ## arg)
module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
如代码中所示,枚举定义了打印等级,每一个等级占用一位。
debug_mask为控制打印的模块参数,默认为0,关闭所有的打印。
dprintk函数为封装好的打印函数,在驱动中调用它来打印相关的调试信息,如下面代码中所示。
static void bma250_early_suspend(struct early_suspend *h)
{
struct bma250_data *data =
container_of(h, struct bma250_data, early_suspend);
dprintk(DEBUG_SUSPEND, "bma250: early suspend\n");
………………
}
在bma250_early_suspend函数中调用dprintk函数打印调试信息,打印等级设为DEBUG_SUSPEND。当debug_mask的第3位为1,则此条打印消息会成功打印;当debug_mask的第3位为0,则屏蔽此打印消息。
在具体的驱动调试中,如果驱动编译成模块,则在驱动加载时,设置debug_mask的值,从而实现对各级打印消息的开关控制。
insmod /system/vendor/modules/bma250.ko debug_mask=0x0b
此方法存在的问题:当驱动加载不成功时,没有模块参数文件节点来让我们修改debug_mask的值,为了避免这个不足,在初始化函数init及probe函数中的初始化fail的相关打印最好写成printk直接打印,这些printk在模块正常工作时是不会被打印的,只有模块加载失败时才会被打印出来。
添加G-sensor驱动模块对应的hal层。G-sensor的hal层源码为android\device\softwinner\fiber-common\hardware\libhardware\libsensors\目录下的。
同时,在android\device\softwinner\wingr-xxx目录下有个gsensor.cfg文件,记录了如下几个变量。
gsensor_name |
G-sensor名称,必须与驱动中设备名相同 |
gsensor_direct_x |
G-sensor x轴的方向,当定义成true时,x轴取正值,当定义为false时,x轴取负值 |
gsensor_direct_y |
G-sensor y轴的方向,当定义成true时,y轴取正值,当定义为false时,y轴取负值 |
gsensor_direct_z |
G-sensor z轴的方向,当定义成true时,z轴取正值,当定义为false时,z轴取负值 |
gsensor_xy_revert |
XY轴对调,当设为TRUE时,x轴变为原来y轴 |
因为最终产品电路设计可能不一样,导致G-sensor可能贴的方向不一样,所以会出现添加G-sensor后,用户实际使用中会出现G-sensor方向不对的现象。需要根据以下步骤进行方向的调试。
Gsensor方向调试说明:
假定机器的长轴为X轴,短轴为Y轴,垂直方向为Z轴。
首先调试Z轴:
第一步观察现象:
旋转机器,发现当只有垂直90°时或者是在旋转后需要抖动一下,方向才会发生变化,则说明Z轴反了。若当机器大概45°拿着的时候也可以旋转,说明Z轴方向正确。无需修改Z轴方向。
第二步修改Z轴为正确方向。
此时需要找到当前使用模组的方向向量(根据模组的名称)。如果此时该方向Z轴向量(gsnesor_direct_z)的值为false,则需要修改为true;当为true,则需要修改为false。通过adb shell将修改后的gsnesor.cfg文件push到system/usr下,重启机器,按第一步观察现象。
其次查看X,Y轴是否互换:
第一步观察现象:
首先假定长轴为X轴,短轴为Y轴,以X轴为底边将机器立起来。查看机器的X,Y方向是否正好互换,若此时机器的X,Y方向正好互换,在说明需要将X,Y方向交换。若此时X,Y方向没有反置,则进入X,Y方向的调试。
第二步 交换X,Y方向
当需要X,Y方向交换时,此时需要找到当前使用模组的方向向量(根据模组的名称)。如果此时该X,Y轴互换向量(gsensor_xy_revert)的值为false,则需要修改为true,当为true,则需要修改为false。通过adb shell将修改后的gsnesor.cfg文件push到system/usr下,重启机器,按第一步观察现象。
再次调试X,Y轴方向:
第一步观察现象:
首先假定长轴为X轴,短轴为Y轴,以X轴为底边将机器立起来,查看机器的方向是否正确,如果正确,说明长轴配置正确,如果方向正好相反,说明长轴配置错误。将机器旋转到短轴,查看机器方向是否正确,如果正确,说明短轴配置正确,如果方向正好相反,说明短轴配置错误。
第二步修改X,Y轴方向:
当需要修改X,Y轴方向时,当只有长轴方向相反或者是只有短轴方向相反时,则只修改方向不正确的一个轴,当两个方向都相反时,则同时修改X与Y轴方向向量。找到当前使用模组的方向向量(根据模组的名称)。
若长轴方向相反,如果此时该方向X轴向量(gsnesor_direct_x)的值为false,则需要修改为true,当为true,则需要修改为false。
若短轴方向相反,如果此时该方向Y轴向量(gsnesor_direct_y)的值为false,则需要修改为true,当为true,则需要修改为false。
通过adb shell将修改后的gsnesor.cfg文件push到system/usr下,重启机器,按第一步观察现象。若发现还是反向X轴或者Y轴的方向仍然相反,则说明X轴为短轴,Y轴为长轴。此时:
若长轴方向相反,如果此时该方向Y轴向量(gsnesor_direct_y)的值为false,则需要修改为true,当为true,则需要修改为false。
若短轴方向相反,如果此时该方向X轴向量(gsnesor_direct_x)的值为false,则需要修改为true,当为true,则需要修改为false。
在android上移植G-sensor还必须将驱动拷贝到android打包目录的对应文件夹中,并在init.sunxi中将其加载。具体修改方法如下:
(1)、android4.x.x
android4.x.x会在extract-bsp的时候将其拷贝到对应目录。
android4.x.x对应的目录已经更改为:$PRODUCT_ROOT/system/vendor/modules/
(2)、修改init.sunxi.rc文件,android4.x.x修改init.sun7i.rc,在对应的文件中添加:insmod /vendor/modules/bma250.ko
若使用自动检测功能时,不需要增加该语句,只需要在该文件中增加:insmod /vendor/modules/sw_device.ko 自动检测驱动,同时sysconfig.fex文件中需要增加xxx_list_para的配置选项,该配置项的详细信息,请查看第二章。