minigui V1.6.10 + tslib 触摸屏较正完美解决方案

作者:黄思华   地址:华侨大学信息学院

 说明:因为最近做PDA,要实现摄像头功能,而我的开发板mini2440,只有一个USB,而我的摄像头是USB的,鼠标没办法用了,只能用触摸笔,而触摸坐标非常不准,首先想到了qt下用的tslib,网上找了一下,还真有minigui+tslib的触摸屏较正方案。经过几天的实验,我在V1.6.0上用tslibSMDK2410实现了触摸屏较正,也在V1.6.10上用tslib+dummy作为ial实现了触摸屏较正。此文先总结介绍minigui V1.6.10 + tslib 完美触摸屏较正方案。

由于在libminigui 中没有发布2410.c,2410.h等,以前版本是有的,所以要用SMDK2410作为ial有些困难,我做过实验失败了,不想弄了,就用dummy+tslib解决吧。说了这么多,下面是详细步骤:

硬件环境:

HostX86PC

Target:友善之臂mini2440开发板

软件环境:

HostVMware虚拟机下的redhat linux 9.0(完全安装)

Targetarm-linux             kernel:linux-2.6.13

Crosstool: arm-linux-gcc-3.4.1

一、移植tslib1.3

(1) 第一步:下载source code并解压

我用的是tslib-1.3.tar.bz2

下载地址:http://download.csdn.net/source/673898

(2) 第二步:针对底层驱动修改配置信息

./autogen.sh                 (这步会生产configure文件)

./configure CC=arm-linux-gcc --build=i686-pc-linux --target=arm-linux --host=arm-linux  --prefix=/home/huangsihua/tslib/build --enable-inputapi=no

其中最后一项--enable-inputapi=no 是由于驱动不支持ioctl操作,如果不改最后会有如下现象:

我在板子上运行./ts_test的时候,总是提示我:ts_open: No such file or directory

(3) 第三步:修改源码

1 修改/tslib/plugins/Makefile里面找rpath

LDFLAGS :=$(LDFLAGS) -rpath $(PLUGIN_DIR)

修改为:

LDFLAGS :=$(LDFLAGS) -rpath `cd $(PLUGIN_DIR) && pwd`(这个可是顿号)

否则make时报如下错:

make的时候libtool:link: only absolute run-paths are allowed

 

2、修改src/ts_read_raw.c中的  char *defaulttseventtype="UCB1x00";改为char *defaulttseventtype="H3600",因为我的触摸屏驱动对应此结构。

 

3、修改tslib源码的tests/ts_calibrate.cgetxy函数中修改一些代码。如下

static int getxy(struct tsdev *ts, int *x, int *y)

{

..................................................................

..................................................................

修改的代码

/* Read until we get a touch. */

do {

 

if (ts_read_raw(ts, &samp[0], 1) < 0) {

perror("ts_read");

 

close_framebuffer();

exit(1);

}

} while (samp[0].pressure > 0);

 

do {

 

if (ts_read_raw(ts, &samp[0], 1) < 0) {

perror("ts_read");

close_framebuffer();

exit(1);

}

} while (samp[0].pressure == 0);

printf("Took %d samples.../n",index);

..................................................................

..................................................................

}

我发现tslibminigui中对于压力参数的规定刚好相反,tslib规定samp[0].pressure> 0是按下,samp[0].pressure == 0是手松开而事实是相反的

如果不改就会出现在运行./ts_calibrate程序时不能有效校准,这个一定得注意!!!!!!!!!!!!!!!

 

4、修改在tslib/plugins/mousebuts.c mousebuts_read函数中一段代码

//if(t>60)

//{

//dest->pressure=1000;

//buts->fLeftBut=0;

//}

//else

//{

dest->pressure=0;

buts->fLeftBut=2;

//}

要将红色的部分注释掉,否则以后运行minigui时对按钮的操作时,如果对一个按钮进行点击时,并把光标停在按钮的上面

它就会不断的触发按钮的点击事件,这当然不是我们想要得到的结果

4)编译与安装

make

make install

经过安装步骤后,进入…./tslib/build 目录下可以看到如下几个文件夹:

binetcsharelibinclude

# ls bin/

      ts_calibrate ts_print ts_test ts_print_raw

# ls etc/

      ts.conf

这里建议配置为(我就是用的这个配置,效果还不错)

module mousebuts

#module variance xlimit=20 ylimit=20 pthreshold=3

#module dejitter xdelta=20 ydelta=20 pthreshold=3

module linear

若实际运行时发现抖动比较厉害,可以采用下面的配置:

module mousebuts

#module variance xlimit=20 ylimit=20 pthreshold=3

module dejitter xdelta=20 ydelta=20 pthreshold=3

module linear

  # ls lib/

 libts-0.0.so.0 libts-0.0.so.0.1.0 libts.la libts.so

  # ls share/ts/

      plugins/

libinclude的内容COPY/usr/local/arm/3.4.1/arm-linux/[libinclude]中。

同时在/opt/FriendlyARM/mini2440/root_nfs下建立一个目录tslib

mkdir tslib

将主机…../tslib/build/下的五个文件夹COPY至该目录下

至此tslib交叉编译安装完毕。

二、修改dummy.c重新配置编译libminigui(tslibminigui的链接)


完成了对 tslib 的交叉编译之后,

下一步的事情就是改写 MiniGUI IAL 引擎。MiniGUI自带的 IAL 输入引擎中,有一个叫做 dummy.c。为了尽可能简单,在这里为简单起见就在其基础上稍作修改,使之符合我们的要求即可。

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <fcntl.h>

#include "common.h"

#include "tslib.h"

#ifdef _DUMMY_IAL

#include <sys/ioctl.h>

#include <sys/poll.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <linux/kd.h>

#include "ial.h"

#include "dummy.h"

#ifndef _DEBUG

#define _DEBUG                    // for debugging

#endif

/* for storing data reading from /dev/touchScreen/0raw */

typedef struct {

       unsigned short pressure;

       unsigned short x;

       unsigned short y;

       unsigned short pad;

} TS_EVENT;

static unsigned char state [NR_KEYS];

static int mousex = 0;

static int mousey = 0;

static TS_EVENT ts_event;

static struct tsdev *ts;

/************************ Low Level Input Operations **********************/

/*

* Mouse operations -- Event

*/

static int mouse_update(void)

{

        return 1;

}

static void mouse_getxy(int *x, int* y)

{

        if (mousex < 0) mousex = 0;

        if (mousey < 0) mousey = 0;

        if (mousex > 239) mousex = 239;

        if (mousey > 319) mousey = 319;

#ifdef _DEBUG

       // printf ("mousex = %d, mousey = %d/n", mousex, mousey);

#endif

       *x = mousex;

       *y = mousey;

}

static int mouse_getbutton(void)

{

        return ts_event.pressure;

}

#ifdef _LITE_VERSION

static int wait_event (int which, int maxfd, fd_set *in, fd_set *out, fd_set *except,                        struct timeval *timeout)

#else

static int wait_event (int which, fd_set *in, fd_set *out, fd_set *except,

                        struct timeval *timeout)

#endif

{

        struct ts_sample sample;

        int ret = 0;

        int fd;

        fd_set rfds;

        int e;

       if (!in) {

              in = &rfds;

              FD_ZERO (in);

       }

fd = ts_fd(ts);

       if ((which & IAL_MOUSEEVENT) && fd >= 0) {

              FD_SET (fd, in);

#ifdef _LITE_VERSION

              if (fd > maxfd) maxfd = fd;

#endif

        }

#ifdef _LITE_VERSION

       e = select (maxfd + 1, in, out, except, timeout) ;

#else

      e = select (FD_SETSIZE, in, out, except, timeout) ;

#endif

       if (e > 0) {

            // input events is coming

             if (fd > 0 && FD_ISSET (fd, in)) {

                   FD_CLR (fd, in);

                   ts_event.x=0;

                  ts_event.y=0;

                  ret = ts_read(ts, &sample, 1);

                  if (ret < 0) {

                        perror("ts_read()");

                        exit(-1);

                  }

                  ts_event.x = sample.x;

                  ts_event.y = sample.y;

                  ts_event.pressure = (sample.pressure > 0 ? 4:0);

               //   if (ts_event.pressure > 0 &&

                     if((ts_event.x >= 0 && ts_event.x <= 239) &&

                        (ts_event.y >= 0 && ts_event.y <= 319)) {

                        mousex = ts_event.x;

                         mousey = ts_event.y;

                   // printf("ts_event.x is %d, ts_event.y is %d------------------------------------->/n",ts_event.x ,ts_event.y);

                   }

//#ifdef _DEBUG

              //    if (ts_event.pressure > 0) {

        //  printf ("mouse down: ts_event.x = %d, ts_event.y = %d,ts_event.pressure = %d/n",ts_event.x,ts_event.y,ts_event.pressure);

               //   }

//#endif

                   ret |= IAL_MOUSEEVENT;

                  return (ret);

             }

      }

       else if (e < 0) {

             return -1;

      }

       return (ret);

}

BOOL InitDummyInput(INPUT* input, const char* mdev, const char* mtype)

{

      char *ts_device = NULL;

       if ((ts_device = getenv("TSLIB_TSDEVICE")) != NULL) {

            // open touch screen event device in blocking mode

            ts = ts_open(ts_device, 0);

      } else {

#ifdef USE_INPUT_API

             ts = ts_open("/dev/input/0raw", 0);

#else

             ts = ts_open("/dev/touchscreen/ucb1x00", 0);

#endif

      }

#ifdef _DEBUG

        printf ("TSLIB_TSDEVICE is open!!!!!!!!!!!/n");

#endif

       if (!ts) {

           perror("ts_open()");

             exit(-1);

       }

      if (ts_config(ts)) {

            perror("ts_config()");

            exit(-1);

       }

      input->update_mouse = mouse_update;

      input->get_mouse_xy = mouse_getxy;

      input->set_mouse_xy = NULL;

      input->get_mouse_button = mouse_getbutton;

      input->set_mouse_range = NULL;

      input->wait_event = wait_event;

      mousex = 0;

      mousey = 0;

      ts_event.x = ts_event.y = ts_event.pressure = 0;

       return TRUE;

}

void TermDummyInput(void)

{

      if (ts)

            ts_close(ts);

}

#endif /* _DUMMY_IAL */

修改好minigui的引擎文件后就可以对minigui进行重新编译了,因为用到了 tslib 库,所以必须在编译的时候告诉 MiniGUI 到哪里去找到 tslib 相关的头文件和共享库文件。具体做法如下所示:

[root@libminigui-1.6.10]# ./configure CC=arm-linux-gcc --build=i686-pc-linux --target=arm-linux --host=arm-linux --disable-galqvfb --disable-galecoslcd --disable-vbfsupport --prefix=/usr/local/arm/3.4.1/arm-linux CFLAGS="-I/usr/local/arm/3.4.1/arm-linux/include -L/usr/local/arm/3.4.1/arm-linux/lib -lts"

[root@ libminigui-1.6.10]# make

[root@ libminigui-1.6.10]# make install

 这里说一下为什么要指定 CFLAGS 标志。其实,通过指定这个标志,告诉编译器应该到哪里去找 tslib 有关的头文件和共享文件, -lts则告诉链接器最后生成的 MiniGUI 的共享库文件最后要和 ts 库(ts touchscreen 的缩写)链接。

     将生成的minigui的库从/usr/local/arm/3.4.1/arm-linux/lib  COPY/opt/FriendlyARM/mini2440/root_nfs/lib下。

 

[Root]# cp /usr/local/arm/3.4.1/arm-linux/etc/MiniGUI.cfg /home/fp/nfs/usr/local/etc/ 记住,保持目录结构的一致

修改 MiniGUI.cfg ,如下

 

[system]

# IAL engine

ial_engine=dummy // 这里修改,我用的是触摸屏,所以就用dummy肯定不会错

mdev=/dev/input/ts0      //解摸屏

mtype=none

[fbcon]

defaultmode=240x320-16bpp // 根据你的LCD大小自己设置,设置错误minigui 就启动不了。

这样我们就把tslibminigui通过dummy链接好了。

三、测试

重编译我我修改制作的PDA程序并将它和res文件COPY/opt/FreindlyARM/mini2440/root_nfs/usr/local/下,打开超级终端,打开开发板,按回车进入VIVI,输入NFS启动命令:

param set linux_cmd_line "console=ttySAC0 root=/dev/nfs nfsroot=192.168.1.111:/opt/FriendlyARM/root_nfs ip=192.168.1.70:192.168.1.111:192.168.1.111:255.255.255.0:sbc2440.arm9.net:eth0:off"

同时在终端输入扩展命令:

export QWS_MOUSE_PROTO=TPanel:/dev/input/event0

export V_ROOT=/tslib

#export TSLIB_TSEVENTTYPE=H3600

export TSLIB_CONSOLEDEVICE=none

export TSLIB_FBDEVICE=/dev/fb0

export TSLIB_TSDEVICE=/dev/input/event0

export TSLIB_CALIBFILE=$V_ROOT/etc/pointercal

export TSLIB_CONFFILE=$V_ROOT/etc/ts.conf

export TSLIB_PLUGINDIR=$V_ROOT/share/ts/plugins

export LD_LIBRARY_PATH=$V_ROOT/lib:$LD_LIBRARY_PATH

当然你也可以把这一串加到profile文件,让开发板在启动时运行这些命令。

最后进入程序所在目录运行

./PDA就可以了,效果非常不错,堪称完美。

有点长哦, minigui V1.6.10 + tslib 触摸屏较正完美解决方案,欢迎大家提出意见和更好的方案。

EMAILhuangsihua@hqu.edu.cn

本人CSDN博客http://blog.csdn.net/huangsihua

参考文章:myleeming   CSDN博客minigui+tslib编译全过程

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值