• Linux Input子系统浅析(二)-- 模拟tp上报键值【转】


    转自:https://blog.csdn.net/xiaopangzi313/article/details/52383226

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaopangzi313/article/details/52383226
    通过前一节的分析得到,linux Input子系统上传数据本质上是将input_dev的数据,上报给input_handler,
    当用户读入event时,驱动层只需要利用copy_to_user将数据传递至用户空间。当然,以上只是内核中Linux input
    的机制,作为驱动工程师我们该如何使用input子系统呢?考虑到部分读者没有嵌入式设备,作者从一个虚拟嵌入式
    设备的编写,描述Input subsystem 的使用。
        实际的嵌入式设备中,用的input system的设备很多,如gsensor,psensor,touch panel等,本文着重模拟一个
    virsual touch 设备,让其向上层空间报值,然后用户空间可以通过通用IO来捕获键值或者坐标。
    一、 虚拟设备的编写流程
    1.定义虚拟设备结构体
    struct touch_dev{
    struct platform_device *p_dev; //定义平台设备,这个不为必须
    struct input_dev *input; //定义input设备结构体
    int x; //定义坐标X
    int y; //定义坐标Y,当然如果需要也可以添加键值
    struct task_struct *run_thread; //定义内核线程,为了让用户空间随时都抓到坐标,我们可以开启线程
    不断上报
    };
    2. 注册平台设备和驱动
    platform_device_register_simple("v_touch",-1,NULL,0);
    platform_device_register_simple("v_touch",-1,NULL,0);
    3. probe 函数实现
    kthread_run(vtouch_thread,vtouch_dev,"vtouch_thread");
    4. 内核线程实现
    static int vtouch_thread(void *data)
    {
    int x,y;
    struct touch_dev *vtouch_dev = (struct touch_dev*)data;

    printk(KERN_INFO "vtouch thread running ");

    do{

    ...

    printk("vtouch thread report ");
    msleep(2000);
    } while(!kthread_should_stop());//线程退出条件

    return 0;
    }
    二、 input 设备的添加流程
    1.在 probe中添加
    //为input device申请内存
    vtouch_dev->input = input_allocate_device();
    //设置 vtouch 设备名称
    vtouch_dev->input->name = "vtouch";
    //设置设备支持坐标事件,包括X坐标,Y坐标事件,Z坐标事件。
    set_bit(EV_ABS,vtouch_dev->input->evbit);
    //对于X轴范围是-1024到+1024,数据误差是-2到+2,中心平滑位置是0
    input_set_abs_params(vtouch_dev->input, ABS_X, -1024, 1024, 2, 0);
    //同上
    input_set_abs_params(vtouch_dev->input, ABS_Y, -1024, 1024, 2, 0);
    //注册输入设备
    ret = input_register_device(vtouch_dev->input);
    if(ret < 0){
    printk("%s register input device error ",__func__);
    goto input_register;
    }
    2.在线程中添加

    //上报绝对坐标
    input_report_abs(vtouch_dev->input,ABS_X,x);
    input_report_abs(vtouch_dev->input,ABS_Y,y);
    //上报同步通知
    input_sync(vtouch_dev->input); //对于坐标必须添加
    三、应用程序编写
    int main(void)
    {
    struct input_event ev;
    int count,x,y;

    int fd = open(EVENT_DEV, O_RDWR);


    while(1){
    count = read(fd, &ev,sizeof(struct input_event));
    if(EV_ABS == ev.type){
    if(ev.code == ABS_X){
    x = ev.value;
    }else if(ev.code == ABS_Y){
    y = ev.value;
    }
    printf("position: x=%d, y=%d ",x,y);
    }else if(EV_SYN == ev.type){
    puts("sync!");
    }
    }

    return 0;
    }
    整体源码如下:
     驱动:  input_simulate.c

     应用: input_simulate_test.c

    四、调试过程
    1. 通过
    cat /proc/bus/input/devices
    查看与dev、input目录下的event对应的设备 

    2. ./a.out  //运行应用程序

    实验效果:

    五、总结

        就单纯使用而言,应用input subsystem 我们只需要做以下工作,

    1. 定义input_device 并分配调用input_allocate_device(); 分配空间 

    2. 设置input_dev 支持的事件类型如:set_bit,input_set_abs_params

    3. 调用input_register_device 注册input_dev

    4. 调用input_report_abs,input_sync上报事件
    ---------------------
    作者:xiaopangzi313
    来源:CSDN
    原文:https://blog.csdn.net/xiaopangzi313/article/details/52383226
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    将字符串指针ps1 和 ps2之间的内存拷贝出来
    wm_copydata不等返回值处理 SendMessage SendMessageTimeout
    成为编程高手的八大奥秘
    成功老板防骗反骗技巧
    创业者怎样掌握简便的创业机会
    爱过了,恨过了,在这里留下最想对他/她说的那句话!(转)
    创业者须知的8条创业逻辑
    超越无形, 做只“一天到晚会游的鱼”
    男性的12种健康食物!
    原始商人的深度思考(二)市场准入时机的把握
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/10783591.html
Copyright © 2020-2023  润新知