原子学习笔记3——使用tslib库

一、tslib介绍

tslib 是专门为触摸屏设备所开发的 Linux 应用层函数库,并且是开源。
tslib 为触摸屏驱动和应用层之间的适配层,它把应用程序中读取触摸屏 struct input_event 类型数据(这是输入设备上报给应用层的原始数据)并进行解析的操作过程进行了封装,向使用者提供了封装好的 API 接口。

二、tslib 移植

首先进入到 tslib 的 git 仓库下载源码tslib下载地址
下载 1.16 版本的 tslib,往下翻找到 1.16 版本的下载链接:
在这里插入图片描述
点击红框字样进入下载页面:
在这里插入图片描述
下载 tar.gz 格式的压缩包文件,点击文字即可下载。

三、编译 tslib 源码

解压tslib-1.16.tar.gz 源码包
在这里插入图片描述
解压之后会生成 tslib-1.16 目录,tslib包目录下创建一个 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

执行下面这条命令对 tslib 源码工程进行配置:

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

–host 选项用于指定交叉编译得到的库文件是运行在哪个平台,通常将–host 设置为交叉编译器名称的前缀,譬如 arm-pokylinux-gnueabi-gcc 前缀就是 arm-poky-linux-gnueabi;–prefix 选项则用于指定库文件的安装路径,后面写自己设置的路径
在这里插入图片描述
接着执行

make
make install

在这里插入图片描述

至此交叉编译完成,可以在安装目录下看到生成的文件夹。
移植的最后一步就是把 tslib 安装目录下的库文件、etc 下的配置文件以及编译得到的测试工具拷贝到开发板 Linux 系统目录下,由于开发板出厂系统中已经移植了 tslib 库,所以我们这里就不用拷贝了。如果是自己做的根文件系统并没有移植 tslib,那么就需要把这些库、可执行文件以及配置文件拷贝到根文件系统中,大致步骤如下:

  • 将安装目录 bin/目录下的所有可执行文件拷贝到开发板/usr/bin 目录下;
  • 将安装目录 etc/目录下的配置文件 ts.conf 拷贝到开发板/etc 目录下;
  • 将安装目录 lib/目录下的所有库文件拷贝到开发板/usr/lib 目录下。

四、基于tslib写单点触摸屏应用程序

使用 tslib 提供的 API 接口来编写触摸屏应用程序,使用 tslib 库函数需要在我们的应用程序中包含 tslib 的头文件 tslib.h。

#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);
}

可以看出上述步骤:

  • 打开触摸屏设备:struct tsdev *ts_setup(const char *dev_name, int nonblock),参数 dev_name 指定触摸屏的设备节点,参数 nonblock 表示是否以非阻塞方式打开触摸屏设备。
  • 配置触摸屏设备:int ts_config(struct tsdev *ts),解析 ts.conf 文件中的配置信息,加载相应的插件。
  • 读取触摸屏数据:int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr),ts_read 用于读取单点触摸数据
    代码中ts_setup函数的dev_name参数为null,函数内部会读取TSLIB_TSDEVICE 环境变量,获取该环境变量的内容以得知触摸屏的设备节点。
    在这里插入图片描述
    ts_read()函数的 samp 参数是一个 struct ts_sample *类型的指针,指向一个 struct ts_sample 对象,struct ts_sample 数据结构描述了触摸点的信息。
    编译应用程序:
${CC} -I /home/jack/linux/tslib/tools/tslib/include -L /home/jack/linux/tslib/tools/tslib/lib -lts -o ts_single_touch tslib_touch.c

-I 指定tslib库的头文件路径
-L 指定tslib库路径
-l 指定链接库,也就是 libts.so 库文件
在这里插入图片描述
结果如下:
在这里插入图片描述

五、基于tslib写多点触摸屏应用程序

使用 ts_read_mt()函数读取多点触摸数据

#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);
}

结果如下:
在这里插入图片描述

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

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

相关文章

2023-2024-2Java面向对象程序设计-阶段性测试2

填空题&#xff08;总分&#xff1a;10.00&#xff09; 1、Java程序中使用【 import 】关键字导入外部的包。 2、使用【 final 】关键字声明的类不能有子类。 4、JVM是【 Java Virtual Machine 】的英文简写。 5、面向对象编程思想的三个特性是【封装】、【继承】、【多态】。 …

数据分析师的职业规划与参考资料

数据分析师如何规划 参考&#xff1a;超详细的数据分析职业规划 一个产品的出现可以从业务和技术两个方向分析&#xff0c;业务需求技术支持产品的出现。 如果把职业也当成一个产品&#xff0c;也有类似的分析&#xff0c; 其中业务也就是领域&#xff0c;即这个业务领域的特点…

Power BI案例-医院数据集的仪表盘制作

数据集描述 医生数据集doctor 医生编号是唯一的&#xff0c;名称会存在重复 医疗项目数据projects 病例编号是唯一的&#xff0c;注意这个日期编号不是真正的日期。 日期数据date 这里的日期编号对应医疗项目数据中的日期编号 科室数据集Department 维度表 采购成本事实表…

知乎上高频提问:Redis到底是单线程还是多线程程序?

1.概述 这里我们先给出问题的全面回答&#xff1a;Redis到底是多线程还是单线程程序要看是针对哪个功能而言&#xff0c;对于核心业务功能部分(命令操作处理数据)&#xff0c;Redis是单线程的&#xff0c;主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的&#xff…

海康rtsp拉流,rtmp推流,nginx部署转flv集成

海康rtsp拉流&#xff0c;rtmp推流&#xff0c;nginx部署转flv集成 项目实际使用并测试经正式使用无问题&#xff0c;有问题欢迎评论留言 核心后台java代码&#xff1a; try {// FFmpeg命令String command "ffmpeg -re -i my_video.mp4 -c copy -f flv rtmp://localho…

[学习笔记]批量迁移数据库文件

拷贝数据库文件 首先在本地运行如下SQL语句&#xff0c;查看数据库文件的磁盘位置 SELECT name, physical_name AS CurrentLocation, state_desc FROM sys.master_files默认是保存在C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA目录下 首先复制数据…

Ansible常用模块详解(附各模块应用实例和Ansible环境安装部署)

目录 一、ansible概述 1、简介 2、Ansible主要功能&#xff1a; 3、Ansible的另一个特点&#xff1a;所有模块都是幂等性 4、Ansible的优点&#xff1a; 5、Ansible的四大组件&#xff1a; 二、ansible环境部署&#xff1a; 1、环境&#xff1a; 2、安装ansible&#…

浅析RoPE旋转位置编码的远程衰减特性

为什么 θ i \theta_i θi​的取值会造成远程衰减性 旋转位置编码的出发点为&#xff1a;通过绝对位置编码的方式实现相对位置编码。 对词向量 q \boldsymbol{q} q添加绝对位置信息 m m m&#xff0c;希望找到一种函数 f f f&#xff0c;使得&#xff1a; < f ( q , m ) …

MySQL数据库——SQL语法

Structured Query Language&#xff08;结构化查询语言&#xff09;&#xff0c;简称SQL&#xff0c;是用于操作关系型数据库的标准编程语言。SQL提供了一种与数据库交互的方式&#xff0c;可以用于查询、插入、更新和删除数据库中的数据。 1. SQL通用语法 SQL语句可以写在一…

持续集成交付CICD:K8S 手动完成前端项目应用发布与回滚

目录 一、实验 1.环境 2.Harbor查看镜像与连接K8S节点 3.K8S集群部署 nginx-ingress-controller 4. Jenkins 通过GitLab共享库 实现前端项目镜像构建 5.K8S node节点拉取镜像 6.K8S master节点更新部署文件 7.前端项目应用回滚 一、实验 1.环境 &#xff08;1&#x…

Android 架构 - 组件化

一、概念 组件化是对单个功能进行开发&#xff0c;使得功能可以复用。将多个功能组合起来就是一个业务模块&#xff0c;因此去除了模块间的耦合&#xff0c;使得按业务划分的模块成了可单独运行的业务组件。&#xff08;一定程度上的独立&#xff0c;还是依附于整个项目中&…

EXCEL VLOOKUP函数

参考资料 Excel&#xff1a;史上最全的VLOOKUP应用教程VLOOKUP函数最全面最详细的讲解大全&#xff0c;涵盖17个重要和常见用法&#xff01; 目录 零. 前提条件一. 单条件查找1.1 顺向查找1.2 逆向查找 二. 多条件查找2.1 顺向查找2.2 逆向查找 三. 根据条件查询等级四. 交差查…

RHCE8 资料整理(十一)

RHCE8 资料整理 第 32 章 控制语句32.1 判断语句 when32.1.1 when 判断中>、<、!和的使用32.1.2 when 判断中 in的用法32.1.3 when 判断中 is的用法 32.2 判断语句 block-rescue32.3 循环语句 第 32 章 控制语句 一个play中可以包含多个task&#xff0c;如果不想所有的t…

DriveWorks Solo捕获参数(三)

捕获参数 - 木门和矩形窗 木质门 下一个组件是木门本身。除了尺寸之外&#xff0c;门还具有需要控制的功能。 让我们首先捕获尺寸。 通过单击“捕获资源管理器”中的标题来激活“捕获的模型”部分。 双击任务窗格树中的模型木门以在 SOLIDWORKS 中将其打开。捕获以下尺寸。…

多维时序 | MATLAB实现WOA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测

多维时序 | MATLAB实现WOA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现WOA-CNN-LSTM-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 MATLAB实现WOA-CNN-LST…

零基础也能制作家装预约咨询小程序

近年来&#xff0c;随着互联网的快速发展&#xff0c;越来越多的消费者倾向于使用手机进行购物和咨询。然而&#xff0c;许多家装实体店却发现自己的客流量越来越少&#xff0c;急需一种新的方式来吸引顾客。而开发家装预约咨询小程序则成为了一种利用互联网技术来解决这一问题…

【设计模式--结构型--适配器模式】

设计模式--结构型--适配器模式 适配器模式概述结构案例类适配器模式对象适配器模式 应用场景 适配器模式 概述 将一个类的接口转换成客户希望的另一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的那些类能一起工作。 适配器模式分为类适配器模式和对象适配器模式…

Java解决不同路径问题2

Java解决不同路径问题2 01题目 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中…

RUST与RUSTful简介

RUST与RUSTful 1、背景2、RUST的起源3、RUST与RUSTful4、总结 1、背景 随着互联网&#xff08;Internet&#xff09;的发展&#xff0c;越来越多的人开始意识到&#xff0c;网站即软件&#xff0c;而且是一种新型的软件。这种"互联网软件"采用客户端/服务器&#xff…

服务器数据恢复-raid5故障导致上层分区无法访问的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台服务器上3块硬盘组建了一组raid5磁盘阵列。服务器运行过程中有一块硬盘的指示灯变为红色&#xff0c;raid5磁盘阵列出现故障&#xff0c;服务器上层操作系统的分区无法识别。 服务器数据恢复过程&#xff1a; 1、将故障服务器上磁…