I.MX6ULL之使用tslib实现触摸屏的应用

I.MX6ULL之使用tslib实现触摸屏的应用

本文章所用到的代码可以到Gitee下载。

tslibtslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能。

首先,需要下载tslib的官方源码:http://www.tslib.org/,然后进行交叉编译,使用tslib提供的例程测试一下,命令如下:

##确定自己的编译工具链
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin

##使用配置命令,运行在arm机器,库文件安装目录为当前目录
## --host 选项用于指定交叉编译得到的库文件是运行在哪个平台
##--prefix 选项则用于指定库文件的安装路径
./configure --host=arm-buildroot-linux-gnueabihf  --prefix=/

make
##安装的同时指定tslib库中的环境变量路径
make install DESTDIR=$PWD/tmp

##把include目录下的文件和lib目录下的文件都复制到系统自带的目录中
##把lib目录下的文件,bin目录下的所有文件。etc目录下的ts.conf文件都复制到开发板上
cp  /mnt/tslib-1.21/tmp/lib/*so*  -d     ~/nfs_roots
cp  /mnt/tslib-1.21/tmp/bin/*            ~/nfs_roots
cp  /mnt/tslib-1.21/tmp/etc/ts.conf  -d  ~/nfs_roots

#这里真的盲目了很久,然后想着只要一点点找的话应该会找到,结果真就找到了
#关闭默认的qt gui-->去到相应目录下查找自己的hmi文件
mv  /etc/init.d/S99myirhmi2 /root
reboot

#恢复gui
mv S99myirhmi2 /etc/init.d/
reboot

##执行tslib的测试程序试一下
ts_test_mt

在这里插入图片描述

tslib实现测试程序:
首先看一下tslib的一些结构体:
包含了文件描述符,以及两个指向module(plug)结构体指针,主要提供给ts_setup()函数使用,来打开文件以及加载预先配置的环境变量。
在这里插入图片描述 通过链表来指向下一个module。
在这里插入图片描述通过read()函数来读取到的数据结构,本实验用到的有x,y,id,valid(如果读取到的数据有更新则为1).
tslib示例演示:
在这里插入图片描述

代码实现:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <getopt.h>
#include <linux/input.h>
#include <sys/ioctl.h>
#include <tslib.h>

/* 实现距离的测量,实际返回的是x距离的平方加上y距离的平方 */
int distance(struct ts_sample_mt *point1,struct ts_sample_mt *point2)
{
    /* 算出x,y轴的差值 */
    int x = point1->x - point2->x;
    int y = point1->y - point2->y;

    return x*x+y*y;
}


int main(int argc,char **argv)
{
    struct tsdev *ts;   /* 声明一个结构体变量,用来保存文件描述符 以及指向module结构的指针 */
    struct input_absinfo slot;  /* 输入信息 */
    struct ts_sample_mt **samp_mt = NULL;
    struct ts_sample_mt **prev_samp_mt = NULL;/* 上次的和本次的 */
    int i;      /* 用作循环 */
    int ret;    /* 用作接收返回数据 */
    int touch_cnt;  /* 统计触点,只需要两个 */
    int point_pressed[20];  /* 保存触点 */
    int max_slots;      /* 最大的触点数 */


    ts = ts_setup(NULL, 0); /* 用来配置打开的设备节点,已经在文件系统中配置好了  */
    if(!ts)
    {
        printf("ts_setup error!\n");
        return -1;
    }
    /* 通过ioctl函数传入命令进去来返回想要的参数并存储在slot中 */
    if (ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) 
        {
    		perror("ioctl EVIOGABS");
    		ts_close(ts);
    		return errno;
   	    }
    /* 支持的最大触摸点数 */
    max_slots = slot.maximum + 1 - slot.minimum;

    samp_mt = malloc(sizeof(struct ts_sample_mt *));
    if (!samp_mt) 
    {
		ts_close(ts);
		return -ENOMEM;
	}
    samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
	if (!samp_mt[0]) {
		free(samp_mt);
		ts_close(ts);
		return -ENOMEM;
	}


    prev_samp_mt = malloc(sizeof(struct ts_sample_mt *));
    if (!prev_samp_mt) 
    {
		ts_close(ts);
		return -ENOMEM;
	}
    prev_samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
	if (!prev_samp_mt[0]) {
		free(prev_samp_mt);
		ts_close(ts);
		return -ENOMEM;
	}

    /* 清除掉里面的数据 */
    /* 只需要判断ts_sample_mt中的valid来查看是否更新了数据 */
    for(i = 0;i< max_slots;i++)
        prev_samp_mt[0][i].valid = 0;


    while(1)
    {        
        /*
            开始读取数据 
            假设nr设置为1,max_slots设置为5,
            那么读到的数据保存在:samp[0][0]、
            samp[0][1]、samp[0][2]、samp[0][3]、samp[0][4]中
        */
        ret = ts_read_mt(ts, samp_mt, max_slots, 1);

        if(ret < 0)
        {
            printf("ts_read_mt error!\n");
            ts_close(ts);
            return -1;
        }

        /* 将读到的数据从samp_st拷贝到prev_samp_mt中 */
        for(i = 0;i< max_slots;i++)
        {   
            /* 数据有更新 */
            if(samp_mt[0][i].valid)
            {
                memcpy(&prev_samp_mt[0][i], &samp_mt[0][i], sizeof( struct ts_sample_mt));
            }
        }

        touch_cnt = 0;
        /* 
            记录同时按下的点数
            驱动程序使用slot,tracking_id来标识一个触点,
            tracking_id等于-1时,标识这个触点已经松开。 
        */
        for(i = 0;i < max_slots;i++)
        {
            if(prev_samp_mt[0][i].valid && prev_samp_mt[0][i].tracking_id != -1)
                point_pressed[touch_cnt ++] = i;
        }

        if(touch_cnt == 2)
        {
            printf("distance : %08d\n",distance(&prev_samp_mt[0][point_pressed[0]],&prev_samp_mt[0][point_pressed[1]]));
        }
    }

    


    return 0;
}






实际测试:
在这里插入图片描述
函数详解:

/* 通过传入文件名,是否阻塞,并选择环境变量 */
struct tsdev *ts_setup(const char *dev_name, int nonblock)

/* 调用ts_open函数来打开文件,并确定是否阻塞 */
ts = ts_open(dev_name, nonblock);	

/* 
	通过环境变量TSLIB_TSDEVICE来确定打开的触摸屏节点号,我们在编译tslib的时候就已经做好了这一步,扫描过程是首先扫描环境变量,如果环境变量中不包括触摸屏节点,就扫描
static const char * const ts_name_default[] = {
		"/dev/input/ts",
		"/dev/input/touchscreen",
		"/dev/touchscreen/ucb1x00",
		NULL
};
如果还没有找到的话,就调用fname = scan_devices();函数去扫描本机中的触摸屏节点。
 */
dev_name = dev_name ? dev_name : getenv("TSLIB_TSDEVICE");

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值