首先要配置编译选项,在 libminigui-1.6.10 顶层目录下,通过使用 configure脚本来进行相关的配置。运行 configure 脚本,会生成 makefile 文件,然后根据传递给 configure 脚本的各种选项来生成 mgconfig.h文件。之后,运行 make和 make install命令,就可以编译MiniGUI并将 MiniGUI的头文件和函数库安装到指定目录。
./configure --prefix=/minigui/miniguitmp --target=arm-linux --host=arm-linux --build=i686-pc-linux-gnu --enable-smdk2410ial=yes
运行之后,产生makefile 等几个文件。
然后修改mgconfig.h文件,因为我在./configure中虽然指定了--enable-smdk2410ial=yes,但是编译后仍然没有编译smdk2410,所以需要修改。
讲mgconfig.h中的#undef _SMDK2410_IAL 更改为#define _SMDK2410_IAL 1.
保存后
make
make install
将函数库,头文件等安装到指定的路径/minigui/miniguitmp中。
(3)安装资源文件的方法。
tar –xzvf minigui-res-1.6.x.tar.gz
cd minigui-res-1.6.x
vi config.linux
将prefix修改为要安装的目录/minigui/miniguitmp
#make install
要在板上运行该编译好的程序,还需要做一些准备工作。
首先,将上面生成的库文件放到板上根文件系统/usr/lib 目录中。动态编译的程序,需要依赖这些库文件,少了则无法运行。
有了库文件,还不够,还需要资源文件。资源文件放在板上根文件系统/usr/lib/minigui/res 里,但是在 MiniGUI 的配置里一定要指定到正确的路径,否则会找不到资源而报错。
另外,还需要 MiniGUI的配置文件。配置文件是放在板上根文件系统/etc/下。要想适合目标板环境, MiniGUI.cfg 文件内容需要修改。
[system]
# GAL engine and default options
gal_engine=fbcon
defaultmode=240 x 320 -16bpp
# IAL engine
ial_engine=SMDK2410
mdev=/dev/ts
mtype=none
[fbcon]
defaultmode=240 x 320 -16bpp
[qvfb]
defaultmode=240 x 320-16bpp
display=0
# The first system font must be a logical font using RBF device font.
[systemfont]
font_number=6
font0=rbf-fixed-rrncnn-8-16-ISO8859-1
font1=*-fixed-rrncnn-*-16-GB2312
font2=*-Courier-rrncnn-*-16-GB2312
font3=*-SansSerif-rrncnn-*-16-GB2312
font4=*-Times-rrncnn-*-16-GB2312
font5=*-Helvetica-rrncnn-*-16-GB2312
default=0
wchar_def=1
fixed=1
caption=2
menu=3
control=3
font_number=4
name0=rbf-fixed-rrncnn-8-16-ISO8859-1
fontfile0=/usr/lib/minigui/res/font/8x16-iso8859-1.bin
特别注意红字部分。本人目标板的液晶屏使用 320*240 16bpp 模式。GAL 引擎选择
fbcon。
这样在制作根文件系统后在烧写到开发板里就能启动了。
我启动开发板后,下载个程序运行,发现触摸屏非常不准确。
我就上网搜了解决办法,参考大漠孤狼的带屏幕校正功能2410的 IAL的帖子。下面的是他的帖子的内容。其中我采用了tslib中带的触摸屏校准程序,
把下面的数组中的内容static mPOINT ts_position[4]={ {940,926},{940,102},{96,104},{120,940} };
static mPOINT display_position[4]={ {0,0},{0,319},{239,319},{239,0} };
改为我自己的了。然后把新修改的2410.c重新拷到/libminigui1.6.10/src/ial中,按照上面的方法重新编译。这样触摸屏就好使了。
根据以上原因,我对 MiniGUI 1.3.3 版本中的 2410 的 IAL 程序进行了修改,使得它在我的 便宜屏 上一样可以正常工作。它提供了去抖动功能,就是点击时一头一尾那两下的不准确的值不能要,同时提供了一个方便的屏幕校准程序,你只需要做小小的修改就可以 校准让它在你的便宜屏上很好的正常工作了。
新程序的使用方法:
在 2410.c 中定义了两个数组,如下
typedef struct mPoint { int x,
y ;
} mPOINT ;
static mPOINT ts_position[4]={ {940,926},{940,102},{96,104},{120,940} };
static mPOINT display_position[4]={ {0,0},{0,319},{239,319},{239,0} };
ts_position 意思为 TouchScreen 的 位置
display_position 意思为屏幕上显示的 位置
比如我前面说的,我的屏幕是 240x320 的,我点四个角 {0,0},{0,319},{239,319},{239,0} ,从触屏上读出来的数据分别为 {940,926},{940,102},{96,104},{120,940} ,填入这两个数就行
所以使用方法就是,你自己取四个点(其实只要3个点就够了,呵),点这四个点,得到相应的触摸屏读出来的值,把这些数据填到这两个数组中,OK,你的 触摸屏 就可以正常工作了 :)
后面附一个 readpos.c 的程序,你可以执行它,然后点击触摸屏,它会显示出触摸屏读出来的值。
程序: 2410_带触摸屏校正功能.c
#include
#include
#include
#include
#include
#include "common.h"
#ifdef _SMDK2410_IAL
#include
#include
#include
#include
#include
#include /* i add it here */
#include
#include
#include
#include "ial.h"
#include "2410.h"
typedef struct mPoint {
int x,
y ;
} mPOINT ;
static mPOINT ts_position[4]={ {940,926},{940,102},{96,104},{120,940}
};
static mPOINT display_position[4]={ {0,0},{0,319},{239,319},{239,0}
};
typedef struct Matrix {
/* This arrangement of values facilitates
* calculations within getDisplayPoint()
*/
int An, /* A = An/Divider */
Bn, /* B = Bn/Divider */
Cn, /* C = Cn/Divider */
Dn, /* D = Dn/Divider */
En, /* E = En/Divider */
Fn, /* F = Fn/Divider */
Divider ;
} mMATRIX ;
static mMATRIX m_matrix;
int setCalibrationMatrix( mPOINT * display,
mPOINT * screen,
mMATRIX * matrix) ;
int getDisplayPoint( mPOINT * display,
mPOINT * screen,
mMATRIX * matrix ) ;
/* for data reading from /dev/ts */
typedef struct {
unsigned short pressure;
unsigned short x;
unsigned short y;
unsigned short pad;
} TS_EVENT;
static unsigned char state [NR_KEYS];
static int ts = -1;
static int mousex = 0;
static int mousey = 0;
static TS_EVENT ts_event;
#undef _DEBUG
/************************ Low Level Input Operations **********************/
/*
* Mouse operations -- Event
*/
static int mouse_update(void)
{
return 1;
}
static void mouse_getxy(int *x, int* y)
{
#ifdef _DEBUG
printf ("mousex = %d, mousey = %d\n", mousex, mousey);
#endif
if (mousex < 0) mousex = 0;
if (mousey < 0) mousey = 0;
if (mousex > 239) mousex = 239;
if (mousey > 319) mousey = 319;
*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
{
fd_set rfds;
int retvalue = 0;
int e;
static int last_pressure=0;
if (!in) {
in = &rfds;
FD_ZERO (in);
}
if ((which & IAL_MOUSEEVENT) && ts >= 0) {
FD_SET (ts, in);
#ifdef _LITE_VERSION
if (ts > maxfd) maxfd = ts;
#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) {
if (ts >= 0 && FD_ISSET (ts, in) ) {
FD_CLR (ts, in);
ts_event.x=0;
ts_event.y=0;
read (ts, &ts_event, sizeof (TS_EVENT));
if(last_pressure==0)
{
read(ts,&ts_event,sizeof(TS_EVENT));
read(ts,&ts_event,sizeof(TS_EVENT));
}
if (ts_event.pressure > 0 ) {
int new_x;
int new_y;
mPOINT ts_point,display_point;
ts_point.x=ts_event.x;
ts_point.y=ts_event.y;
getDisplayPoint(&display_point,&ts_point,&m_matrix);
new_x = display_point.x;
new_y = display_point.y;
if(last_pressure==0 || (last_pressure>0 && abs(new_x-mousex)<7))
mousex=new_x;
if(last_pressure==0 || (last_pressure>0 && abs(new_y-mousey)<7))
mousey=new_y;
/*
printf("ts_x=%d,ts_y=%d\n",ts_event.x,ts_event.y);
printf("mounsex=%dmousey=%d\n",mousex,mousey);
*/
}
#ifdef _DEBUG
if (ts_event.pressure > 0) {
printf ("mouse down: ts_event.x = %d, ts_event.y = %d\n", ts_event.x, ts_event.y);
}
#endif
ts_event.pressure = ( ts_event.pressure > 0 ? IAL_MOUSE_LEFTBUTTON : 0);
last_pressure=ts_event.pressure;
/*
printf("pressure=%d\n",ts_event.pressure);
*/
retvalue |= IAL_MOUSEEVENT;
}
}
else if (e < 0) {
return -1;
}
return retvalue;
}
BOOL Init2410Input (INPUT* input, const char* mdev, const char* mtype)
{
ts = open ("/dev/ts", O_RDONLY);
if (ts < 0) {
fprintf (stderr, "2410: Can not open touch screen!\n");
return FALSE;
}
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;
setCalibrationMatrix(&display_position,&ts_position,&m_matrix);
return TRUE;
}
void Term2410Input(void)
{
if (ts >= 0)
close(ts);
}
#endif /* _SMDK2410_IAL */
int setCalibrationMatrix( mPOINT * displayPtr,
mPOINT * screenPtr,
mMATRIX * matrixPtr)
{
int retvalue = 0 ;
matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
if( matrixPtr->Divider == 0 )
{
retvalue = -1 ;
}
else
{
matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) -
((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ;
matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) -
((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ;
matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y +
(screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y +
(screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ;
matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) -
((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ;
matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) -
((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ;
matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y +
(screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y +
(screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ;
}
return( retvalue ) ;
} /* end of setCalibrationMatrix() */
int getDisplayPoint( mPOINT * displayPtr,
mPOINT * screenPtr,
mMATRIX * matrixPtr )
{
int retvalue = 0 ;
if( matrixPtr->Divider != 0 )
{
/* Operation order is important since we are doing integer */
/* math. Make sure you add all terms together before */
/* dividing, so that the remainder is not rounded off */
/* prematurely. */
displayPtr->x = ( (matrixPtr->An * screenPtr->x) +
(matrixPtr->Bn * screenPtr->y) +
matrixPtr->Cn
) / matrixPtr->Divider ;
displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) +
(matrixPtr->En * screenPtr->y) +
matrixPtr->Fn
) / matrixPtr->Divider ;
}
else
{
retvalue = -1 ;
}
return( retvalue ) ;
} /* end of getDisplayPoint() */