Touch调试环境:yocto
调试过ETTI touch的人都知道,ETTI Touch 是人类历史上最容易调试的Touch,不涉及driver ,不涉及Makefile,Kconfig,也不涉及中断信号的处理。
既然ETTI Touch 那么容易调试,那为什么各大 Touch 厂家不把自家的Touch做成ETTI Touch的处理方式,不更好的方便调试吗?
总结了一下,原因有两个:
1、 Touch 调试本来就不复杂。
2、 ETTI这种处理方式是要付出代价的,所谓“鱼与熊掌不可兼得”。付出什么代价?下文会进行分析。
先来看看ETTI Touch调试的过程。(以串口屏为例)
分四步走:配置内核,把可执行程序跟配置文件放到rootfs里面,修改启动脚本,触摸矫正。
配置内核:
# make ARCH=arm menuconfig
选上以下两项:
--->[Device Drivers]
---> [Input devicesupport]
---> [Event interface]
---> [Device Drivers]
---> [Input device support]
---> [Miscellaneous devices]
---> [User level driver support]
即:
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
这样,新内核启动,可以看到以下节点:
/dev/input/uinput 或者是 /dev/uinput
把可执行程序跟配置文件放到rootfs里面:
主要是往rootfs存放 Touch 的可儿执行程序,和配置文件。这里,配置文件需要修改一下读取数据的设备节点。
eGTouchL.ini 里面修改 : SerialPath0 /dev/ttyX
修改启动脚本:
这里主要是修改 rc.local ,把Touch 的可执行程序启动的命令添加上。但修改完毕后会发现,触摸屏启动比较慢,因为 rc.local 是最后一个被执行的启动脚本,如果有需要,这里提示把启动命令行放到执行较前的启动脚本里面就可以了。
触摸校正:
校正很简单,校正完之后,把数据更新到“/etc/X11/xorg.conf.d/99-calibration.conf”里面即可。这里抛下一个问题,如果在yocto下调试,怎样把校正程序校正之后的数据打印出来?有兴趣,或者有需要的人士去研究一下吧。
到处为止,触摸屏就能够正常工作。下面,我们来分析一下触摸屏的工作原理是什么。
Linux内核引入uevent机制的目的:
一句话,很简单,就是为了能让用户空间也能向内核注入event数据。
当配置完内核配置选项:
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
机子运行起来可以看到“/dev/uinput”的设备节点。
这个“/dev/uinput”设备节点,你可以自己写一个应用程序去打开它,如:
char *dev = "/dev/uinput“;
int fd = open(dev, O_WRONLY | O_NDELAY);
配置完毕。过程(略)。
然后往里面写数据:
struct uinput_user_dev device
···
write(fd,& device,sizeof(device));
这样,就可以把用户空间的数据写入内核里面。接下来,我们看看内核 uevent 里面做了什么事情:
drivers/input/misc/uinput.c
433 static ssize_t uinput_inject_event(struct uinput_device *udev,
434 const char __user *buffer, size_t count)
435 {
436 struct input_event ev;
437
438 if (count < input_event_size())
439 return -EINVAL;
440
441 if (input_event_from_user(buffer, &ev))
442 return -EFAULT;
443
444 input_event(udev->dev, ev.type, ev.code, ev.value);
445
446 return input_event_size();
447 }
448
449 static ssize_t uinput_write(struct file *file, const char __user *buffer,
450 size_t count, loff_t *ppos)
451 {
452 struct uinput_device *udev = file->private_data;
453 int retval;
454
455 if (count == 0)
456 return 0;
457
458 retval = mutex_lock_interruptible(&udev->mutex);
459 if (retval)
460 return retval;
461
462 retval = udev->state == UIST_CREATED ?
463 uinput_inject_event(udev, buffer, count) :
464 uinput_setup_device(udev, buffer, count);
465
466 mutex_unlock(&udev->mutex);
467
468 return retval;
469 }
我们知道,当用户空间调用 write 函数的时候,会调用到uinput.c 的uinput_write 函数。
从上面的代码可以看到uinput_write 函数首先从 user 空间拷贝数据到kernel 空间,然后调用uinput_inject_event 函数来处理。uinput_inject_event里面有一行代码:
input_event(udev->dev, ev.type, ev.code, ev.value);
看到这里,已经很明朗了,最终还是会调用到input_event 把数据上报到系统去。
这时候,在按着touch 的时候,你可以在机器上使用串口命令:
Cat /dev/input/event*
或者
Cat /dev/input/ touchscreen*
都可以看到打印源源不断的数据。
分析到这里,我们就能知道 ETTI Touch 的工作流程:
那么对比一下其他tp厂家的做法,如墩泰,思立微等:
从两者的比较可以看出,ETTI的处理过程多出了“从user空间到kernel空间,再到user空间的过程”,如果涉及到多点触摸,当数据量较大的时候,肯定会影响到执行效率。如果配置够强大,这方面的差异性也可以忽略掉,根据自己的需求而定。