1. 拷贝至开发板
将上次实验中的 tmp 文件夹拷贝到开发板,可以通过 nfs 来传输,并将 tmp/lib 下的所有 .so 文件拷贝至 开发板的 /usr/lib 中,并且确保库的映射关系正确。
2. 声明 tslib 的环境变量
export TSLIB_CALIBFILE='/etc/pointercal'
export TSLIB_CONFFILE='/tslib/etc/ts.conf'
export TSLIB_CONSOLEDEVICE='none'
export TSLIB_FBDEVICE='/dev/fb0'
export TSLIB_PLUGINDIR='/tslib/lib/ts'
export TSLIB_TSDEVICE='/dev/input/event1'
这里的 TSLIB_TSDEVICE,要选择与你的触摸屏对应的 event,有一个好的方法,通过命令
cat /proc/bus/input/devices
来确定,我的屏幕为 ft5x06,信息如下:
3. 运行测试程序
进入到 /tslib/bin
执行 ./ts_test
很尴尬,得到以下提示:
selected device is not a touchscreen I understand
去网上搜索了下,有曾经遇到过该问题的网友写道:
是由于内核和编译器的一个宏(EV_VERSION 位置:内核和编译器的 input.h 文件中声明)定义不一致导致的,于是我对比了内核与编译器中的宏,果然不一样,我选择改了编译器中的宏并重新编译 tslib,再次导入开发板运行,仍然提示上述错误!
搜索了下 tslib 的源码,找到该提示的位置,如下(位于 tslib/plugins/input-raw.c):
if (! ((ioctl(ts->fd, EVIOCGVERSION, &version) >= 0) &&
(version == EV_VERSION) &&
(ioctl(ts->fd, EVIOCGBIT(0, sizeof(bit) * 8), &bit) >= 0) &&
(bit & (1 << EV_ABS)) &&
(ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit) * 8), &absbit) >= 0) &&
(absbit & (1 << ABS_X)) &&
(absbit & (1 << ABS_Y)) && (absbit & (1 << ABS_PRESSURE)))) {
fprintf(stderr, "selected device is not a touchscreen I understand\n");
return -1;
}
加上打印便于调试:
if (! ((ioctl(ts->fd, EVIOCGVERSION, &version) >= 0) &&
(version == EV_VERSION) &&
(ioctl(ts->fd, EVIOCGBIT(0, sizeof(bit) * 8), &bit) >= 0) &&
(bit & (1 << EV_ABS)) &&
(ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit) * 8), &absbit) >= 0) &&
(absbit & (1 << ABS_X)) &&
(absbit & (1 << ABS_Y)) && (absbit & (1 << ABS_PRESSURE)))) {
printf("version: %x, EV_VERSION: %x \n \
EV_ABS: %d \n \
ABS_X: %lld \n \
ABS_Y: %lld \n \
ABS_PRE: %lld \n",\
version, EV_VERSION, (bit & (1 << EV_ABS)), (absbit & (1 << ABS_X)),\
(absbit & (1 << ABS_Y)), (absbit & (1 << ABS_PRESSURE)));
fprintf(stderr, "selected device is not a touchscreen I understand\n");
return -1;
}
重新编译 tslib,导入开发板运行发现 ABS_X、ABS_Y、ABS_PRE 都为 0 !!!!
分析了下,这肯定是内核驱动有问题,故找到源码(drivers\input\touchscreen\ft5x06_ts.c),仔细看了一遍,发现启用多点触控的话,传输数据无法与 tslib 对应,所以关闭了多点,注释掉下句即可,如下:
//#define CONFIG_FT5X0X_MULTITOUCH 1
保存,重新编译内核,下载至开发板,再将运行 ts_test,完美运行!
总结
在我找 BUG 的期间,阅读了内核中关于 tiny210 触摸屏另一个源码:mini210_1wire_host.c
我想,用过友善板子的同学可能知道,他们会将触摸屏上加上一块单片机来与开发板通信,利用他们的 1wire 协议实现更加精准的触控体验,这使得我们的实验变的与大众不同,而且官方并不提供该部分的协议。
记得当初用 Mini2440 的时候,配的是 P35 显示屏,内核必须配置为 1wire 驱动才能使用触控,查阅资料后发现可以更改屏幕的硬件部分来兼容内核自带的触屏源码。
tiny210 自带的文件系统中带有 tslib,这个 tslib 是友善修改过的,而且也不开源,使用的接口的就是 1wire(/dev/touchscreen-1wire)。
接下来是 Qt 应用程序的测试,见下篇文章。