基于无触屏模式的Mingui1.6在友善之臂mini2440上的移植
开发库:libminigui-1.6.0.tar.gz
资源文件:minigui-res-1.6.10.tar.gz
示例程序:mg-samples-1.6.10.tar.gz
编译安装
1)在fedora14下建立新的工作目录
[root@embedclub /]#mkdir minigui
[root@embedclub /]#mkdir /minigui/compressed /minigui/source
[root@embedclub /]#cd /minigui/compressed 把下载好的资源包拷贝到该目录下
2)编译安装minigui-res-1.6.10.tar.gz
Minigui-res*.gz是包含基本字体、图片、位图和鼠标光标的图形库。
[root@embedclub compressed]#tar zxvf minigui-res-1.6.10.tar.gz
[root@embedclub compressed]#cd ../source/minigui-res-1.6.10
[root@embedclub minigui-res-1.6.10]#make install
将在/usr/local/lib目录下生成的minigui文件夹整体拷贝到网络根文件系统root_qtopia中的/usr/local/lib/下实际上这个目录与配置问价MiniGui.cfg里的相应内容目录一致,以便更好的找到相应资源。
3)编译安装libminigui-1.6.10.tar.gz minigui函数库源代码
[root@embedclub /]#cd /minigui/compressed
[root@embedclub compressed]#tar zxvf libminigui-1.6.10.tar.gz
[root@embedclub compressed]#cd ../source/libminigui-1.6.10
[root@embedclub libminigui-1.6.10]#./configure --prefix=/home/ --host=arm-linux --target=arm-linux --build=i386-linux --with-osname=linux --with-style=classic --with-targetname=fbcon --enable-autoial --enable-commial --enable-rbf16 --disable-vbfsupport
[root@embedclub libminigui-1.6.10]#make
[root@embedclub libminigui-1.6.10]#make install
把/home/lib目录下所有文件拷贝到网络根文件系统的/lib目录下vi t,将/home/etc下的MiniGUI.cfg拷贝到网络根文件系统的/usr/local/etc/目录下 注:--disable-vbfsupport一定注意这个项否则在开发板上运行时会提示找不到var bitmap font实际上在开发板上的/usr/local/lib/minigui/res/font目录下没有var bitmap font字库 。
4)编译mg-sample-1.6.10.tar.gz
解压进入mg-sample-1.6.10目录下
[root@embedclub mg-sample-1.6.10]#./configure CC=arm-linux-gcc --build=i386-linux --target=arm-linux --host=arm-linux --prefix=/usr/local/arm/jiangyongCFLAGS="-I/home/include -L/home/home/lib -lts"
[root@embedclub mg-sample-1.6.10]#make
把生成的可执行文件helloworld拷贝到开发板上。
5)配置
1.在开发板的/etc下建立ld.so.conf文件,添加以下内容:
/usr/local/lib
/usr/lib
/lib#实际上添加这个库文件目录就可以了,目的是运行helloworld时能找到相应的库文件,其他二个是可选的,是为了系统扩展用的
2.修改/usr/local/etc/MiniGui.cfg文件
[system]
#GAL engine and default options
Gal_engine=fbcon
#IAL engine
Ial_engine=dummy
Mdev=/dev/input/event0 或mice
Mtype=none
[fbcon]
Defaultmode=240x320-16bpp
3.在/etc/init.d/rcS脚本中添加如下内容
/bin.ln -s /dev/vc/0 /dev/tty0使Fbcon与你的frambuff设备相关联。
6)测试
启动开发板MIni2440后在终端运行helloworld或者在etc/init.d/rcS启动脚本中添加以下内容/.helloworld &这样minigui程序就自动跑起来了。
Minigui 在友善之臂mini2440上的移植
1、tslib 1.4 在ARM板Micro2440上移植
tslib背景:
在采用触摸屏的移动终端中,触摸屏性能的调试是个重要问题之一,因为电磁噪声的缘故,触摸屏容易存在点击不准确、有抖动等问题。
Tslib是一个开源的程序,能够为触摸屏驱动获得的采样提供诸如滤波、去抖、校准等功能,通常作为触摸屏驱动的适配层,为上层的应用提供了一个统一的接口。
Tslib较准原理:
在Qtopia中,就触摸屏的调试问题主要涉及到以下三个部分:触摸屏驱动、Tslib、QTslibTPanelHandlerPrivate 封装。
触摸屏驱动为与硬件直接接触部分,为上层的Tslib提供最原始的设备坐标数据,并可以配置采样间隔、屏幕灵敏度等。采样间隔决定了单位时间内的采样数量,在其他参数不变的情况下,采样间隔越小意味着单位时间内的采样数量越多,也就意味着采样越逼真、越不容易出现采样信息丢失如输入法书写时丢笔划的情况,但因为噪声的影响,采样间隔越小同时也意味着显示出来的图形的效果越差。
Tslib为触摸屏驱动和应用层之间的适配层,其从驱动处获得原始的设备坐标数据,通过一系列的去噪、去抖、坐标变换等操作,来去除噪声并将原始的设备坐标转换为相应的屏幕坐标。
在tslib中为应用层提供了2个主要的接口ts_read()和ts_read_raw(),其中ts_read()为正常情况下的借口,ts_read_raw()为校准情况下的接口。
正常情况下,tslib对驱动采样到的设备坐标进行处理的一般过程如下:raw device --> variance --> dejitter --> linear --> applicationmodule module module
校准情况下,tslib对驱动采样到的数据进行处理的一般过程如下:raw device--> CalibrateQTslibTPanelHandlerPrivate 为tslib提供了应用层封装,为tslib与应用层的接口部分。
在触摸屏调试过程中,涉及到的参数主要有采样间隔(驱动)、灵敏度(驱动)、去噪算法及约束(tslib)、去抖算法及约束(tslib)、ts门槛值(tslib)。
由于各种相关期间的影响,在不同的硬件平台上,相关参数可能需要调整。以上参数的相互关系为:采样间隔越大,采样点越少,采样越失真,但因为信息量少,容易出现丢笔划等丢失信息情况,但表现出来的图形效果将会越好;去噪算法跟采样间隔应密切互动,采样间隔越大,去噪约束应越小,反之采样间隔越小,去噪约束应越大。去抖算法为相对独立的部分,去抖算法越复杂,带来的计算量将会变大,系统负载将会变重,但良好的去抖算法可以更好的去除抖动,在进行图形绘制时将会得到更好的效果;灵敏度和ts门槛值为触摸屏的灵敏指标,一般不需要进行变动,参考参考值即可。
编译tslib库
1.首先从网上下载的tslib-1.4.tar.gz
2.解压tar xvzf tslib-1.4.tar.gz ; cd tslib
3.生成configure,这里比一般的开源项目少做一步,要先运行解压目录下的脚本
./autogen.sh
4.用configure生成Makefile.
生成脚本:
./configure --host=arm-linux --prefix=/home/tslibac_cv_func_malloc_0_nonnull=yes--enable-inputapi=no
其中ac_cv_func_malloc_0_nonnull=yes是为解决如下编译错误设置的
ts_test.o: In function `main':ts_test.c:(.text+0x1d8): undefined reference to `rpl_malloc'fbutils.o: In function `open_framebuffer':fbutils.c:(.text+0xa20): undefined reference to `rpl_malloc'collect2: ld returned 1 exit status
--enable-inputapi=no. 是为了解决运行中提示ts_open:Inappropriate ioctol for device,它表示即不使用ioctl来控制触摸屏。但是我在几个板没有碰到这样提示--enable-inputapi=no
5.编译安装
make
make install-strip #安装strip后的库
#make install #安装没有strip库版本.
tslib 发布要将libts.so,以及它的针对各个触摸屏设备的插件,ts.conf ts_calibrate一同发布在开发板上,并用前述的环境变量设置相应的值。
tslib1.4 目录下看到相关的应用程序、共享库、配置文件等了,需要说明的是在嵌入式中,由于触摸屏的种类多样、质量不一,采用Tslib的参考配置往往无法获得较好的触摸屏触摸效果,同样需要经过大量的测试才能得到满意的配置参数,恶劣情况下,甚至需要对Tslib的算法进行进一步的优化。
配置与测试tslib
tslib只是应用级的一个程序库,只是用来封装底层的触摸屏驱动的操作,以一个统一接口来给其它应用程序使用.因此tslib正常工作的 前提是开发板上的触摸屏驱动能正常工作.另外触摸屏的效果往往需要在LCD上显示,因此tslib也需要开发板上的FrameBuffer驱动正常工作.。
ARM开发板常见的触摸屏驱动分为两大类,一类是模拟HP 3600的调用接口.这类驱动一般使用/dev/h3600_tsraw的设备结点文件.早期开发板一般都是这一类,
另外一类是采用Linux 2.6输入设备接口的驱动。这类驱动会将触摸屏驱动设计成一个标准输入事件设备(linux input layer event interface),所有事件输入设备结点命名为/dev/input/eventN (N>=0)。
一般都是/dev/input/event0.而且驱动向应用程序发送标准的struct event结构。
ARM板使用哪种驱动接口.要参考产商的文档或直接查看已经成功的程序使用哪一个。
tslib 运行时需要一个关键的ts.conf来设置采用哪一种驱动。另外还需要设定一些环境变量。当编译完tslib安装后,在安装目录的etc下有一个ts.conf的模板。如果使用h3600设备,则使用module_raw h3600,如果是使用输入设备,则使用module_raw input.
#ts.conf template
module_raw input#module_raw h3600
module pthres pmin=1module variance delta=30module dejitter delta=100module linear
其中pthres为Tslib提供的触摸屏灵敏度门槛插件;variance为Tslib提供的触摸屏滤波算法插件;dejitter为Tslib提供的触摸屏去噪算法插件;linear为Tslib提供的触摸屏坐标变换插件。
注意配置项要顶格写,如果有空格,tslib将会u有段错误。这是它的bug.
正常运行tslib也需要配置一系列环境变量,在你板子的/etc/profile配置文件中加入:
#export TSLIB_ROOT=/usr/local/tslibexport TSLIB_ROOT=/mnt/hxy/output/arm_linux#取决具体的设备驱动了,事件驱动用export TSLIB_TSDEVICE=/dev/input/event0#h3600用如下配置# export TSLIB_TSDEVICE=/dev/h3600_tsraw#触摸屏定位文件保存位置export TSLIB_CALIBFILE=/etc/pointercal#tslib配置文件内容export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf#tslib 插件目录export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/tsexport TSLIB_CONSOLEDEVICE=none#LCD设备结点export TSLIB_FBDEVICE=/dev/fb0#把libts.so加入动态搜索路径export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TSLIB_ROOT/lib
将其放入ARM开发的Flash或NFS路径下。可以测试运行安几装目录下的bin的几个测试程序运行ts_test.将会在屏幕出现如下界面。点击控制台将会有输出。
关于触摸屏定位
软件最常采用是鼠标的坐标体系,它是采用相对位移来判断位置.但触摸屏采用绝对定位坐标。为了让程序响应触摸屏的点击,要把触摸屏的坐标换算成软件识别的 相对坐标。因此要有一组参数来做换算。换算的参数来自于触摸屏定位程序,如果参数不对,最明显的结果就是定位不准。每一个使用触摸屏的嵌入式设备通常都带 有这样工具,比如我们使用手机。(但大规模量产的定位参数都是统一设好).
开发板一般需要自己手动设置,tslib自带一个ts_calibrate有这样功能。Qtopia也自带一个。两者界面类似,写的结果通常都是/etc/pointercal这个文本文件里面。
操作方法也类似,当界面出一个小十字时,点击交叉点即可,设置分别会在左上,左下,右上,右下和中心依次出现五个小十字。
2、修改dummy.c重新配置编译libminigui(即tslib和minigui的链接)
(注:res库的安装和移植步骤如无触屏模式一样)
改写MiniGUI的IAL引擎
因为MiniGUI自带的IAL输入引擎中,有一个叫做dummy.c。为了尽可能简单,在这里在其基础上稍作修改,使之符合我们的要求即可,下面为改后的dummy.c文件。
#include
#include
#include
#include
#include
#include "common.h"
#include "tslib.h"
#ifdef _DUMMY_IAL
#include
#include
#include
#include
#include
#include "ial.h"
#include "dummy.h"
#ifndef _DEBUG
#define _DEBUG // for debugging
#endif
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;
static int mouse_update(void)
{
return 1;
}
static void mouse_getxy(int *x, int* y)
{
if (mousex
if (mousey
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
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
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
对minigui重新编译
对minigui进行重新编译了,主要是lib库,因为用到了tslib库,所以必须在编译的时候告诉MiniGUI到哪里去找到tslib相关的头文件和共享库文件
./configure CC=arm-linux-gcc --build=i386-linux --target=arm-linux --host=arm-linux --disable-galqvfb --disable-galecoslcd --disable-vbfsupport --prefix=/usr/local/arm/jiangyongCFLAGS="-I/home/tslib/include -L/home/tslib/lib -lts"
[root@ libminigui-1.6.10]# make
[root@ libminigui-1.6.10]# make install
这里说一下为什么要指定CFLAGS标志。其实,通过指定这个标志,告诉编译器应该到哪里去找tslib有关的头文件和共享文件,-lts则告诉链接器最后生成的MiniGUI的共享库文件最后要和ts库(ts是touchscreen的缩写)链接。
将生成的minigui的lib库从/usr/local/arm/jiangyong/lib COPY到/home/root_qtopia/lib下。
[Root]# cp /usr/local/arm/jiangyong/etc/MiniGUI.cfg/home/root_qtopia/usr/local/etc
修改MiniGUI.cfg
[system]
#GAL engine
gal_engine=fbcon
# IAL engine
ial_engine=dummy //这里修改,我用的是触摸屏,所以就用dummy肯定不会错
mdev=/dev/input/event0//解摸屏
mtype=IMPS2
[fbcon]
defaultmode=240x320-16bpp //根据你的LCD大小自己设置,设置错误minigui就启动不了。
这样我们就把tslib和minigui通过dummy链接好了。
编译测试程序
在这里我以helloworld为例
[Root]#cd /minigui/source/mg-samples-1.6.10/src
[Rootsrc]#Arm-linux-gcc -I/usr/local/jiangyong/include -L/usr/local/jiangyong/lib -L/home/tslib/lib -o helloworld helloworld.c -lpng -ljpeg --lmingui -lpthread -lm
[Rootsrc]# cp helloworld /home/root_qtopia 拷贝到网络根文件系统下
测试程序
运行你的板子,运行tslib/bin/下的触摸屏矫正程序,完了后运行根目录下的helloworld,这是你将看到你的minigui界面的事件可以通过触摸屏控制了。