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

来源:互联网 发布:84ty域名升级访问升级 编辑:程序博客网 时间:2024/05/16 05:56
通过前一节的分析得到,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\n");            do{  ...          printk("vtouch thread report\n");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\n",__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\n",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上报事件

  




2 0
原创粉丝点击