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) {//按压力>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,输出“移动”信息

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

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

        • 更新压力值

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

  • 验证

    • 多点触摸应用程序测试结果
  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木木不迷茫(˵¯͒¯͒˵)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值