首页 > 代码库 > 【转载】tslib移植_freescale imx6

【转载】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;。最终代码如下:

 

[cpp] view plain copy
 
 print?
  1. static int check_fd(struct tslib_input *i)  
  2. {  
  3. /*  struct tsdev *ts = i->module.dev; 
  4.     int version; 
  5.     long evbit[BITS_TO_LONGS(EV_CNT)]; 
  6.     long absbit[BITS_TO_LONGS(ABS_CNT)]; 
  7.     long keybit[BITS_TO_LONGS(KEY_CNT)]; 
  8.  
  9.     if (ioctl(ts->fd, EVIOCGVERSION, &version) < 0) { 
  10.         fprintf(stderr, "tslib: Selected device is not a Linux input event device\n"); 
  11.         return -1; 
  12.     } 
  13.  
  14.     if (version < EV_VERSION) { 
  15.         fprintf(stderr, "tslib: Selected device uses a different version of the event protocol than tslib was compiled for\n"); 
  16.         return -1; 
  17.     } 
  18.  
  19.     if ( (ioctl(ts->fd, EVIOCGBIT(0, sizeof(evbit)), evbit) < 0) || 
  20.         !(evbit[BIT_WORD(EV_ABS)] & BIT_MASK(EV_ABS)) || 
  21.         !(evbit[BIT_WORD(EV_KEY)] & BIT_MASK(EV_KEY)) ) { 
  22.         fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS and KEY event types)\n"); 
  23.         return -1; 
  24.     } 
  25.  
  26.     if ((ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit)), absbit)) < 0 || 
  27.         !(absbit[BIT_WORD(ABS_X)] & BIT_MASK(ABS_X)) || 
  28.         !(absbit[BIT_WORD(ABS_Y)] & BIT_MASK(ABS_Y))) { 
  29.         fprintf(stderr, "tslib: Selected device is not a touchscreen (must support ABS_X and ABS_Y events)\n"); 
  30.         return -1; 
  31.     }*/  
  32.   
  33.     /* Since some touchscreens (eg. infrared) physically can‘t measure pressure, 
  34.     the input system doesn‘t report it on those. Tslib relies on pressure, thus 
  35.     we set it to constant 255. It‘s still controlled by BTN_TOUCH/BTN_LEFT - 
  36.     when not touched, the pressure is forced to 0. */  
  37.     /* Since some touchscreens (eg. infrared) physically can‘t measure pressure, 
  38.     the input system doesn‘t report it on those. Tslib relies on pressure, thus 
  39.     we set it to constant 255. It‘s still controlled by BTN_TOUCH/BTN_LEFT - 
  40.     when not touched, the pressure is forced to 0. */  
  41.   
  42. /*  if (!(absbit[BIT_WORD(ABS_PRESSURE)] & BIT_MASK(ABS_PRESSURE))) { 
  43.         i->current_p = 255; 
  44.  
  45.         if ((ioctl(ts->fd, EVIOCGBIT(EV_KEY, sizeof(keybit)), keybit) < 0) || 
  46.             !(keybit[BIT_WORD(BTN_TOUCH)] & BIT_MASK(BTN_TOUCH) || 
  47.               keybit[BIT_WORD(BTN_LEFT)] & BIT_MASK(BTN_LEFT))) { 
  48.             fprintf(stderr, "tslib: Selected device is not a touchscreen (must support BTN_TOUCH or BTN_LEFT events)\n"); 
  49.             return -1; 
  50.         } 
  51.     } 
  52.  
  53.     if (evbit[BIT_WORD(EV_SYN)] & BIT_MASK(EV_SYN)) 
  54.         i->using_syn = 1; 
  55.  
  56.     if (i->grab_events == GRAB_EVENTS_WANTED) { 
  57.         if (ioctl(ts->fd, EVIOCGRAB, (void *)1)) { 
  58.             fprintf(stderr, "tslib: Unable to grab selected input device\n"); 
  59.             return -1; 
  60.         } 
  61.         i->grab_events = GRAB_EVENTS_ACTIVE; 
  62.     }*/  
  63.   
  64.     i->using_syn = 1;  
  65.     return 0;  
  66. }  

 

②若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 
轻按触摸屏。。。终端输出乱码,表明触摸屏正常!
再编写简单应用层代码测试:

 

[cpp] view plain copy
 
 print?
  1. #include<stdio.h>  
  2. #include<sys/types.h>  
  3. #include<sys/stat.h>  
  4. #include<fcntl.h>  
  5. #include<unistd.h>  
  6. #include <linux/input.h>  
  7. int main(int argc, char *argv[])  
  8. {  
  9.     struct input_event event;  
  10.     char *device = argv[1];  
  11.     int ret = 0;  
  12.     int fd = open(device, O_RDWR);  
  13.     if(fd < 0){  
  14.         fprintf(stderr, "open %s failed!",device);  
  15.         return -1;  
  16.     }  
  17.     ret = read(fd, &event, sizeof(event));  
  18.     if(ret < (int)sizeof(event)){  
  19.         fprintf(stderr, "could not get event");  
  20.         return -1;  
  21.     }  
  22.     printf("%04x %04x %08x", event.type, event.code, event.value);  
  23.     return 0;  
  24. }  

 

 

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

可能是触摸屏驱动没有加载,找不到设备节点

【转载】tslib移植_freescale imx6