zoukankan      html  css  js  c++  java
  • 修改系统android2.3.4增加gsensor

    工作之余抽点时间出来写写博文,希望对新接触的朋友有帮助。今天在这里和大家一起学习一下修改系统

        转载请注明文章出处和作者!

        出处:http://blog.csdn.net/xl19862005

        作者:大熊(Xandy

        硬件平台:TI DM37XX  
    sensor:lsm330dlc(acc + gyr)
    1、将lsm330dlc驱动代码放到drivers/input/misc目录下,修改此上当下的kconfig和Makefile文件分别增加如下字段:

        Kconfig
    config SENSORS_LSM330DLC 
    tristate "ST's family of MEMS sensor modules of LSM330DLC"
    depends on I2C && INPUT && MACH_ZT6810
    select INPUT_POLLDEV
    default y
    help
    This driver provides support for the LSM330DLC gyroscope and accelerator connected via I2C.

        
    Makefile
    obj-$(CONFIG_SENSORS_LSM330DLC)+= lsm330dlc_acc.o lsm330dlc_gyr.o

        2、对比硬件原理图,修改lsm330dlc.h中的响应中断IO及数据万能IO,如:

        /*Xandy modify the accelerator and gyro interrupt pins @2012/9/12*/
    #define INT1_GPIO_ACC 178
    #define INT2_GPIO_ACC 179  
    #define INT1_GPIO_GYR 181
    #define INT2_GPIO_GYR 180  
    /*Xandy add Sensors enable pin*/
    #define SENSOR_EN_GPIO 38

        3、修改BSP响应文件(既对应的board-xx.c文件),对lsm330dlc进行驱动注册(I2C总线),如:

        #ifdef CONFIG_SENSORS_LSM330DLC
    static struct i2c_board_info __initdata zt6810_i2c_LSM330DLC[] = {
           {
                   I2C_BOARD_INFO("lsm330dlc_acc", 0x19),
           },
           {
          I2C_BOARD_INFO("lsm330dlc_gyr", 0x6B), 
    },
    };
    #endif
    static int __init zt6810_i2c_init(void)
    {
    omap_register_i2c_bus(1, 2600, zt6810_i2c_boardinfo,
    ARRAY_SIZE(zt6810_i2c_boardinfo));
    /* Bus 2 is used for Battery ckeck(bq27410) */
    #ifdef CONFIG_BATTERY_MAX17049
    omap_register_i2c_bus(2, 100, zt6810_i2c_MAX17049, ARRAY_SIZE(zt6810_i2c_MAX17049));
    #else
    omap_register_i2c_bus(2, 100, NULL, 0);
    #endif
    /* projector don't work reliably with 400kHz */
    #ifdef CONFIG_SENSORS_LSM330DLC  
    omap_register_i2c_bus(3, 200, zt6810_i2c_LSM330DLC, ARRAY_SIZE(zt6810_i2c_LSM330DLC));
    #endif
    return 0;
    }

        内核编译通过之后,将uImage烧录到样机,如果不出不测,在串口终端进入响应目录,ls一下将会看到如下内容:

        修改和系统

        修改和系统

        修改和系统

        可以看出acc在I2C总线注册胜利,响应的I2C总线号及address为3-0019,而gyr则为3-006B
    4、在串口终端里输入如下命令:

        # cat /proc/bus/input/devices

        将会失掉如下信息:

        # cat /proc/bus/input/devices
    I: Bus=0019 Vendor=0001 Product=0001 Version=0100
    N: Name="gpio-keys"
    P: Phys=gpio-keys/input0
    S: Sysfs=/devices/platform/gpio-keys/input/input0
    U: Uniq=
    H: Handlers=kbd event0 
    B: EV=3
    B: KEY=4 0 0 0 100000 0 0 0
    I: Bus=0019 Vendor=0001 Product=0001 Version=0003
    N: Name="TWL4030 Keypad"
    P: Phys=twl4030_keypad/input0
    S: Sysfs=/devices/platform/omap/omap_i2c.1/i2c-1/1-004a/twl4030_keypad/input/input1
    U: Uniq=
    H: Handlers=kbd event1 
    B: EV=100013
    B: KEY=800 c1680 0 2000000 100000aa
    B: MSC=10
    I: Bus=0000 Vendor=0000 Product=0000 Version=0000
    N: Name="ADS7846 Touchscreen"
    P: Phys=spi1.0/input0
    S: Sysfs=/devices/platform/omap2_mcspi.1/spi1.0/input/input2
    U: Uniq=
    H: Handlers=mouse0 event2 
    B: EV=b
    B: KEY=400 0 0 0 0 0 0 0 0 0 0
    B: ABS=1000003
    I: Bus=0000 Vendor=0000 Product=0000 Version=0000
    N: Name="twl4030_pwrbutton"
    P: Phys=twl4030_pwrbutton/input0
    S: Sysfs=/devices/platform/omap/omap_i2c.1/i2c-1/1-0049/twl4030_pwrbutton/input/input3
    U: Uniq=
    H: Handlers=kbd event3 
    B: EV=3
    B: KEY=100000 0 0 0
    I: Bus=0018 Vendor=0000 Product=0000 Version=0000
    N: Name="lsm330dlc_acc"
    P: Phys=
    S: Sysfs=/devices/platform/omap/omap_i2c.3/i2c-3/3-0019/input/input4
    U: Uniq=
    H: Handlers=js0 event4 
    B: EV=9
    B: ABS=100 107
    I: Bus=0018 Vendor=0000 Product=0000 Version=0000
    N: Name="lsm330dlc_gyr"
    P: Phys=
    S: Sysfs=/devices/platform/omap/omap_i2c.3/i2c-3/3-006b/input/input5
    U: Uniq=
    H: Handlers=js1 event5 
    B: EV=9
    B: ABS=7

        

        这里列出的是现在系统已经注册的input设备的一些信息,最后两项就是之前加入的sensor(acc + gyr)注册的响应input设备

        为什么sensor会注册成input设备,看看响应的驱动源码里有如下内容:

        static int lsm330dlc_acc_input_init(struct lsm330dlc_acc_data *acc)
    {
    int err;
    INIT_DELAYED_WORK(&acc->input_work, lsm330dlc_acc_input_work_func);
    acc->input_dev = input_allocate_device();
    if (!acc->input_dev) {
    err = -ENOMEM;
    dev_err(&acc->client->dev, "input device allocation failed\n");
    goto err0;
    }
    acc->input_dev->open = lsm330dlc_acc_input_open;
    acc->input_dev->close = lsm330dlc_acc_input_close;
    acc->input_dev->name = LSM330DLC_ACC_DEV_NAME;
    //acc->input_dev->name = "accelerometer";
    acc->input_dev->id.bustype = BUS_I2C;
    acc->input_dev->dev.parent = &acc->client->dev;
    input_set_drvdata(acc->input_dev, acc);
    set_bit(EV_ABS, acc->input_dev->evbit);
    /* next is used for interruptA sources data if the case */
    set_bit(ABS_MISC, acc->input_dev->absbit);
    /* next is used for interruptB sources data if the case */
    set_bit(ABS_WHEEL, acc->input_dev->absbit);
    input_set_abs_params(acc->input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT);
    input_set_abs_params(acc->input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT);
    input_set_abs_params(acc->input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT);
    /* next is used for interruptA sources data if the case */
    input_set_abs_params(acc->input_dev, ABS_MISC, INT_MIN, INT_MAX, 0, 0);
    /* next is used for interruptB sources data if the case */
    input_set_abs_params(acc->input_dev, ABS_WHEEL, INT_MIN, INT_MAX, 0, 0);
    err = input_register_device(acc->input_dev);
    if (err) {
    dev_err(&acc->client->dev,
    "unable to register input device %s\n",
    acc->input_dev->name);
    goto err1;
    }
     
    return 0;
    err1:
    input_free_device(acc->input_dev);
    err0:
    return err;
    }

        每日一道理
    喜马拉雅直冲霄汉,可上面有攀爬者的旗帜;撒哈拉沙漠一望无垠,可里头有跋涉者的脚印;阿尔卑斯山壁立千仞,可其中有探险者的身影;雅鲁藏布江湍急浩荡,可其中有勇敢者的故事。

        我们在终端里再输入如下命令:
    # getevent
    将失掉如下信息:
    # getevent
    could not get driver version for /dev/input/mice, Not a typewriter
    add device 1: /dev/input/event2
      name:     "ADS7846 Touchscreen"
    could not get driver version for /dev/input/mouse0, Not a typewriter
    add device 2: /dev/input/event0
      name:     "gpio-keys"
    add device 3: /dev/input/event5
      name:     "lsm330dlc_gyr"
    could not get driver version for /dev/input/js1, Invalid argument
    add device 4: /dev/input/event4
      name:     "lsm330dlc_acc"
    could not get driver version for /dev/input/js0, Invalid argument
    add device 5: /dev/input/event1
      name:     "TWL4030 Keypad"
    add device 6: /dev/input/event3
      name:     "twl4030_pwrbutton"
    /dev/input/event4: 0003 0000 00000001
    /dev/input/event4: 0003 0001 ffffff5f
    /dev/input/event4: 0003 0002 000003df
    /dev/input/event4: 0000 0000 00000000
    /dev/input/event4: 0003 0000 fffffffe
    /dev/input/event4: 0003 0001 ffffff5e
    /dev/input/event4: 0003 0002 000003e2
    /dev/input/event4: 0000 0000 00000000
    /dev/input/event4: 0003 0000 00000002
    /dev/input/event4: 0003 0001 ffffff5d
    /dev/input/event4: 0003 0002 000003e5
    /dev/input/event4: 0000 0000 00000000
    /dev/input/event4: 0003 0000 00000001
    /dev/input/event4: 0003 0001 ffffff5f
    /dev/input/event4: 0003 0002 000003df
    /dev/input/event4: 0000 0000 00000000
    /dev/input/event4: 0003 0000 fffffffe
    /dev/input/event4: 0003 0001 ffffff66
    /dev/input/event4: 0003 0002 000003e4
    ......

        
    getevent命令是用来获取系统输入事件的,很轻易看出,以后系统一直有event4的事件发生,对比上面的信息:
    add device 4: /dev/input/event4
      name:     "lsm330dlc_acc"
    可见前面加入的sensor(acc)已经开始工作了并不停地往系统上报以后的加速度事件!
    如果畸形配置且编译通过了sensor的驱动,但无法失掉这些信息,那么你就有必要查查你的硬件是否畸形了,如:芯片是否是分歧;有无虚焊,最后找个示波器挂一下,看看响应的I2C波形正不畸形!
    5、完成了上面的工作,并不等于完成了全部的工作,现在虽然sensor已经开始工作了,但当你进入到具有重力感到的界面,如:系统设置。
    发明UI现在是不会转动的,或者你下一个sensor测试工具,也是一样的。
    这是因为在HAL里头,还没有打通sensor事件上报的通道,下面来看看HAL里头的代码要如何修改。
    sensor HAL层的代码在
    hardware/ti/omap3/libsensors
    目录下面。
    先来看看sensors.cpp这个文件。这里是sensor进行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: "Sensor module",
                    author: "Texas Instruments Inc.",
                    methods: &sensors_module_methods,
            },
            get_sensors_list: sensors__get_sensors_list,
    };
    这是HAL层封装的一个标准结构,我们主要来看看下面这段代码:
    sensors_poll_context_t::sensors_poll_context_t()
    {
    mSensors[accel] = new AccelSensor();
    mPollFds[accel].fd = mSensors[accel]->getFd();
    mPollFds[accel].events = POLLIN;
    mPollFds[accel].revents = 0;
    mSensors[gyro] = new GyroSensor();
    mPollFds[gyro].fd = mSensors[gyro]->getFd();
    mPollFds[gyro].events = POLLIN;
    mPollFds[gyro].revents = 0;
    int wakeFds[2];
    int result = pipe(wakeFds);
    LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));
    fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);
    fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);
    mWritePipeFd = wakeFds[1];
    mPollFds[wake].fd = wakeFds[0];
    mPollFds[wake].events = POLLIN;
    mPollFds[wake].revents = 0;
    }
    可以看出,这里new了两个sensor设备,一个是ACC,另外一个则是GYR!进入到accelSensor.cpp,在下面这个构造函数里:
    AccelSensor::AccelSensor()
        : SensorBase(NULL, "lsm330dlc_acc"),
          mEnabled(0),
          mInputReader(4),
          mHasPendingEvent(false)

        memset(&mPendingEvent, 0, sizeof(mPendingEvent));
        mPendingEvent.version = sizeof(sensors_event_t);
        mPendingEvent.sensor = ID_A;
        mPendingEvent.type = SENSOR_TYPE_ACCELEROMETER;
    mPendingEvent.acceleration.status = SENSOR_STATUS_ACCURACY_HIGH;
        if (data_fd) 
    {
            strcpy(input_sysfs_path, ACCEL_SENSOR_NAME);
            input_sysfs_path_len = strlen(input_sysfs_path);
            enable(0, 1);
        }
    }




    黄色背景标注的是须要修改的,其中ACCEL_SENSOR_NAME的宏定义响应如下:
    /*Xandy add AccelSensor name and GyroSensor name macro definition*/
    #ifdef CONFIG_SENSOR_LSM330DLC 
    #define ACCEL_SENSOR_NAME"/sys/bus/i2c/drivers/lsm330dlc_acc/3-0019/"
    #define GYRO_SENSOR_NAME "/sys/bus/i2c/drivers/lsm330dlc_gyr/3-006b/"   

    #else
    #define ACCEL_SENSOR_NAME "/sys/bus/i2c/drivers/lis331dlh/1-0018/"
    #define GYRO_SENSOR_NAME "/sys/bus/i2c/drivers/l3g4200dh_i2c/1-0068/" 
    #endif
    其中CONFIG_SENSOR_LSM330DLC这个宏开关我在响应的Android.mk里作了如下定义:
    # Xandy add macro define for accel and gyro sensors
    ifeq ($(SENSOR_LSM330DLC), true)
    LOCAL_CFLAGS += -DCONFIG_SENSOR_LSM330DLC
    endif
    而SENSOR_LSM330DLC则在响应工程(device目录下对应你此时的vendor)的BoardConfig.mk里作如下定义:
    #Xandy add accel and gyro sensors
    BOARD_HAS_SENSOR := true
    SENSOR_LSM330DLC := true
    这些其实都是宏定义及编译开关设置的问题,这样做的目标是方便不同工程(vendor)之间的切换及添加新的设备支撑
    GYR HAL的修改和ACC的一样,这里未几提了!
    经过这些修改之后,用mm编译响应的lib,并将lib通过adb push 到样机的文件系统里对应目录下,重启系统之后如果一切畸形,现在进入到有UI旋转的界面,就会起作用了,
    但是,很有很可此时的旋转方向和你运行的方向是不分歧的,那么你还得修改一下Sensor HAL中sensors.h里头的如下宏:
    #ifdef CONFIG_SENSOR_LSM330DLC
    #define EVENT_TYPE_ACCEL_X          REL_X
    #define EVENT_TYPE_ACCEL_Y          REL_Y
    #define EVENT_TYPE_ACCEL_Z          REL_Z
    #else
    #error you must define ACCEL X Y Z
    #endif 


    #ifdef CONFIG_SENSOR_LSM330DLC
    #define EVENT_TYPE_GYRO_X           REL_X//REL_RX
    #define EVENT_TYPE_GYRO_Y           REL_Y//REL_RY
    #define EVENT_TYPE_GYRO_Z           REL_Z//REL_RZ
    #else
    #error you must define GYRO X Y Z
    #endif 
    修改这些 x、y、z的定义,例如改成如下顺遂:
    #ifdef CONFIG_SENSOR_LSM330DLC
    #define EVENT_TYPE_GYRO_X           REL_Z
    #define EVENT_TYPE_GYRO_Y           REL_X
    #define EVENT_TYPE_GYRO_Z           REL_Y
    #else
    #error you must define GYRO X Y Z
    #endif 
    详细顺遂怎样,根据你的硬件摆放位置来定


    至此sensor的调试就基本上完成了,如果还有什么要修改的,那就是一些微调了,如灵敏度等

    文章结束给大家分享下程序员的一些笑话语录: 很多所谓的牛人也不过如此,离开了你,微软还是微软,Google还是Google,苹果还是苹果,暴雪还是暴雪,而这些牛人离开了公司,自己什么都不是。

  • 相关阅读:
    HDU 5583 Kingdom of Black and White 水题
    HDU 5578 Friendship of Frog 水题
    Codeforces Round #190 (Div. 2) E. Ciel the Commander 点分治
    hdu 5594 ZYB's Prime 最大流
    hdu 5593 ZYB's Tree 树形dp
    hdu 5592 ZYB's Game 树状数组
    hdu 5591 ZYB's Game 博弈论
    HDU 5590 ZYB's Biology 水题
    cdoj 1256 昊昊爱运动 预处理/前缀和
    cdoj 1255 斓少摘苹果 贪心
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3076746.html
Copyright © 2011-2022 走看看