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

news2024/11/15 8:35:53

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) {//按压力>0
            if (pressure)   //若上一次的按压力>0
                printf("移动(%d, %d)\n", samp.x, samp.y);
            else
                printf("按下(%d, %d)\n", samp.x, samp.y);
        }
        else
            printf("松开\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) { //如果按压力>0
                    if (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);
                    else
                        printf("slot<%d>, 按下(%d, %d)\n", mt_ptr[i].slot, mt_ptr[i].x, mt_ptr[i].y);
                }
                else
                    printf("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.coloradmin.cn/o/1942753.html

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

相关文章

工具(linux)

Yum 软件包管理器 介绍 yum Yum 是一个在 Red Hat 和 CentOS 等 Linux 发行版中常用的软件包管理器&#xff0c;它可以方便地进行软件包的安装、更新和删除。 安装软件包 使用 yum install 命令可以安装指定的软件包&#xff0c;例如&#xff1a; yum install package_nam…

《程序猿入职必会(2) · 搭建具备前端展示效果的 Vue》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

华为OD2024D卷机试题汇总,含D量50%+,按算法分类刷题,事半功倍

目录 专栏导读华为OD机试算法题太多了&#xff0c;知识点繁杂&#xff0c;如何刷题更有效率呢&#xff1f; 一、逻辑分析二、数据结构1、线性表① 数组② 双指针 2、map与list3、队列4、链表5、栈6、滑动窗口7、二叉树8、并查集9、矩阵 三、算法1、基础算法① 贪心思维② 二分查…

Graph Guided Transformer论文精读

摘要 抛出问题&#xff1a;基于深度学习的框架在将平衡局部空间结构信息的时候对于区域信息的特征建模能力会下降&#xff01; 紧接着提出一个GT&#xff08;Graph–guided transformer&#xff09;模型&#xff0c;整个网络的框架为&#xff1a;首先使用卷积块获取像素级别的…

开源项目:推动经济与科技发展的新引擎

文章目录 每日一句正能量前言开源项目的发展趋势开源项目的发展趋势开源社区的活跃度开源项目在技术创新中的作用结论 参与开源的经验分享如何选择开源项目如何贡献代码如何与开源社区合作个人品牌与职业发展贡献与成就感 开源项目的挑战维护难度版权问题社区管理技术债务安全问…

理解进程status的二进制位表示及进程等待(是什么,为什么,怎么办)

信号编号&#xff1a;低7位 状态编号&#xff1a;次低8位 1.子进程退出后会变为僵尸进程&#xff0c;将退出结果写入自身的task_struct结构体中 2.wait/waitpid是一个系统调用->OS可以读取子进程的task_struct 1.为什么要进行进程等待&#xff1f; 1.将子进程&#xff…

Vatee万腾平台:智慧金融的创新引擎,驱动金融服务升级

在数字化浪潮席卷全球的今天&#xff0c;金融行业正经历着前所未有的变革与升级。Vatee万腾平台&#xff0c;作为智慧金融领域的创新先锋&#xff0c;正以其独特的技术优势、前瞻的战略布局和卓越的服务能力&#xff0c;成为推动金融服务升级的重要引擎。 智慧金融&#xff1a;…

上海联联充电互联互通充电系统嘎嘎快充云快充旭电通池续特来电等等免费对接

1、定时将我方订单信息推送到联联监管 2、实现联联充电Pro使用我方设备充电 3、使用我方小程序开启快电、特来电、星星充电、新电途、石化养车等等

资源调度的艺术:大规模爬虫管理的优化策略

摘要 本文深入探讨了在处理大规模数据抓取项目时&#xff0c;如何通过优化资源调度策略来提升爬虫管理的效率与稳定性。从技术选型到策略实施&#xff0c;揭示了优化的核心技巧&#xff0c;助力企业与开发者高效驾驭大数据采集的挑战。 正文 在互联网信息爆炸的时代&#xf…

iOS ------ weak的基本原理

1.weak的基本概念 weak弱引用&#xff0c;所引用的对象的引用计数不会加一&#xff0c;引用对象被释放的时候会自动设置为nil多用于解决对象间的相互引用造成内存泄露的循环引用的问题 2.实现原理 Person *object [[Person alloc] init]; id __weak objc object;Runtime维…

《程序猿学会 Vue · 基础与实战篇》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

Linux环境下MongoDB安装与主从集群,高可用集群配置教程

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…

VMware 安装完,设备管理器中没有虚拟网卡(vmnet0、wmnet1、vmnet8) / 虚拟网络编辑器中没有桥接模式

问题&#xff1a;VMware 安装完&#xff0c;设备管理器中没有虚拟网卡(vmnet0、wmnet1、vmnet8) / 虚拟网络编辑器中没有桥接模式 1、确认 Device Install Service 和 Device Setup Manager 没有被禁用 Device Install Service 和 Device Setup Manager是 Windows 操作系统中…

C# 2.数组

1.定义整形数组&#xff0c;指定数组长度 string[] s1 new string[3]; byte[] bs new byte[3]; 数组的索引值从0开始&#xff0c;3个元素索引值为0&#xff0c;1,2…… 2.添加元素&#xff1a;数组【索引值】值 i1[0] 3;// 给索引值位0位置添加一个3 3 i1[0] 取出指定位置的…

【LeetCode:3098. 求出所有子序列的能量和 + 记忆化缓存】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

JUC-synchorized与锁原理、锁的升级与膨胀

syn-ed 是一个可重入、不公平的重量级锁&#xff1b;synchronized使用对象锁保证了临界区代码的原子性&#xff0c;无论使用synchorized锁的是代码块还是方法&#xff0c;其本质都是锁住一个对象。 同步代码块&#xff0c;锁住的是括号里的对象同步方法 普通方法&#xff0c;…

手写文件系统一条龙篇

哈喽&#xff0c;我是子牙老师。这篇文章聊聊文件系统是怎么写出来的&#xff0c;看完&#xff0c;你就可以自己去写文件系统了。本文以Linux的EXT系列文件系统为例进行讲解&#xff0c;理解了&#xff0c;其他的文件系统你就可以自行研究了&#xff0c;差不多的东西 理解了本…

第二证券:市场估值依然处于较低区域

结合风格板块、一级工作预喜情况与工作中预喜崎岖较大的企业体现看&#xff0c;估量2024年上半年中下游工作获利改善势头向好。其中&#xff0c;获益于客运量的上升&#xff0c;交通运输工作中大型蓝筹公司盈余才干改善。TMT领域中电子及通讯工作成果上升崎岖较大&#xff0c;工…

微服务分布式事务

1、分布式事务是什么&#xff1f; 微服务架构中的分布式事务是指在多个服务实例之间保持数据一致性的机制。由于微服务通常涉及将业务逻辑拆分成独立的服务&#xff0c;每个服务可能有自己的数据库&#xff0c;因此当一个业务操作需要跨多个服务进行时&#xff0c;确保所有服务…

小白速通 Spring 之 Annotation 篇

Annotation 注解 Service public class MessageServiceImpl implements MessageService{public String getMessage() {return "Hello World!";}} 本质上来说 Annotation(注解)是 Java 推出的一种注释机制,后面我们统一叫 Annotation&#xff0c;和普通的注释有个显…