LV17-01-输入类设备-05-触摸屏tslib开源库-01-简介与移植

本文主要是输入类设备控制——触摸屏tslib开源库的简介与移植的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
PC端开发环境 Windows Windows11
Ubuntu Ubuntu20.04.2的64位版本
VMware® Workstation 17 Pro 17.6.0 build-24238078
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
Win32DiskImager Win32DiskImager v1.0
Linux开发板环境 Linux开发板 正点原子 i.MX6ULL Linux 阿尔法开发板
uboot NXP官方提供的uboot,NXP提供的版本为uboot-imx-rel_imx_4.1.15_2.1.0_ga(使用的uboot版本为U-Boot 2016.03)
linux内核 linux-4.15(NXP官方提供)
点击查看本文参考资料
分类 网址 说明
官方网站 https://www.arm.com/ ARM官方网站,在这里我们可以找到Cotex-Mx以及ARMVx的一些文档
https://www.nxp.com.cn/ NXP官方网站
https://www.nxpic.org.cn/NXP 官方社区
https://u-boot.readthedocs.io/en/latest/u-boot官网
https://www.kernel.org/linux内核官网
其他网站 kernel - Linux source code (v4.15) - Bootlin linux内核源码在线查看
点击查看相关文件下载
分类 网址 说明
NXP https://github.com/nxp-imx NXP imx开发资源GitHub组织,里边会有u-boot和linux内核的仓库
https://elixir.bootlin.com/linux/latest/source 在线阅读linux kernel源码
nxp-imx/linux-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP linux内核仓库tags中的rel_imx_4.1.15_2.1.0_ga
nxp-imx/uboot-imx/releases/tag/rel_imx_4.1.15_2.1.0_ga NXP u-boot仓库tags中的rel_imx_4.1.15_2.1.0_ga
I.MX6ULL i.MX 6ULL Applications Processors for Industrial Products I.MX6ULL 芯片手册(datasheet,可以在线查看)
i.MX 6ULL Applications ProcessorReference Manual I.MX6ULL 参考手册(下载后才能查看,需要登录NXP官网)

一、tslib 是什么

image-20240922134849466

官网在这里:tslib,打开后就是上面的图片:

image-20240922134918836

tslib 是专门为触摸屏设备所开发的 Linux 应用层函数库,并且是开源,也就意味着我们可以直接获取到
tslib 的源代码 。

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

tslib 从触摸屏中获得原始的坐标数据, 并通过一系列的去噪、去抖、坐标变换等操作,来去除噪声并将
原始的触摸屏坐标转换为相应的屏幕坐标。

tslib 有一个配置文件 ts.conf, 该配置文件中提供了一些配置参数、用户可以对其进行修改 ,后面会详细进行学习。

tslib 可以作为 Qt 的触摸屏输入插件,为 Qt 提供触摸输入支持, 如果在嵌入式 Linux 硬件平台下开发过Qt 应用程序的话应该知道;当然,并不是只有 tslib 才能作为 Qt 的插件、为其提供触摸输入支持,还有很多插件都可以,只不过大部分都会选择使用 tslib。

二、tslib 移植

1. 下载源码

首先下载 tslib 源码包,进入到 tslib 的 git 仓库下载源码 :Releases · libts/tslib (github.com)

image-20240922135305189

ALPHA 开发板出厂系统中已经移植了 tslib,并且版本为 1.16,可以在开发板执行 ts_finddev 命令查看到它的版本信息,如下所示:

image-20240922212505883

所以为了统一,我们也下载 1.16 版本的 tslib,往下翻找到 1.16 版本的下载链接:

image-20240922135427001

我们点击 Release tslib 1.16 · libts/tslib (github.com) 进去:

image-20240922135643223

下载 tar.bz2 或 tar.gz 格式压缩包,或者 tar.xz 压缩包,这里我下载 tar.gz 格式的压缩包文件,点
击文字即可下载。下载好后我们解压一下:

image-20240922142701069

解压后有上图这些文件。

2. 编译源码

  • (1)创建安装目录

我们创建一个out目录作为编译成果物存放的位置:

1
2
cd ~/8linux_lib/tslib-1.16/
mkdir out
image-20240922143031420
  • (2)配置工程
1
./configure --host=arm-linux-gnueabihf --prefix=/home/sumu/8linux_lib/tslib-1.16/out

至于工程是如何配置的,可以执行./configure –help 查看它的配置选项以及含义。

–host 选项用于指定交叉编译得到的库文件是运行在哪个平台,通常将–host 设置为交叉编译器名称的前缀,如 arm-linux-gnueabihf-gcc 前缀就是 arm-linux-gnueabihf;

–prefix 选项则用于指定库文件的安装路径,我们将安装路径设置为之前创建的/home/sumu/8linux_lib/tslib-1.16/out 目录。

配置完成后如下图所示:

image-20240922143858249
  • (3)编译工程
1
make

编译完毕之后如下图所示:

image-20240922144233300
  • (4)安装
1
make install

安装完毕之后如下所示:

image-20240922144409400

这样out目录下就是我们的成果物了。

3. 移植到开发板

移植的最后一步就是把 tslib 安装目录下的库文件、 etc 下的配置文件以及编译得到的测试工具拷贝到开发板 Linux 系统目录下。

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

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

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

将安装目录下的测试工具、库文件以及配置文件拷贝到开发板之后,接着需要配置一些环境变量,因为
tslib 工作的时候它需要依赖于一些环境变量,例如它会通过读取环境变量来得知 ts.conf 配置文件、库文件
的路径以及我们要测试的触摸屏对应的设备节点等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# TSLIB_CONSOLEDEVICE 用于配置控制台设备文件名,直接配置为 none 即可
export TSLIB_CONSOLEDEVICE=none

# TSLIB_FBDEVICE 用于配置显示设备的名称, tslib 提供了手指触摸画线的测试工具,需要在 LCD 上显示,所以这里需要指定一个显示设备的设备节点。
export TSLIB_FBDEVICE=/dev/fb0

# TSLIB_TSDEVICE 用于配置触摸屏对应的设备节点,根据实际情况配置。
export TSLIB_TSDEVICE=/dev/input/event1

# TSLIB_CONFFILE 用于配置 ts.conf 文件的所在路径。
export TSLIB_CONFFILE=/etc/ts.conf

# TSLIB_PLUGINDIR用于配置插件所在路径。
export TSLIB_PLUGINDIR=/usr/lib/ts

如果想每次启动系统都能生效,可以把这些命令放置在/etc/profile 脚本中执行;出厂系统中已经配置好
了,无需进行配置。

三、编译输出目录简介

我们前面编译安装后,输出目录有以下文件:

image-20240922145037170

二级目录有以下文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
sumu@sumu-virtual-machine:~/8linux_lib/tslib-1.16/out$ tree -L 2
.
├── bin
│   ├── ts_calibrate
│   ├── ts_finddev
│   ├── ts_harvest
│   ├── ts_print
│   ├── ts_print_mt
│   ├── ts_print_raw
│   ├── ts_test
│   ├── ts_test_mt
│   ├── ts_uinput
│   └── ts_verify
├── etc
│   └── ts.conf
├── include
│   └── tslib.h
├── lib
│   ├── libts.la
│   ├── libts.so -> libts.so.0.9.1
│   ├── libts.so.0 -> libts.so.0.9.1
│   ├── libts.so.0.9.1
│   ├── pkgconfig
│   └── ts
└── share
  └── man

8 directories, 16 files

1. bin

bin 目录下有一些 tslib 提供的小工具,可以用于测试触摸屏,如下所示:

image-20240922145133361

这些测试工具的源码实现,可以在 tslib 源码中找到,具体路径为 tslib 源码目录下的 tests 文件夹中:

image-20240922152223567

2. etc

etc 目录下有一个配置文件 ts.conf :

image-20240922145329398

我们打开 ts.conf 文件看看它有哪些配置选项

image-20240922145612853

module_raw input:取消注释,使能支持 input 输入事件;

module pthres pmin=1:如果我们的设备支持按压力大小测试,那么可以把它的注释取消, pmin 用于调节按压力灵敏度,默认就是等于 1。

module dejitter delta=100: tslib 提供了触摸屏去噪算法插件,如果需要过滤噪声样本, 取消注释,默认参数 delta=100。

module linear: tslib 提供了触摸屏坐标变换的功能,如将 X、 Y 坐标互换、坐标旋转等之类,如果我们需要实现坐标变换,可以把注释去掉。

3. include

include 目录下只有一个头文件 tslib.h,该头文件中包含了一些结构体数据结构以及 API 接口的申明,
使用 tslib 提供的 API 就需要包含该头文件。

image-20240922145753985

4. lib

lib 目录下包含了编译 tslib 源码所得到的库文件,默认这些都是动态库文件,也可以通过配置 tslib 工程
使其生成静态库文件。lib/ts 目录下存放的是一些插件库。

image-20240922145859293

5. share

image-20240922150034235

没去了解,可以忽略。

四、tslib 框架分析

tslib 的主要代码如图 :

image-20241020110116880

核心在于“plugins”目录里的“插件”,或称为“ module”。这个目录下的每个文件都是一个 module,每个 module 都提供 2 个函数: read、 read_mt,前者用于读取单点触摸屏的数据,后者用于读取多点触摸屏的数据。

要分析 tslib 的框架,先看看示例程序怎么使用,我们参考 ts_test.c 和ts_test_mt.c,前者用于一般触摸屏(比如电阻屏、单点电容屏),后者用于多点触摸屏。

image-20241020111817124

调用 ts_open 后,可以打开某个设备节点,构造出一个 tsdev 结构体。然后调用 ts_config 读取配置文件的处理,假设/etc/ts.conf 内容如下:

1
2
3
4
module_raw input
module pthres pmin=1
module dejitter delta=100
module linear

每行表示一个“ module”或“ moduel_raw”。对于所有的“module”,都会插入 tsdev.list 链表头,也就是 tsdev.list执行配置文件中最后一个“ module”,配置文件中第一个“ module”位于链表的尾部。

对于所有的“ module_raw”,都会插入 tsdev.list_raw 链表头,一般只有一个“ module_raw”。

注意: tsdev.list 中最后一个“ module”会指向 ts_dev.list_raw 的头部。无论是调用 ts_read 还是 ts_read_mt,都是通过 tsdev.list 中的模块来处理数据的。这写模块是递归调用的,比如 linear 模块的 read 函数如图 :

image-20241020112027351

linear 模块的 read_raw 函数如图 :

image-20241020112137099

因为是递归调用,所有最先使用 input 模块读取设备节点得到原始数据,再依次经过 pthres 模块、 dejitter 模块、 linear 模块处理后,才返回最终数据。