tslib 库-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

tslib 库

在这里插入图片描述

tslib 简介

tslib 库,这是 Linux 系统下,专门为触摸屏开发的应用层函数库,开源

功能与作用:作为触摸屏驱动和应用层之间的适配层,封装了读取和解析触摸屏数据的复杂过程,提供API接口

数据处理:从触摸屏获取原始坐标数据,进行去噪、去抖和坐标变换等操作,转换为屏幕坐标

配置文件:包含配置文件 ts.conf,用户可以修改以调整参数

与Qt的集成:tslib 可作为 Qt 的触摸屏输入插件,提供触摸输入支持,但并非唯一选择

移植应用:介绍如何将 tslib 库移植到开发板平台

tslib 移植

下载 tslib 源码

  • git 仓库下载源码 https://github.com/libts/tslib/releases

编译 tslib 源码

  • 前期准备工作

    • 将 tslib 源码拷贝到 Ubuntu 系统

    • 解压 tslib 压缩包

      • 将其解压到当前目录下:

      • tar -xzf tslib-1.16.tar.gz

    • 在家目录下创建一个 tools 目录,然后在 tools 目录下创建 tslib 目录,等会编译 tslib 库的时候将安装目录指定到这里

    • 进入到 tslib-1.16 目录,准备进行编译 tslib 源码

    • 对交叉编译工具的环境进行设置

      • source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
  • 第一步是配置工程

    • ./configure --host=arm-poky-linux-gnueabi --prefix=/home/dt/tools/tslib/

    • 可以执行./configure --help 查看它的配置选项以及含义

    • –host 设置为交叉编译器名称的前缀

    • –prefix 选项则用于指定库文件的安装路径

  • 第二步是编译工程

    • 直接执行 make
  • 第三步是安装,将编译得到的库文件、可执行文件等安装到一个指定的目录下

    • make install

tslib 安装目录下的文件夹介绍

  • bin 目录

    • tslib 提供的小工具,可以用于测试触摸屏
  • etc 目录

    • 有一个配置文件 ts.conf

      • ts.conf 文件的内容

      • module_raw input:取消注释以启用 input 输入事件支持

      • module pthres pmin=1:启用按压力测试,pmin 调节按压力灵敏度,默认值为1

      • module dejitter delta=100:启用触摸屏去噪算法插件,delta 默认参数为100

      • module linear:启用触摸屏坐标变换功能,如坐标互换和旋转

  • include 目录

    • 目录结构:include 目录下仅包含一个头文件 tslib.h

    • 头文件内容:tslib.h 包含结构体数据结构和 API 接口的声明

    • API 使用:使用 tslib 提供的 API 时,需要包含 tslib.h 头文件

  • lib 目录

    • 包含编译 tslib 源码得到的库文件,默认是动态库文件

    • 静态库:通过配置 tslib 工程可以生成静态库文件

    • ts 目录:存放一些插件库

  • share 目录

在开发板上测试 tslib

  • 文件拷贝步骤

    • 将安装目录 bin/目录下的所有可执行文件拷贝到开发板/usr/bin 目录下

    • 将安装目录 etc/目录下的配置文件 ts.conf 拷贝到开发板/etc 目录下

    • 将安装目录 lib/目录下的所有库文件拷贝到开发板/usr/lib 目录下

  • 配置环境变量

    • export TSLIB_CONSOLEDEVICE=none
      export TSLIB_FBDEVICE=/dev/fb0
      export TSLIB_TSDEVICE=/dev/input/event1
      export TSLIB_CONFFILE=/etc/ts.conf
      export TSLIB_PLUGINDIR=/usr/lib/ts

    • TSLIB_CONSOLEDEVICE:配置控制台设备文件名,设置为 none

    • TSLIB_FBDEVICE:配置显示设备名称,指定显示设备的设备节点

    • TSLIB_TSDEVICE:配置触摸屏对应的设备节点,根据实际情况设置

    • TSLIB_CONFFILE:配置 ts.conf 文件路径

    • TSLIB_PLUGINDIR:配置插件所在路径

    • 将这些配置写入 /etc/profile 文件中,以确保每次启动系统时都能生效

  • 多点触摸测试工具

    • 单点触摸测试工具(ts_print、ts_test)

    • 多点触摸测试工具(ts_print_mt、ts_test_mt)

    • ts_print 和 ts_print_mt 可以在终端打印触摸点信息,而 ts_test 和
      ts_test_mt 则支持在 LCD 上画线

      • 执行ts_print 命令,在触摸屏上滑动、或按下、松开触摸屏将会在终端打印出相应的信息

      • ts_print_mt 也是如此,不过它支持多点触摸

    • 查看测试工具源码

      • 如果你对这些测试工具的实现感兴趣,可以在 tslib 源码目录下的 tests 文件夹中找到相应的源码

tslib 库函数的使用介绍

打开和关闭触摸屏设备

  • 打开触摸屏设备

    • 打开触摸屏设备函数 - ts_open

      • #include “tslib.h”
        struct tsdev *ts_open(const char *dev_name, int nonblock);

      • dev_name:触摸屏的设备节点

      • nonblock:是否以非阻塞方式打开设备,0 表示阻塞,非 0 表示非阻塞

      • 返回值:
        成功:返回指向触摸屏设备句柄的指针 (struct tsdev *)
        失败:返回 NULL

    • 打开和配置触摸屏设备函数 - ts_setup

      • #include “tslib.h”
        struct tsdev *ts_setup(const char *dev_name, int nonblock)

      • dev_name:触摸屏的设备节点,可设置为 NULL,此时从环境变量 TSLIB_TSDEVICE 获取设备节点

      • nonblock:是否以非阻塞方式打开设备,0 表示阻塞,非 0 表示非阻塞

      • ts_setup()相比 ts_open(),除了打开触摸屏设备外,还对触摸屏设备进行了配置

  • 关闭触摸屏设备函数 - ts_close

    • int ts_close(struct tsdev *);

配置触摸屏设备

  • 功能:解析 ts.conf 文件中的配置信息,加载相应的插件

  • #include “tslib.h”
    int ts_config(struct tsdev *ts)

  • ts:指向触摸屏句柄的指针

  • 成功返回 0,失败返回-1

读取触摸屏数据

  • 读取单点触摸数据 - ts_read

    • #include “tslib.h”
      int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr)

      • 功能:
        读取单点触摸数据并存放在 samp 指针所指向的内存中

      • ts:指向触摸屏设备句柄的指针

      • samp:指向一个 struct ts_sample 对象的指针,描述单个触摸点的信息

        • struct ts_sample {
          int x; //x坐标
          int y; //y坐标
          unsigned int pressure; //按压力大小
          struct timeval tv; //时间
          };
      • nr:采样数,设置为 1 即可

  • 读取多点触摸数据 - ts_read_mt

    • #include “tslib.h”
      int ts_read_mt(struct tsdev *ts, struct ts_sample_mt **samp, int max_slots, int nr)

      • 功能:
        读取多点触摸数据,将数据存放在 samp 指针所指向的 struct ts_sample_mt 数组中

      • ts:指向触摸屏设备句柄的指针

      • samp:指向 struct ts_sample_mt 数组的指针,描述多个触摸点的信息,每个触摸点使用一个 struct ts_sample_mt 对象

        • struct ts_sample_mt 结构体

      • max_slots:触摸屏支持的最大触摸点数

        • 应用程序可以通过 ioctl() 函数获取触摸屏支持的最大触摸点数和坐标的最大分辨率等信息
      • nr:表示对一个触摸点的采样数,设置为 1 即可

基于 tslib 库函数编写触摸屏应用程序

单点触摸应用程序

#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);//从环境变量 TSLIB_TSDEVICE 获取设备节点//以阻塞方式打开设备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);// 退出程序,返回成功状态
}
  • 程序

    • 打开并配置设备:调用 ts_setup 函数打开并配置触摸屏设备

      • 从环境变量 TSLIB_TSDEVICE 获取设备节点,以阻塞方式打开设备
    • 检查设备是否打开:检查 ts_setup 是否成功,如果失败则输出错误信息并退出

    • 无限循环读取数据:进入无限循环,读取触摸屏数据

      • 读取数据:调用 ts_read 函数读取一个样本数据

        • 检查读取结果:检查 ts_read 是否成功,如果失败则输出错误信息并退出
      • 处理按压力:根据当前样本的按压力进行处理

        • 按压力大于0:如果当前样本的按压力大于0,进一步判断上一次的按压力

          • 上一次按压力大于0:如果上一次的按压力也大于0,打印“移动”

          • 如果上一次的按压力等于0,打印“按下”

        • 按压力小于等于0:如果当前样本的按压力等于0,打印“松开”

      • 更新按压力:更新上一次的按压力为当前样本的按压力

    • 关闭设备:关闭触摸屏设备

    • 退出程序,返回成功状态

  • 编译

    • ${CC} -I /home/alientek/linux/IMX6ULL/tool/tslib/include -L /home/alientek/linux/IMX6ULL/tool/tslib/lib -lts -o testApp testApp.c

    • -I 选项用于指定头文件路径,指向 tslib 安装目录的 include 目录,缺少时会找不到 tslib.h

    • -I 选项用于指定头文件路径,指向 tslib 安装目录的 include 目录,缺少时会找不到 tslib.h

    • 编译时需要链接到动态库文件,使用 -l 选项指定链接库

    • 动态库文件命名方式为 lib+名字+.so,例如 -l ts 对应 libts.so

  • 验证

    • 单点触摸应用程序测试

多点触摸应用程序

#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])//如果上一次的按压力>0//short valid; //此次样本是否有效标志 触摸点数据是否发生更新printf("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);
}
  • 程序

    • 打开并配置触摸屏设备

      • 调用 ts_setup 函数初始化触摸屏设备

      • 如果初始化失败,输出错误信息并退出程序

    • 获取触摸屏支持的最大触摸点数

      • 使用 ioctl 获取最大触摸点数

      • 如果获取失败,输出错误信息,关闭设备并退出程序

    • 为触摸样本分配内存

    • 读数据:
      进入无限循环

      • 调用 ts_read_mt 函数读取多点触摸数据

        • 如果读取失败,输出错误信息,关闭设备,释放内存并退出程序
      • 遍历所有触摸点数据,检查每个触摸点数据是否有效

        • 如果有效,检查压力值

          • 如果压力大于0

            • 如果上一次的压力大于0,输出“移动”信息

            • 否则,输出“按下”信息

          • 否则,输出“松开”信息

        • 更新压力值

    • 关闭触摸屏设备,释放内存并退出程序

  • 验证

    • 多点触摸应用程序测试结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/47944.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ 高精度加法(只支持正整数)

再给大家带来一篇高精度&#xff0c;不过这次是高精度加法&#xff01;话不多说&#xff0c;开整&#xff01; 声明 与之前那篇文章一样&#xff0c;如果看起来费劲可以结合总代码来看 定义 由于加法进位最多进1位&#xff0c;所以我们的结果ans[]的长度定义为两个加数中最…

零基础学SpringBoot(一)--初识SpringBoot

1. SpringBoot简介 SpringBoot 是Spring家族中的一个全新的框架&#xff0c;它用来简化Spring应用程序的创建和开发过程&#xff0c;也可以说Spring Boot能简化我们之前采用SSM(SpringMVC Spring MyBatis)框架进行开发的过程。 以前我们采用SSM框架进行开发的时候&#xff0c…

vue3前端开发-小兔鲜项目-二级分类页面无限加载的实现

vue3前端开发-小兔鲜项目-二级分类页面无限加载的实现&#xff01;实际的项目开发中&#xff0c;经常会遇到这需求。产品内容庞大&#xff0c;但是用户不可能一次性全部都加载请求的。当客户向下滚动&#xff0c;触碰到插件的底部时&#xff0c;会再次申请下一页内容。这样就会…

Adobe国际认证详解-动漫制作专业就业方向和前景

动漫制作专业的就业方向和前景随着创意产业的蓬勃发展而愈发广阔。这一专业涵盖了从角色设计、场景绘制到动画制作、特效合成等多个环节&#xff0c;是创意与技术相结合的典型代表。随着数字媒体和互联网的普及&#xff0c;动漫制作专业人才的需求正不断增长&#xff0c;为该专…

2024 杭电多校第一场

目录 目录 树 博弈 传送 树 给一棵根为 1 的有根树&#xff0c;点 i 具有一个权值 Ai 。 定义一个点对的值 f(u,v)max(Au,Av)|Au−Av| 。 你需要对于每个节点 i &#xff0c;计算 ansi∑u∈subtree(i),v∈subtree(i)f(u,v) &#xff0c;其中 subtree(i) 表示 i 的子树。 请…

Vscode离线下载对应版本的ms-python.vsix

一、查看vscode的版本号和发行时间 vscode界面中Help-About查看版本号和发行时间&#xff0c;ms-python的发行时间需要和这个时间相近&#xff1a; 二、在github仓库中查看ms-python有什么版本&#xff0c;以及发行时间 github仓库路径 https://github.com/microsoft/vsco…

虚幻引擎,体积雾、体积光、镜头泛光

1、体积雾 这里介绍的是用于地面的体积雾效果&#xff0c;效果如图1-1&#xff1a; 图1-1 首先&#xff0c;需要场景中存在指数级高度雾并开启体积雾&#xff08;如图1-2&#xff09;。然后创建材质&#xff0c;材质域选择“体积”&#xff0c;混合模式选择“Additive”。材质节…

shell脚本中for循环和while循环

目录 for循环 while 循环 前面说完了if判断语句&#xff0c;现在该来学习shell脚本中的另一个重点内容了&#xff0c;那就是循环语句。循环语句分为 for 循环和 while 循环&#xff0c;二者本质上来说是没有太大区别&#xff0c;但针对不同的情况&#xff0c;使用不同的语句可…

【Git-常用命令】一文搞懂学会git的常用命令以及使用技巧

【Git-常用命令】一文搞懂学会git的常用命令以及使用技巧 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注&…

Lua 语法学习笔记

Lua 语法学习笔记 安装(windows) 官网&#xff1a;https://www.lua.org/ 下载SDK 解压&修改名称&#xff08;去除版本号&#xff09; 将lua后面的版本号去掉&#xff0c;如lua54.exe->lua.ext 配置环境变量 数据类型 数据类型描述nil这个最简单&#xff0c;只有值n…

Java基础(二十四):网络编程

目录 一、网络通信要素1、通信要素一&#xff1a;IP地址和域名1.1、IP地址1.2、域名 2、通信要素二&#xff1a;端口号3、通信要素三&#xff1a;网络通信协议 二、传输层协议&#xff1a;TCP与UDP协议1、TCP协议2、UDP协议3、三次握手4、四次挥手 三、网络编程API1、InetAddre…

收藏必备!ChatGPT助你快速阅读AI论文的全流程解析

尽管论文的旅程尚未开始&#xff0c;但在初次研究地图时&#xff0c;感觉就像在解读天书&#xff0c;难度很大&#xff01; 有什么有效的方法呢&#xff1f; 我们可以借助ChatGPT的强大功能。只需输入相关文献&#xff0c;它便能立刻解析出文献中的关键信息&#xff0c;迅速让…

【瑞芯微RV1126(板端摄像头图像数据采集)】②使用v4l2视频设备驱动框架采集图像数据

RV1126开发板&#xff1a;使用v4l2视频设备驱动框架采集图像数据 前言一、按键二、LCD显示三、V4L2 摄像头应用编程四、完整代码 前言 本系列的目的是&#xff0c;不仅仅将能够进行图片推理的模型部署于板端&#xff0c;还提供了两种摄像头数据采集的方法&#xff0c;集成到自…

redis的集群模式

为什么使用redis 提高并发性和可用性 提供了三种集群模式&#xff1a; 第一种&#xff1a;主从模式 概念&#xff1a;redis主从模式表示一个主节点跟若干个从节点。主节点负责读和写操作&#xff0c;而从节点只负责读操作&#xff0c;主节点的数据会自动同步到从节点上。 如何搭…

树莓派4B从装系统raspbian到vscode远程编程(python)

1、写在前面 前面用的一直是Ubuntu系统&#xff0c;但是遇到一个奇葩的问题&#xff1a; 北通手柄在终端可以正常使用&#xff0c;接收到数据 但在python程序中使用pygame库初始化时总是报错&#xff1a;Invalid device number&#xff0c;检测不到手柄 经过n次重装系统&am…

瑞吉外卖学习(一)

pom文件的导入中 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.6</version><relativePath/> <!-- lookup parent from repository --></…

AIGC Kolors可图IP-Adapter-Plus风格参考模型使用案例

参考: https://huggingface.co/Kwai-Kolors/Kolors-IP-Adapter-Plus 代码环境安装: git clone https://github.com/Kwai-Kolors/Kolors cd Kolors conda create --name kolors python=3.8 conda activate kolors pip install -r requirements.txt python3 setup.py install…

linux虚拟机主机配置网卡

问题复现 我的虚拟主机了连不上远程工具windTerm ,但是我的另一台虚拟主机可以连上 我的解决思路 ping ip 地址 发现能够 ping 通 查看 ifconfig 配置信息 我对比另一个虚拟主机 发现了我的子网掩码netmask有问题 解决方式 第一种 连接配置 配置 ipv4.addresses 192.168.1…

JavaScript青少年简明教程:赋值语句

JavaScript青少年简明教程&#xff1a;赋值语句 赋值语句&#xff08;assignment statement&#xff09; JavaScript的赋值语句用于给变量、对象属性或数组元素赋值。赋值语句的基本语法是使用符号 () 将右侧的值&#xff08;称为“源操作数”&#xff09;赋给左侧的变量、属…

Leetcode—154. 寻找旋转排序数组中的最小值 II【困难】

2024每日刷题&#xff08;147&#xff09; Leetcode—154. 寻找旋转排序数组中的最小值 II 实现代码 class Solution { public:int findMin(vector<int>& nums) {int l 0;int r nums.size() - 1;int m -1;while(l < r) {m (r - l) / 2 l;if(nums[m] < n…