【转载】tslib移植_freescale imx6
本文来自网络:http://blog.csdn.net/xishuang_gongzi/article/details/49422879
环境:
host:Ubuntu12.04
target:freescale imx6
交叉编译链:4.6.2
tslib源代码:在https://github.com/kergoth/tslib下载到较新版本
tslib安装目标路径:/imx_disk/xx/qt/tslib
安装步骤:
1.准备工作
确保以下软件已安装
# apt-get install autoconf(或autoconf2.13) # apt-get install automake # apt-get install libtool
2.下载
https://github.com/kergoth/tslib下载新版本
3.配置
解压源代码tslib-master.zip,并进入源代码文件夹
# unzip tslib-master # cd tslib-master
配置
# ./autogen.sh # echo "ac_cv_func_malloc_0_nonnull=yes" > arm-none-Linux-gnueabi.cache
# ./configure CC=/opt/freescale/usr/local/gcc-4.6.2-glibc-2.13-linaro-multilib-2011.12/fsl-linaro-toolchain/bin/arm-fsl-linux-gnueabi-gcc --host=arm-none-linux-gnueabi --cache-file=arm-none-linux-gnueabi.cache --prefix=/imx_disk/xx/qt/tslib/tslib
注意,prefix选项更换为你的安装路径。
4 修改源码:
①由于触摸屏驱动没有提供ioctl接口,需要屏蔽tslib中ioctl相关代码。否则运行有错误。
vi ./plugins/input-raw.c
屏蔽掉static int check_fd(struct tslib_input *i)中所有ioctl相关代码,只保留一句i->using_syn = 1;。最终代码如下:
- static int check_fd(struct tslib_input *i)
- {
- /* struct tsdev *ts = i->module.dev;
- int version;
- long evbit[BITS_TO_LONGS(EV_CNT)];
- long absbit[BITS_TO_LONGS(ABS_CNT)];
- long keybit[BITS_TO_LONGS(KEY_CNT)];
- if (ioctl(ts->fd, EVIOCGVERSION, &version) < 0) {
- fprintf(stderr, "tslib: Selected device is not a Linux input event device\n");
- return -1;
- }
- if (version < EV_VERSION) {
- fprintf(stderr, "tslib: Selected device uses a different version of the event protocol than tslib was compiled for\n");
- return -1;
- }
- if ( (ioctl(ts->fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) ||
- !(evbit[BIT_WORD(EV_ABS)] & BIT_MASK(EV_ABS)) ||
- !(evbit[BIT_WORD(EV_KEY)] & BIT_MASK(EV_KEY)) ) {
- fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS and KEY event types)\n");
- return -1;
- }
- if ((ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit)) < 0 ||
- !(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) ||
- !(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) {
- fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS_X and ABS_Y events)\n");
- return -1;
- }*/
- /* Since some touchscreens (eg. infrared) physically can't measure pressure,
- the input system doesn't report it on those. Tslib relies on pressure, thus
- we set it to constant 255. It's still controlled by BTN_TOUCH/BTN_LEFT -
- when not touched, the pressure is forced to 0. */
- /* Since some touchscreens (eg. infrared) physically can't measure pressure,
- the input system doesn't report it on those. Tslib relies on pressure, thus
- we set it to constant 255. It's still controlled by BTN_TOUCH/BTN_LEFT -
- when not touched, the pressure is forced to 0. */
- /* if (!(absbit[BIT_WORD(ABS_PRESSURE)] & BIT_MASK(ABS_PRESSURE))) {
- i->current_p = 255;
- if ((ioctl(ts->fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) ||
- !(keybit[BIT_WORD(BTN_TOUCH)] & BIT_MASK(BTN_TOUCH) ||
- keybit[BIT_WORD(BTN_LEFT)] & BIT_MASK(BTN_LEFT))) {
- fprintf(stderr, "tslib: Selected device is not a touchscreen (must support BTN_TOUCH or BTN_LEFT events)\n");
- return -1;
- }
- }
- if (evbit[BIT_WORD(EV_SYN)] & BIT_MASK(EV_SYN))
- i->using_syn = 1;
- if (i->grab_events == GRAB_EVENTS_WANTED) {
- if (ioctl(ts->fd, EVIOCGRAB, (void *)1)) {
- fprintf(stderr, "tslib: Unable to grab selected input device\n");
- return -1;
- }
- i->grab_events = GRAB_EVENTS_ACTIVE;
- }*/
- i->using_syn = 1;
- return 0;
- }
②若ts_calibrate 测试,无反应,可能是触摸屏驱动中没有report 压力值。一般电容屏驱动不上传压力值,我们使用ft5x06触摸芯片,驱动中probe函数中设置set_bit(ABS_PRESSURE, input_dev->absbit);,然后随报点上传压力值input_report_abs(data->input_dev, ABS_PRESSURE, 1); 触摸点为0时说明触摸结束,input_report_abs(data->input_dev, ABS_PRESSURE, 0);
5.编译
# make
6.安装
# make install
7.移植至开发板
将安装路径下的整个tslib文件夹,下载至开发板的上,我存放的路径为/usr/local
8. 修改ts.conf内容
打开安装路径下的/etc/ts.conf文件,修改其内容。
# vi /usr/local/tslib/etc/ts.conf
下面是ts.conf文件的第一行与第二行
# Uncomment if you wish to use the linux input layer event interface # module_raw input
去掉# module_raw input前面的注释,一定要注意中间的空格也去掉,module顶格。
配置文件ts.conf内容如下:
module_raw input
module pthres pmin=1
module variance delta=30
module dejitter delta=100
module linear
module_raw有许多种,这里只使用input(即Linux的input子系统)后面的几个module还没有深入了解,它们使用的库就在tslib/lib/ts中,最后三个模块的字面意思是“方差(滤波)”、“去抖动(去噪)”、“线性(坐标变换)”
9. 设置开发板环境变量
通过超级终端, 打开环境变量文件/etc/profile
# vi /etc/profile
添加如下内容:
export TSLIB_CONSOLEDEVICE=none export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_ROOT=/usr/local/tslib export TSLIB_TSDEVICE=/dev/input/event2
#export QWS_MOUSE_PROTO=tslib:/dev/input/event2 export TSLIB_CALIBFILE=/etc/pointercal export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TSLIB_ROOT/lib
其中,TSLIB_ROOT更换为自己实际存放的路径;
另外,TSLIB_TSDEVICE 和QWS_MOUSE_PROTO这两项需要查看自己的板子的触摸屏设备对应/dev/input/下那个文件。
说明:
TSLIB_TSDEVICE //触摸屏设备文件名。
TSLIB_CALIBFILE //校准的数据文件,由ts_calibrate校准程序生成。
SLIB_CONFFILE //配置文件名。
TSLIB_PLUGINDIR //插件目录
TSLIB_CONSOLEDEVICE //控制台设备文件名
TSLIB_FBDEVICE //设备名
以上环境变量在实际开发中的实际配置可以根据实际情况决定。而这些指定的设备节点一定要和你的开发板上的/dev目录下的设备节点相对应。
10 触摸屏设备检查
①检查系统中是否包含触摸屏设备和鼠标设备
使用cat /proc/bus/input/devices查看
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name="ft5x0x_ts"
P: Phys=
S: Sysfs=/devices/virtual/input/input15
U: Uniq=
H: Handlers=event2
B: PROP=0
B: EV=b
B: KEY=0
B: ABS=2650000 1000000
②检查是否包含触摸屏设备和鼠标设备的文件,不存在则建立即可
ls /dev/ 查看是否包含上述的文件名event2
如果不包含,可以用cat命令查看上面的S: Sysfs后跟的设备名,即可找到设备的主设备号和次设备好。就可以创建设备了。如:
cat /sys/devices/virtual/input/input15/event2/uevent
MAJOR=13
MINOR=66
DEVNAME=input/event2
③就可以在/dev/input下建立设备event2了。
#mknod /dev/input/event1 c 13 66
④检测触摸屏驱动是否正常
首先初步检测驱动:
#cat /dev/input/event2
轻按触摸屏。。。终端输出乱码,表明触摸屏正常!
再编写简单应用层代码测试:
- #include<stdio.h>
- #include<sys/types.h>
- #include<sys/stat.h>
- #include<fcntl.h>
- #include<unistd.h>
- #include <linux/input.h>
- int main(int argc, char *argv[])
- {
- struct input_event event;
- char *device = argv[1];
- int ret = 0;
- int fd = open(device, O_RDWR);
- if(fd < 0){
- fprintf(stderr, "open %s failed!",device);
- return -1;
- }
- ret = read(fd, &event, sizeof(event));
- if(ret < (int)sizeof(event)){
- fprintf(stderr, "could not get event");
- return -1;
- }
- printf("%04x %04x %08x", event.type, event.code, event.value);
- return 0;
- }
11 运行
运行校准程序:
/usr/local/tslib/bin/ts_calibrate
xres = 1280, yres = 800
Took 3 samples...
Top left : X = 28 Y = 45
Took 6 samples...
Top right : X = 1221 Y = 47
Took 54 samples...
Bot right : X = 1215 Y = 754
Took 26 samples...
Bot left : X = 40 Y = 769
Took 4 samples...
Center : X = 635 Y = 403
16.143372 0.996495 -0.004317
1.869019 0.005320 0.978174
Calibration constants: 1057972 65306 -282 122488 348 64105 65536
生成的校准文件名为pointercal,位于/etc目录下。
运行测试程序:
./ts_test
即可。
屏幕最上方会出现三个按钮,分别为“Drag”、“Draw”和“Quit”,默认是第一个,因此,用触摸笔点击任何一处,十字光标便会到那里。
下面是点击“Draw”按钮并用触摸笔写字的提示信息的一小部分:
1302603922.770286: 98 302 1
1302603922.800295: 107 300 1
1302603922.815277: 118 297 1
1302603922.830291: 130 294 1
1302603922.845288: 143 290 1
1302603922.845288: 151 288 1
1302603922.875166: 168 284 0
第一列为timeval结构体的两个成员:tv_sec和tv_usec,中间两列分别是X和Y的坐标,最后为pressure,这里可以理解成“触摸事件”,为1表示触摸笔点击了(接触)屏幕,为0表示触摸笔离开了屏幕
12 错误处理
①./autogen.sh执行失败是因为缺少工具,通过sudo apt-get install autoconf automake libtool安装相应工具。
②
Couldnt open tslib config file: No such file or directory
ts_config: No such file or directory
原因:一般为环境变量 TSLIB_PLUGINDIR 设置问题。可以查看ts_config.c代码,打印出具体路径查看错误原因
③打不开module input
Couldnt load module input
No raw modules loaded.
tsconfig: Success
原因分析:
查看ts.conf中module_raw的配置
编译选项需要增加 --enable_input=yes 否则没有input.so文件
④
ts open
tslib: Selected device is not a Linux input event device
原因分析:input-raw.c 函数需要根据底层驱动做适当修改。
触摸屏驱动没有提供ioctl接口,要删除代码中与ioctl有关的所有函数。
⑤Segmentation fault
解决:一般是因为配置文件ts.conf格式错误。参数前面不能有空格。
⑥
#ts_calibrate
ts_open: No such file or directory
可能是触摸屏驱动没有加载,找不到设备节点