【Linux应用编程笔记】tslib库使用

2023-12-17 19:12

本文主要是介绍【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. 打开触摸屏设备
  2. 配置触摸屏设备
  3. 读取触摸屏设备
  4. 关闭触摸屏设备

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库使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/505521

相关文章

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

MySQL的JDBC编程详解

《MySQL的JDBC编程详解》:本文主要介绍MySQL的JDBC编程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、前置知识1. 引入依赖2. 认识 url二、JDBC 操作流程1. JDBC 的写操作2. JDBC 的读操作总结前言本文介绍了mysq

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1