本文主要是介绍linux学习:输入设备+tslib库控制触控屏应用接口,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
动作记录结构体
例子 从触摸屏设备节点/dev/event0 中读取数据,并显示当前触摸 屏的实时原始数据
TSLIB 库详解
安装步骤
配置
连接操作系统的输入设备,可不止一种,也许是一个标准 PS/2 键盘,也许是一个 USB 鼠标,或者是一块触摸屏,甚至是一个游戏机摇杆,Linux 在处理这些纷繁各异的输入设备的时候,采用的办法还是找中间层来屏蔽各种细节
在 Linux 的内核中,对输入设备的使用,实际上运用了 3 大块来管理,他们分别是所 谓的输入设备驱动层、输入子系统核心层,以及事件触发层
- 1,输入设备驱动层:
- 每一种设备都有其特定的驱动程序,他们被妥当地装载到操作系统的设备模型框架内, 封装硬件所提供的功能,向上提供规定的接口。
- 2,核心层:
- 此处将收集由设备驱动层发来的数据,整合之后触发某一事件。
- 3,事件触发层:
- 可以通过在用户空间读取相应设备的节点文件来获知某 设备的某一个动作。在最靠近应用程序的事件触发层上,内核所获知的各类输入事件,比如 键盘被按了一下,触摸屏被滑了一下等,都将被统一封装在一个叫做 input_even 的结构体当中,这个结构体定义如下:(/usr/inlucde/linux/input.h)
动作记录结构体
struct input_event {struct timeval time;__u16 type;__u16 code;__s32 value;
}
- time:输入事件发生的时间戳,精确到微秒。时间结构体定义如下
struct timeval { __time_t tv_sec; // 秒long int tv_usec; // 微秒 };
- type:输入事件的类型
- EV_SYN:事件间的分割标志,有些事件可能会在时间和空间上产生延续,比如持 续按住一个按键。为了更好地管理这些持续的事件,EV_SYN 用以将他们分割成一个 个的小的数据包。
- EV_KEY:用以描述键盘,按键或者类似键盘的设备的状态变化。
- EV_REL:相对位移,比如鼠标的移动,滚轮的转动等。
- EV_ABS:绝对位移,比如触摸屏上的坐标值。
- EV_MSC:不能匹配现有的类型,这相当于当前暂不识别的事件。比如在 Linux 系统中按下键盘中针对 Windows 系统的“一键杀毒”按键,将会产生该事件。
- EV_LED:用于控制设备上的 LED 灯的开关,比如按下键盘的大写锁定键,会同 时产生 ”EV_KEY” 和 ”EV_LED” 两个事件。
- code:这个“事件的代码”用于对事件的类型作进一步的描述。比如:当发生 EV_KEY 事件时,则可能是键盘被按下了,那么究竟是哪个按键被按下了呢?此时查看 code 就知道 了。当发生 EV_REL 事件时,也许是鼠标动了,也许是滚轮动了。这时可以用 code 的值 来加以区分
- value:当 code 都不足以区分事件的性质的时候,可以用 value 来确认。比如由 EV_REL 和 REL_WHEEL 确认发生了鼠标滚轮的动作,但是究竟是向上滚还是向下滚呢? 再比如由由 EV_KEY 和 KEY_F 确认了发生键盘上 F 键的动作,但究竟是按下呢还是弹起 呢?这时都可以用 value 值来进一步判断
例子 从触摸屏设备节点/dev/event0 中读取数据,并显示当前触摸 屏的实时原始数据
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdbool.h>
4 #include <unistd.h>
5 #include <string.h>
6 #include <strings.h>
7 #include <errno.h>
8
9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include <fcntl.h>
12 #include <Linux/input.h>
13
14 int main(int argc, char **argv)
15 {
16 int ts = open("/dev/event0", O_RDONLY);
17
18 struct input_event buf;
19 bzero(&buf, sizeof(buf));
20
21 while(1)
22 {
23 read(ts, &buf, sizeof(buf));
24
25 switch(buf.type)
26 {
27 case EV_SYN:
28 printf("--------------------- SYN ------------------\n");
29 break;
30 case EV_ABS:
31 printf("time: %u.%u\ttype: EV_ABS\t",
32 buf.time.tv_sec, buf.time.tv_usec);
33 switch(buf.code)
34 {
35 case ABS_X:
36 printf("X:%u\n", buf.value);
37 break;
38 case ABS_Y:
39 printf("Y:%u\n", buf.value);
40 break;
41 case ABS_PRESSURE:
42 printf("pressure:%u\n", buf.value);
43 }
44 }
45 }
46 return 0;
47 }
以上代码打印出来的是直接从触摸屏读取的原始数据(raw data),没有经过 任何校正,也没有任何滤波、去抖、消噪,因此这些数据是不能直接给应用层程序使用的, 但是不用担心,这些繁琐复杂的工作已经有了很成熟的库支持了,下一小节即将要介绍的 TSLIB 库,就是这样一个开源的、能为触摸屏获得的原始数据提供诸如滤波、去抖、消噪 和校正功能的库,TSLIB 作为触摸屏驱动的适配层,为上层的应用提供了一个统一的编程 接口,将使得我们编写基于触摸屏的应用更加简便
TSLIB 库详解
安装步骤
要使用 TSLIB 库,先下载它,网址是:GitHub - libts/tslib: Touchscreen access library
打开这个网页之后,点击右边的“Download ZIP”按钮,选择保存路径即可。然后解压
安装工具
- sudo apt-get install automake
- sudo apt-get install libt
在主目录底下运行./autogen.sh,会生成一个configure文件
输入 echo "ac_cv_func_malloc_0_nonnull=yes"> arm-Linux.cache
echo 语句是为了避免编译时找不到 ac_cv_func_malloc_0_nonnul
输入 ./configure --host=arm-Linux --cache-file=arm-Linux.cache --prefix=/usr/local/tslib
执行./configure 命令时,各参数含义如下:
- --host 指明当前系统所使用的交叉编译工具的前缀,根据具体情况而变。
- --cache-file 指明运行 configure 脚本时的缓存文件。
- --prefix 指明 TSLIB 的安装路径,根据具体情况而变
在运行make,sudo make install,就可以在刚刚--prefix所指定的目录下出现tslib文件了
将所有文件拷贝到开发板中,修改tslib/etc/ts.conf,取消“# module_raw input”注释
修改/etc/profile,在末尾添加
export TSLIB_ROOT=/tslib/lib
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_CONFFILE=/tslib/etc/ts.conf
export TSLIB_PLUGINDIR=/tslib/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_CALIBFILE=/tslib/calibration
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/tslib/lib
- TSLIB_ROOT 指明 TSLIB 库在开发板中的具体位置,要以实际情况为准。
- TSLIB_TSDEVICE 指明开发板触摸屏的设备节点文件名称。
- TSLIB_FBDEVICE 指明开发板 LCD 的设备节点文件名称。
- TSLIB_CONFFILE 指明 TSLIB 库的配置文件的具体位置,要以实际情况为准。
- TSLIB_PLUGINDIR 指明 TSLIB 库的插件模块的具体位置,要以实际情况为准。
- TSLIB_CONSOLEDEVICE 指明终端名称,none 意为让系统自动匹配。
- TSLIB_CALIBFILE 指明校正文件的位置,该文件在执行 ts_calibrate 之后自动生成。
- LD_LIBRARY_PATH 是开发板系统的动态库链接路径
运行tslib/bin/ts_print例子,点击触摸屏就可以打印触碰的xy坐标,下面是测试代码
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/time.h>#include "tslib.h" 21
int main(void)
{struct tsdev *ts;char *tsdevice = NULL;// 以非阻塞方式获取触摸屏设备文件描述符if((tsdevice=getenv("TSLIB_TSDEVICE")) != NULL){ts = ts_open(tsdevice, 0);}else{#ifdef USE_INPUT_APIts = ts_open("/dev/input/event0", 0);#elsets = ts_open("/dev/touchscreen/ucb1x00", 0);#endif}if(!ts){perror("ts_open");exit(1);}if(ts_config(ts)) // 根据配置文件加载相应的插件模块{perror("ts_config");exit(1);}while(1){struct ts_sample samp; // 储存触摸屏 X/Y 轴坐标和压力值int ret;ret = ts_read(ts, &samp, 1); // 读取一个触摸屏数据分包if (ret < 0){perror("ts_read");exit(1);}if (ret != 1)continue;printf("%ld.%06ld: %6d %6d %6d\n", 68 samp.tv.tv_sec, // 秒samp.tv.tv_usec, // 微秒samp.x, // X 轴坐标samp.y, // Y 轴坐标samp.pressure); // 压力值}return 0;
}
配置
在etc/ts.conf中可以选择要用的模块
- module_raw input
- 提供模块数据,必须开启的
- module variance delta=30
- 消除电磁噪音
- module dejitter delta=100
- 去抖
- module linear
- 校正
plugins 目录就是 TSLIB 支持的插件源码所在地,编译之后,这些插件库会以隐藏文 件的方式统一存放在 plugins/.libs 里面。src 无疑是最重要的目录了,里面存放的就是 TSLIB 的核心源代码,包括获取触摸屏文件描述符,加载插件模块,参数解析,读取配置文件信息等等。最后还有一个 tests 目录,里面存放了一些简单的演示代码
这篇关于linux学习:输入设备+tslib库控制触控屏应用接口的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!