Linux驱动,之input驱动,移植与编译tslib库,应用层,调用库来读取触摸屏坐标(二)

原文链接:https://blog.youkuaiyun.com/weixin_44453694/article/details/127937666

这种移植编译的教程,网上非常多,很有用,在写触摸屏应用的时候,移植这个库,简化我们开发时,自己写各种复杂的函数。可以用到实际的项目中。

一、tslib库编译与移植

1.tslib库简介

tslib 是电阻式触摸屏用于校准的一个软件库,是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能,通常作为触摸屏驱动的适配层,为上层的应用提供了一个统一的接口。

2 相关工具安装
安装必要工具libtool、automake、autoconf

$ sudo apt-get install libtool
$ sudo apt-get install automake
$ sudo apt-get install autoconf

3 tslib安装步骤

系统环境
开发环境: Ubuntu18.04
目标开发板: Tiny4412
交叉编译器: arm-linux-gcc
Linux内核: Linux3.5

1.下载tslib库源码包,将源码解压到用户目录下。

tslib源码下载地址:https://github.com/libts/tslib/releases

在这里插入图片描述

2.configure配置,生成Makefile文件。

[wbyq@wbyq tslib-master]$ ./autogen.sh
[wbyq@wbyq tslib-master]$ ./configure --host=arm-linux ac_cv_func_malloc_0_nonnull=yes --cache-file=arm-linux.cache --prefix=$PWD/_install
  • -host=arm-linux - - -指定编译器
  • -prefix=$PWD/_install - - -指定安装目录

3.编译安装。

 make
 make install  

编译安装好后会生成 _install 文件夹。
在这里插入图片描述

[wbyq@wbyq tslib-master]$ cd _install/
[wbyq@wbyq _install]$ tree
.
├── bin
│   ├── ts_calibrate
│   ├── ts_harvest
│   ├── ts_print
│   ├── ts_print_raw
│   └── ts_test
├── etc
│   └── ts.conf
├── include
│   └── tslib.h
└── lib
    ├── libts-1.0.so.0 -> libts-1.0.so.0.0.0
    ├── libts-1.0.so.0.0.0
    ├── libts.la
    ├── libts.so -> libts-1.0.so.0.0.0
    ├── pkgconfig
    │   ├── tslib-1.0.pc
    │   └── tslib.pc
    └── ts
        ├── arctic2.la
        ├── arctic2.so
        ├── collie.la
        ├── collie.so
        ├── corgi.la
        ├── corgi.so
        ├── dejitter.la
        ├── dejitter.so
        ├── dmc.la
        ├── dmc.so
        ├── galax.la
        ├── galax.so
        ├── h3600.la
        ├── h3600.so
        ├── input.la
        ├── input.so
        ├── linear_h2200.la
        ├── linear_h2200.so
        ├── linear.la
        ├── linear.so
        ├── mk712.la
        ├── mk712.so
        ├── pthres.la
        ├── pthres.so
        ├── tatung.la
        ├── tatung.so
        ├── touchkit.la
        ├── touchkit.so
        ├── ucb1x00.la
        ├── ucb1x00.so
        ├── variance.la
        └── variance.so

6 directories, 45 files

4.拷贝bin目录下的文件到开发板/bin目录下。

[wbyq@wbyq _install]$ cp bin/* /home/wbyq/soft_work/rootfs/bin/

5.拷贝lib目录下的.so文件到开发板的/lib目录下。

[wbyq@wbyq _install]$ cp lib/.so /home/wbyq/soft_work/rootfs/lib/ -rfdv
[wbyq@wbyq _install]$ cp lib/ts/ /home/wbyq/soft_work/rootfs/lib/ -rfdv

6.拷贝etc/ts.conf文件到开发板的/etc目录下。

[wbyq@wbyq _install]$ cp etc/ts.conf /home/wbyq/soft_work/rootfs/etc/

7.修改配置文件。
如果希望使用linux输入层事件接口,需要取消module_raw input 注释。

[wbyq@wbyq _install]$ vim /home/wbyq/soft_work/rootfs/etc/ts.conf
在这里插入图片描述

8.配置开发板的的启动文件 profile。event2,需要根据自己开发板,设置,是否是这个。

[wbyq@wbyq _install]$ vim /home/wbyq/soft_work/rootfs/etc/profile
在这里插入图片描述

注意: 设置完环境变量之后,需要重启开发板生效,或者使用 source 命令立即生效。

开发板运行效果

前提是要安装好开发板,安装触摸屏驱动,检查触摸屏设备节点是否为上面设置的event2,运行ts_test。

[root@wbyq code]# insmod ft5x06_dev.ko
[ 759.390000] IIC子系统:设备层注册成功

[root@wbyq code]# insmod ft5x06_drv.ko
[ 762.175000] IIC子系统:驱动层注册成功

[ 762.175000] 资源匹配成功
[ 762.175000] input: Unspecified device as /devices/virtual/input/input3

[root@wbyq code]# ts_test
874.277420: 388 354 1
874.322712: 384 352 1
874.337917: 369 348 1
874.353162: 355 346 1
874.368397: 332 343 1
874.383524: 304 339 1
874.398664: 277 337 1
874.413889: 258 336 1
874.429156: 243 335 1
874.444247: 234 334 1
874.474649: 230 333 1
874.489914: 236 330 1
874.504974: 248 328 1

tslib中提供的测试命令,是通过ts.config文件读取相应的触摸屏配置信息和LCD屏配置信息。提供非常多的测试命令,可以写字。
在这里插入图片描述

可以调用tslib提供的函数,来读取坐标,我们就不用字节写读取input,我们前面那样写的。
使用 tslib 提供的 API 接口来编写触摸屏应用程序,使用 tslib 库函数需要在我们的应用程序中包含 tslib 的头文件 tslib.h。

1、基于tslib写单点触摸屏应用程序

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

#include "tslib.h"
int main(int argc,char *argv[])
{
	struct tsdev *ts;
	char *tsdevice=NULL;
	
	/*打开触摸屏设备节点*/
	if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL ) {
		ts = ts_open(tsdevice,0);
	} 
	else {
		ts = ts_open("/dev/input/event2",0);
	}
	
	if(ts==NULL)
	{
		perror("ts_open");
		exit(1);
	}
	
	if (ts_config(ts)) {
		perror("ts_config");
		exit(1);
	}
	
	struct ts_sample samp;
	int ret;
	printf("   时间    \t X坐标   \t Y坐标\t压力值 \n");

	while (1)
	{
		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", samp.tv.tv_sec, samp.tv.tv_usec,samp.x, samp.y, samp.pressure);
	}
	return 0;	
}

可以看出上述步骤:

打开触摸屏设备:struct tsdev *ts_setup(const char *dev_name, int nonblock),参数 dev_name 指定触摸屏的设备节点,参数 nonblock 表示是否以非阻塞方式打开触摸屏设备。
配置触摸屏设备:int ts_config(struct tsdev *ts),解析 ts.conf 文件中的配置信息,加载相应的插件。
读取触摸屏数据:int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr),ts_read 用于读取单点触摸数据
代码中ts_setup函数的dev_name参数为null,函数内部会读取TSLIB_TSDEVICE 环境变量,获取该环境变量的内容以得知触摸屏的设备节点。
在这里插入图片描述
ts_read()函数的 samp 参数是一个 struct ts_sample *类型的指针,指向一个 struct ts_sample 对象,struct ts_sample 数据结构描述了触摸点的信息。

程序编译时,要指定库的,如下。

cflags=-I/home/wbyq/soft_work/tslib-master/tslib-master/_install/include  		#指定头文件
cflags+=-L/home/wbyq/soft_work/tslib-master/tslib-master/_install/lib 		 	#指定库文件路径
cflags+=-lts  				#指定库

app:
	arm-linux-gcc app.c -o app $(cflags)

或者这样

${CC} -I /home/jack/linux/tslib/tools/tslib/include -L /home/jack/linux/tslib/tools/tslib/lib -lts -o ts_single_touch tslib_touch.c

-I 指定tslib库的头文件路径
-L 指定tslib库路径
-l 指定链接库,也就是 libts.so 库文件

在这里插入图片描述

2、基于tslib写多点触摸屏应用程序
使用 ts_read_mt()函数读取多点触摸数据

#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
                        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);
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值