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_API
            ts = ts_open("/dev/input/event0", 0);
        #else
            ts = 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 目录,里面存放了一些简单的演示代码

  • 15
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

码农小白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值