全部博文(396)
分类: 嵌入式
2017-10-26 16:31:58
tslib是一个开源程序,最主要的用途是可以校正触摸屏。通常可以把它作为触摸屏的一个适配层,为上层的应用程序提供统一的接口。在这里,我们移植tslib,为以后移植和使用QT打下基础。
首先下载tslib-1.4.tar.gz文件,并完成解压、配置、编译和安装操作,命令如下:
tar -zxvf tslib-1.4.tar.gz
cd tslib
./autogen.sh
./configure --host=arm-linux ac_cv_func_malloc_0_nonnull=yes --cache-file=arm-linux.cache -prefix=/usr/local/tslib
make
make install
其中-prefix是指定安装路径,由于是把tslib安装到/usr/local/tslib目录下,因此需要根用户权限。
然后再把交叉编译好的tslib安装到开发板上,也就是复制相应的文件到开发板的根文件系统内:
/usr/local/tslib/lib文件下除去pkgconfig目录以外的其他所有文件复制到根文件系统的/lib目录下;
/usr/local/tslib/bin文件下所有文件复制到根文件系统的/bin目录下;
/usr/local/tslib/etc下的ts.conf文件复制到根文件系统的/etc下,并修改其中的内容,下面是ts.conf文件的前两行;
# Uncomment if you wish to use the linuxinput layer event interface
# module_raw input
去掉# module_raw input前面的注释以及空格,也就是module要顶格。该文件内的其他部分无需改动。
最后添加环境变量,把有关tslib的环境变量添加到开发板根文件系统的/etc/profile文件内,添加的内容如下:
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CALIBFILE=/temp/pointercal
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
下面对这些环境变量做一简单的说明:
TSLIB_TSDEVICE——触摸屏设备节点,这个要根据自己开发板的情况填写;
TSLIB_CONFFILE——配置文件名,就是前面复制并修改的ts.conf文件;
TSLIB_PLUGINDIR——插件目录
TSLIB_CALIBFILE——校准的数据文件pointercal。当执行ts_calibrate命令对触摸屏进行校正的时候,会生成一个校准文件,这样在以后使用触摸屏的时候,系统会根据该文件正确判断触点的位置。在这里我把pointercal文件放到temp目录下,因为对于我的系统来说,temp目录是可读写的。如果你选择的pointercal文件所在目录是不可写的,那么是不会生成pointercal文件的,即使执行了ts_calibrate命令,触点的位置也是错误的;
TSLIB_CONSOLEDEVICE——控制台设备文件名;
TSLIB_FBDEVICE——LCD设备节点,也要根据自己开发板的情况填写。
这样开发板的根文件系统就添加了tslib,重新编译根文件系统,并把它烧写进开发板内,启动开发板后执行ts_calibrate命令,用来进行校验触摸屏;执行ts_test命令可以对触摸屏进行测试。
但我在执行ts_calibrate命令的时候出现了下列提示错误:
selecteddevice is not a touchscreen I understand
经过仔细阅读代码,发现错误发生在tslib中的plugins目录下input-raw.c文件中的check_fd函数内:
static intcheck_fd(struct tslib_input *i)
{
structtsdev *ts = i->module.dev;
intversion;
u_int32_tbit;
u_int64_tabsbit;
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 ");
return-1;
}
if(bit & (1 << EV_SYN))
i->using_syn= 1;
return0;
}
首先tslib通过EVIOCGVERSION来获取驱动的版本号,然后再通过EVIOCGBIT来判断设备是否为触摸屏,因为触摸屏的事件是绝对值事件(EV_ABS),最后获取触摸屏的X轴(ABS_X),Y轴(ABS_Y),以及压力(ABS_PRESSURE)。其中只要有一项内容不正确,tslib都会认为该设备不是触摸屏,而打印出“selecteddevice is not a touchscreen I understand”错误。
版本号EV_VERSION是容易不一致的,我的交叉编译器定义的EV_VERSION值在编译器目录下的arm/usr/include/linux/input.h中给出的:
#define EV_VERSION 0x010000
linux-3.6.6中的EV_VERSION是在include/linux/input.h中定义的:
#define EV_VERSION 0x010001
两者不一致,改变任一一个都可以。
再来看触摸屏的绝对值事件,这个在驱动移植的时候肯定是正确,不然测试程序肯定是不正确。
最后看触摸屏的X轴(ABS_X),Y轴(ABS_Y),以及压力(ABS_PRESSURE)。通过查看linux-3.6.6中的触摸屏驱动文件s3c2410_ts.c,发现系统没有给出ABS_PRESSURE,因此为了与tslib一致,linux-3.6.6要加上ABS_PRESSURE内容。在touch_timer_fire函数中的第一input_sync(ts.input);前添加:
input_report_abs(ts.input, ABS_PRESSURE, 1);
在该函数中的第二input_sync(ts.input);前添加:
input_report_abs(ts.input, ABS_PRESSURE, 0);
在s3c2410ts_probe函数内的ts.input->name = "S3C24XX TouchScreen";语句前添加:
input_set_abs_params(ts.input, ABS_PRESSURE, 0, 1, 0, 0);
通过上面的修改,就可以使tslib能够正确识别出开发板的触摸屏,执行ts_calibrate和ts_test命令毫无问题。