tslib 的安装与使用

5 tslib

需要安装好触摸屏驱动

tslib 是一个触摸屏的开源库,可以使用它来访问触摸屏设备,可以给输入设备添加各种“filter”(过滤器,就是各种处理),地址是:http://www.tslib.org/。

编译 tslib 后,可以得到libts库,还可以得到各种工具:较准工具、测试工具。

5.1 tslib 框架分析

tslib的主要代码如下:

在这里插入图片描述

核心在于 “plugins” 目录里的 “插件”,或称为 “module”。这个目录下的每个文件都是一个 module,每个 module 都提供 2 个函数:read、read_mt,前者用于读取单点触摸屏的数据,后者用于读取多点触摸屏的数据。

框架:

在这里插入图片描述

调用ts_open后,可以打开某个设备节点,构造出一个tsdev结构体。然后调用ts_config读取配置文件的处理,假设 /etc/ts.conf 内容如下:

 module_raw input
 module pthres pmin=1
 module dejitter delta=100
 module linear

每行表示一个 “module” 或 “moduel_raw”。

对于所有的 “module”,都会插入 tsdev.list 链表头,也就是 tsdev.list 执行配置文件中最后一个 “module”,配置文件中第一个 “module” 位于链表的尾部。

对于所有的 “module_raw”,都会插入 tsdev.list_raw 链表头,一般只有一个 “module_raw”。

注意:tsdev.list 中最后一个 “module” 会指向 ts_dev.list_raw 的头部。

无论是调用 ts_read 还是 ts_read_mt,都是通过 tsdev.list 中的模块来处理数据的。这写模块是递归调用的,比如 linear 模块的 read 函数如下:

在这里插入图片描述

linear 模块的 read_raw 函数如下:

在这里插入图片描述

因为是递归调用,所有最先使用 input 模块读取设备节点得到原始数据,再依次经过 pthres 模块、dejitter 模块、linear 模块处理后,才返回最终数据。

5.2 编译

  1. 获得源码后解压

  2. 进入源码目录

  3. 配置:

    ./configure  --host=arm-linux-gnueabihf   --prefix=$PWD/tmp
    make
    make install
    cd  tmp
    #然后将 include 下的文件复制到交叉编译工具的 include 中
    cp  include/*  -rf  /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux- \
    	gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/include
    #然后将 lib 下的文件复制到交叉编译工具的 lib 中
    cp  lib/*  -drf  /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux- \
    	gnueabihf/bin/../arm-linux-gnueabihf/libc/usr/lib
    
  4. 将编译好的 tmp 复制到开发板的文件系统

    sudo cp * -rf /home/luo/linux/nfs/buildrootfs

  5. 在开发板中配置 tslib

    1. 打开/etc/ts.conf文件,找到下面这一行:module_raw input,如果有注释,就去掉

    2. 打开/etc/profile 文件,在里面加入如下内容:

export TSLIB_TSDEVICE=/dev/input/event1 #表示触摸设备文件,这里设置为/dev/input/event1,这个要根据具体情况设置
export TSLIB_CALIBFILE=/etc/pointercal #表示校准文件,如果进行屏幕校准的话校准结果就保存在这个文件中,这里设置校准文件为/etc/pointercal,此文件可以不存在,校准的时候会自动生成。
export TSLIB_CONFFILE=/etc/ts.conf #触摸配置文件,文件为/etc/ts.conf,此文件在移植 tslib 的时候会生成。
export TSLIB_PLUGINDIR=/lib/ts #表示 tslib 插件目录位置,目录为/lib/ts。
export TSLIB_CONSOLEDEVICE=none #表示控制台设置,这里不设置,因此为 none
export TSLIB_FBDEVICE=/dev/fb0	#屏幕驱动文件

5.3 测试

电容屏可以不用校准,如果是电阻屏就要先进行校准!校准的话输入如下命令:ts_calibrate

校准完成以后如果不满意,或者不小心对电容屏做了校准,那么直接删除掉/etc/pointercal文件即可。 最后我们使用 ts_test_mt 这个软件来测试触摸屏工作是否正常,以及多点触摸是否有效,
执行如下所示命令:ts_test_mt
在这里插入图片描述

其中 :

  • Drag 为拖拽,按下后,用手指接触屏幕,会有十字光标跟随,多点就有多个光标
  • Draw 为绘制,按下后,用手指触摸屏幕,会画出线来,多个手指就同时画出多条线
  • Quit 为退出。

5.4 应用测试

5.4.1 头文件

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <getopt.h>

#include <linux/input.h>

#include <sys/ioctl.h>

#include <tslib.h>

5.4.2 distance 函数

int distance(struct ts_sample_mt *point1, struct ts_sample_mt *point2)
{
	int x = point1->x - point2->x;
	int y = point1->y - point2->y;

	return x*x + y*y;
}

5.4.3 main 函数

int main(int agrc, char **argv)
{
	struct tsdev *ts;
	int i, ret;
	struct ts_sample_mt **samp_mt;
	struct ts_sample_mt **pre_samp_mt;
	int max_slots;
	int point_pressed[20];
	struct input_absinfo slot;
	int touch_cnt = 0;
	ts = ts_setup(NULL, 0);
	if(ts == NULL)
		goto setup_fail;
	
	if(ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT),&slot) < 0)
		goto ioctl_fail;
	
	max_slots = slot.maximum + 1 - slot.minimum;
	samp_mt = malloc(sizeof(struct ts_sample_mt *));
	if(samp_mt == NULL){
		goto mem_fail;
	}
	samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
	if(samp_mt == NULL){
		free(samp_mt);
		goto mem_fail;
	}

	pre_samp_mt = malloc(sizeof(struct ts_sample_mt *));
	if(pre_samp_mt == NULL)
		goto mem_fail;

	pre_samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
	if(pre_samp_mt[0] == NULL){
		free(pre_samp_mt);
		goto mem_fail;
	}

	for(i = 0; i<max_slots; i++){
		pre_samp_mt[0][i].valid = 0;
	}

	while(1){
		ret = ts_read_mt(ts, samp_mt, max_slots, 1);
		if(ret < 0){
			printf("ts_read_mt error!\n");
			ts_close(ts);
			return -1;
		}

		for(i = 0; i<max_slots; ++i)
			if(samp_mt[0][i].valid)
				memcpy(&pre_samp_mt[0][i], &samp_mt[0][i], sizeof(struct ts_sample_mt));

		touch_cnt = 0;
		for(i=0; i<max_slots; ++i)
			if(pre_samp_mt[0][i].valid && pre_samp_mt[0][i].tracking_id != -1)
				point_pressed[touch_cnt++] = i;

		if(touch_cnt == 2)
			printf("distance : %08d\n",distance(&pre_samp_mt[0][point_pressed[0]],
						&pre_samp_mt[0][point_pressed[1]]));
				
	}
	return 0;
setup_fail:
	printf("ts_setup error!\n");
	return -1;
ioctl_fail:
	perror("ioctl EVIOGABS");
	ts_close(ts);
	return errno;
mem_fail:
	ts_close(ts);
	return -ENOMEM;

}

5.4.4 makefile

KERNELDIR := /home/luo/linux/IMX6ULL/linux-imx-rel_imx_4.1.15_2.1.0_ga_alpha
CURRENT_PATH := $(shell pwd)

CROSS_COMPILE ?= arm-linux-gnueabihf-

build: kernel_modules

kernel_modules:
	$(CROSS_COMPILE)gcc -o mt_cal_distance mt_cal_distance.c -lts

clean:
	rm mt_cal_distance

5.4.5 测试结果

会打印出两点的距离

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值