本文主要是介绍【Linux应用编程笔记】tslib库使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
系列文章目录
【Linux应用编程笔记】GPIO
【Linux应用编程笔记】输入设备
本系列使用的开发板为正点原子阿尔法IMX6ULL开发板,及根据正点原子所的提供教程学习
文章目录
- 系列文章目录
- 做什么?
- 一、tslib简介
- 二、tslib移植
- 1、编译tslib源码
- 2、tslib安装目录文件夹及移植
- 1、bin目录
- 2、etc目录
- 3、include目录
- 4、lib目录
- 5、share目录
- 三、tslib库的使用
- 1、环境变量配置
- 2、tslib库函数介绍
- 1、打开触摸屏设备
- 2、配置触摸屏设备
- 3、读取触摸屏数据
- 4、关闭触摸屏设备
- 5、结构体
- 四、应用编程
- 1、单点触摸
- 2、多点触摸
- 3、编译
做什么?
学习tslib库的使用
一、tslib简介
一个专门为触摸屏设备开发的开源Linux应用层函数库,可作为Qt的触摸屏输入插件,为Qt提供触摸输入支持。
tslib为触摸屏驱动和应用层之间的适配层,它把应用程序中读取触摸屏struct input_event类型数据并进行解析的操作过程进行了封装,向使用者提供了等装好的API接口。
二、tslib移植
1、编译tslib源码
下载 tslib 源码包
将下载好的源码包拷贝至Ubuntu系统中解压,创建一个目录用来安装tslib。
进入解压后的源码包目录中准备编译tslib源码,编译前记得先对交叉编译工具的环境进行设置:
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
然后对tslib源码工程进行设置:
./configure --host=arm-poky-linux-gnueabi --prefix=xx //这里的“xx”是安装路径
–host 选项用于指定交叉编译得到的库文件是运行在哪个平台,通常将–host 设置为交叉编译器名称的前缀,譬如 arm-pokylinux-gnueabi-gcc 前缀就是 arm-poky-linux-gnueabi;–prefix 选项则用于指定库文件的安装路径
接着make,然后再make install就可以了
2、tslib安装目录文件夹及移植
这里使用的根文件系统是挂载的BusyBox(之前跟着教程做的),内核和设备树使用的是出厂系统
。
1、bin目录
一些小工具,用于测试触摸屏。这个文件目录下的所有可执行文件要拷贝到开发板上的/bin目录下。
2、etc目录
里面就一个配置文件ts.conf,需要拷贝到开发板的/etc目录下
3、include目录
只有一个头文件tslib.h,包含了一些结构体数据结构以及API接口的声明,所以使用tslib提供的API就要包含这个头文件
4、lib目录
这里包含了编译tslib源码所得到的库文件,默认为动态库文件,也可以通过配置使其生成静态库文件,ts目录下存放的是一些插件库。这个目录下的所有库文件都要拷贝到开发板的/lib目录下。
5、share目录
教程上说可忽略。
三、tslib库的使用
1、环境变量配置
使用tslib前需要配置一些环境变量,因为它工作时需要依赖于一些环境变量
export TSLIB_CONSOLEDEVICE=none //配置控制台设备文件名,直接为none即可
export TSLIB_FBDEVICE=/dev/fb0 //配置显示设备的名称
export TSLIB_TSDEVICE=/dev/input/event1 //配置触摸屏对应的设备节点
export TSLIB_CONFFILE=/etc/ts.conf //配置ts.con文件的路径
export TSLIB_PLUGINDIR=/lib/ts //配置插件所在的路径
配置到这就可以使用tslib提供的测试工具了,比如:
ts_print:单点触摸工具
ts_print_mt:多点触摸工具
ts_print:在终端打印触摸点信息
... ...
如果不想每次开机都把环境变量配置敲一遍就配置一下/etc/profile(没有这个文件就自己创建一个)
,也可以不配置
# /etc/profile# 这是一个示例profile脚本# No core files by default
ulimit -S -c 0 > /dev/null 2>&1USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]\# '
PATH=$PATHHOSTNAME=`/bin/hostname`export USER LOGNAME PS1 PATHexport TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
2、tslib库函数介绍
tslib的基本使用步骤:
- 打开触摸屏设备
- 配置触摸屏设备
- 读取触摸屏设备
- 关闭触摸屏设备
1、打开触摸屏设备
#include "tslib.h"
struct tsdev *ts_open(const char *dev_name, int nonblock);
dev_name:触摸屏的设备节点
nonblock:0:阻塞方式打开触摸屏设备非0:非阻塞方式打开触摸屏设备
返回值:成功:返回一个 struct tsdev *指针,指向触摸屏设备句柄失败:NULLstruct tsdev *ts_setup(const char *dev_name, int nonblock)
dev_name:触摸屏的设备节点,当设置为NULL时函数内部会读取TSLIB_TSDEVICE 环境变量,获取该环境变量的内容以得知触摸屏的设备节点(就是之前设置的环境变量)
nonblock:0:阻塞方式打开触摸屏设备非0:非阻塞方式打开触摸屏设备
教程上说这个函数能对触摸屏设备进行配置,但是没有说怎么配置,也可能没找到,先空着
2、配置触摸屏设备
#include "tslib.h"
int ts_config(struct tsdev *ts)
ts:指向触摸屏句柄,就是打开成功返回的那个
返回值:成功:0失败:-1
配置就是解析ts.conf文件中的配置信息,加载相应的插件。
3、读取触摸屏数据
#include "tslib.h"//读取单点触摸数据
int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr)
samp:一个 struct ts_sample *类型的指针,指向一个struct ts_sample对象,获取到的数据会存这里面//读取多点触摸数据
int ts_read_mt(struct tsdev *ts, struct ts_sample_mt **samp, int max_slots, int nr)
max_slots:触摸屏设备支持的最大触摸点数
samp :是一个 struct ts_sample_mt **类型的指针,多点触摸,每个触摸点的信息struct ts_sample_mt 数据结构来描述。
一个触摸点的数据就是struct ts_sample,这堆触摸点合起来就是struct ts_sample_mt 数组ts:指向触摸屏设备句柄,就是打开成功返回的那个
nr:指定了 ts_read 函数要从设备中读取多少字节的数据。如果设备中没有足够的数据可供读取,则 ts_read 函数将等待,直到有足够的数据可供读取或者发生错误。,设置为1即可。
4、关闭触摸屏设备
int ts_close(struct tsdev *);
//函数指针,只需要传递一个struct tsdev类型的指针就好了
5、结构体
struct ts_sample {int x; //X 坐标int y; //Y 坐标unsigned int pressure; //按压力大小struct timeval tv; //时间
};struct ts_sample_mt {/* ABS_MT_* event codes. linux/include/uapi/linux/input-event-codes.h* has the definitions.*/int x; //X 坐标int y; //Y 坐标unsigned int pressure; //按压力大小int slot; //触摸点 slotint tracking_id; //IDint tool_type;int tool_x;int tool_y;unsigned int touch_major;unsigned int width_major;unsigned int touch_minor;unsigned int width_minor;int orientation;int distance;int blob_id;struct timeval tv; //时间/* BTN_TOUCH state */short pen_down; //BTN_TOUCH 的状态/* valid is set != 0 if this sample* contains new data; see below for the* bits that get set.* valid is set to 0 otherwise*/short valid; //此次样本是否有效标志 触摸点数据是否发生更新
};
四、应用编程
1、单点触摸
#include <stdio.h>
#include <stdlib.h>
#include <tslib.h> //包含 tslib.h 头文件
int main(int argc, char *argv[])
{struct tsdev *ts = NULL;struct ts_sample samp;int pressure = 0;//用于保存上一次的按压力,初始为 0,表示松开/* 打开并配置触摸屏设备 */ts = ts_setup(NULL, 0);if (NULL == ts) {fprintf(stderr, "ts_setup error");exit(EXIT_FAILURE);}/* 读数据 */for ( ; ; ) {if (0 > ts_read(ts, &samp, 1)) {fprintf(stderr, "ts_read error");ts_close(ts);exit(EXIT_FAILURE);}if (samp.pressure) {//按压力>0if (pressure) //若上一次的按压力>0printf("移动(%d, %d)\n", samp.x, samp.y);elseprintf("按下(%d, %d)\n", samp.x, samp.y);}elseprintf("松开\n");//打印坐标pressure = samp.pressure;}ts_close(ts);exit(EXIT_SUCCESS);
}
2、多点触摸
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <tslib.h>
int main(int argc, char *argv[])
{struct tsdev *ts = NULL;struct ts_sample_mt *mt_ptr = NULL;struct input_absinfo slot;int max_slots;unsigned int pressure[12] = {0}; //用于保存每一个触摸点上一次的按压力,初始为 0,表示松开int i;/* 打开并配置触摸屏设备 */ts = ts_setup(NULL, 0);if (NULL == ts) {fprintf(stderr, "ts_setup error");exit(EXIT_FAILURE);}/* 获取触摸屏支持的最大触摸点数 */if (0 > ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot)) {perror("ioctl error");ts_close(ts);exit(EXIT_FAILURE);}max_slots = slot.maximum + 1 - slot.minimum;printf("max_slots: %d\n", max_slots);/* 内存分配 */mt_ptr = calloc(max_slots, sizeof(struct ts_sample_mt));/* 读数据 */for ( ; ; ) {if (0 > ts_read_mt(ts, &mt_ptr, max_slots, 1)) {perror("ts_read_mt error");ts_close(ts);free(mt_ptr);exit(EXIT_FAILURE);}for (i = 0; i < max_slots; i++) {if (mt_ptr[i].valid) {//有效表示有更新!if (mt_ptr[i].pressure) { //如果按压力>0if (pressure[mt_ptr[i].slot])//如果上一次的按压力>0printf("slot<%d>, 移动(%d, %d)\n", mt_ptr[i].slot, mt_ptr[i].x, mt_ptr[i].y);elseprintf("slot<%d>, 按下(%d, %d)\n", mt_ptr[i].slot, mt_ptr[i].x, mt_ptr[i].y);}elseprintf("slot<%d>, 松开\n", mt_ptr[i].slot);pressure[mt_ptr[i].slot] = mt_ptr[i].pressure;}}}/* 关闭设备、释放内存、退出 */ts_close(ts);free(mt_ptr);exit(EXIT_SUCCESS);
}
3、编译
${CC} -I /home/xx/linux/tools/tslib/include -L /home/xx/linux/tools/tslib/lib -lts -o LCDAPP LCD.c
-I:可以让编译器在指定的目录中搜索头文件,以便正确地编译源代码文件。
/home/xx/linux/tools/tslib/include:tslib 库的头文件所在的目录。
-L:可以让编译器在指定的目录中搜索库文件,以便正确地链接库函数并生成可执行文件。
/home/xx/linux/tools/tslib/lib:tslib 库的库文件所在的目录。
-lts:指定了需要链接的库文件名,其中 -l 表示链接库文件,ts 表示库文件名为 libts.so。Linux 中,动态库文件的命名方式为 lib+名字+.so
-o:指定了编译生成的可执行文件的名称,其中LCDAPP是可执行文件的名称。
LCD.c:这个参数指定了需要编译的源代码文件的名称,其中 LCD.c 是 C 语言源代码文件的名称。
这篇关于【Linux应用编程笔记】tslib库使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!