通过前一节的分析得到, 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. 在线程中添加
来源: http://www.bubuko.com/infodetail-3039141.html