在移植Minigui到远峰的YFDVK-2440-I板的过程中遇到很多问题,在网上的资料又找不能一个完整一点的。故移植后把移植的过程总结一下,希望对大家有点帮助 。MiniGUI1.33版本可以有编译成两种形式,Lite和Threads,按我的理解是Lite方式适用于同时运行多个MiniGUI程序,而Threads适用于目标系统只需要运行单一的MiniGUI程序。mde我理解成桌面管理模块。由于我只需要在目标系统上运行单一的一个程序,所以编译成 Threads的方式,也没有编译mde模块。MiniGUI是一组动态链接库,可以理解成 Windows的动态链接库,移植MiniGUI的过程相当于在宿主机上交叉编译目标机上的库文件。
宿主机平台使用Red hat Linux9,安装arm-linux-gcc到/usr/local/arm/2.95.3下面。并修改/etc/profile加入pathmunge /usr/local/arm/2.95.3/bin
在飞漫公司下载libminigui-1.3.3.tar.tar、minigui-res-1.3.3.tar.tar。假定保存在~/minigui下面。
1、 释放libminigui-1.3.3.tar.tar,并将文件夹重命名为minigui
cd ~/minigui
tar -zxvf libminigui-1.3.3.tar.tar
mv libminigui-1.3.3 minigui
cd minigui
2、配置minigui选项。
make menuconfig
system wide options中取消Build MiniGUI-Lite,Use incore (built-in) resource选项。
Gal engine options 图形引擎根据目标机的显示方式确认,我用三星的S3C2410只勾选了 NEWGal engine on Linux FrameBuffer console,其它的不选。
Ial engine options 输入引擎我可用触摸屏所以只选了SMDK2410 Touch Screen。
Font Options 中取消选择Var bitmap font ,可能是因为为Bug的原因,当选择了该选项后,编译测试例子的时候总是提示vbfcon …错误。
Image options 我只选择了Includes SaveBitmap-related functions。其它图形格式我没有选择。
Development environment options 我使用Linux平台,arm-linux-gcc编译器,安装路径设置在~/mingui/target
退出配置界面,提示是否保存配置,选是。
3、 译minigui
make
make install
如果编译成功,将在目标文件夹~/mingui/target下面生成include、lib、etc三个文件夹。
4、 编译测试例子guitest.c,代码如下
#include <stdio.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#ifndef _LITE_VERSION
#include <minigui/dti.c>
#endif
static int TestWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
switch (message)
{
case MSG_PAINT:
hdc = BeginPaint (hWnd);
TextOut(hdc,100,100,"hello/n!");
EndPaint(hWnd,hdc);
return 0;
case MSG_CLOSE:
DestroyMainWindow (hWnd);
PostQuitMessage (hWnd);
return 0;
}
return DefaultMainWinProc(hWnd, message, wParam, lParam);
}
void InitCreateInfo(MAINWINCREATE * pCreateInfo)
{
pCreateInfo->dwStyle = WS_CAPTION|WS_VISIBLE;
pCreateInfo->dwExStyle = WS_EX_NONE;
pCreateInfo->spCaption = "Hello world!";
pCreateInfo->hMenu = 0;
pCreateInfo->hCursor = GetSystemCursor(0);
pCreateInfo->hIcon = 0;
pCreateInfo->MainWindowProc = TestWinProc;
pCreateInfo->lx = 0;
pCreateInfo->ty = 0;
pCreateInfo->rx = 319;
pCreateInfo->by = 239;
pCreateInfo->iBkColor = PIXEL_lightwhite;
pCreateInfo->dwAddData = 0;
pCreateInfo->hHosting = HWND_DESKTOP;
}
int MiniGUIMain (int argc, const char* argv[])
{
MSG Msg;
HWND hMainWnd;
MAINWINCREATE CreateInfo;
#ifdef _LITE_VERSION
SetDesktopRect(0, 0, 240, 320);
#endif
InitCreateInfo(&CreateInfo);
hMainWnd = CreateMainWindow (&CreateInfo);
printf ("The main window created./n");
if (hMainWnd == HWND_INVALID)
return -1;
ShowWindow(hMainWnd, SW_SHOWNORMAL);
printf ("The main window showed./n");
while (GetMessage(&Msg, hMainWnd)) {
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
MainWindowThreadCleanup (hMainWnd);
return 0;
}
arm-linux-gcc -o guitest guitest.c -I/usr/local/arm/2.95.3/arm-linux/include -lminigui -lpthread –I~/mingui/target/include -L~/mingui/target/lib
5、 调整~/mingui/target/etc/MiniGUI.cfg配置文件。我的如下
[system]
# GAL engine
gal_engine=fbcon
# IAL engine
ial_engine=SMDK2410
mdev==/dev/touchscreen/0raw
mtype=none
上面/dev/touchscreen/0raw是触摸屏的驱动,mtype是键盘驱动,我没有使用。
6、 将~/mingui/target/lib 下面的MiniGUI库文件复制到目标平台的/lib下面,把~/mingui/target/etc下面的MiniGUI.cfg复制到目标平台的/etc下面。这样,MiniGUI就算是在目标机上安装好了。
7、 其它问题。
由于我使用的7”液晶屏是800X480,而1.33版本的MiniGUI不支持这一分辨率。需要修改~/minigui/mingui/src/newgal/fbcon/fbvideo.c文件,加入这个分辨率。
static const GAL_Rect checkres[] = {
{ 0, 0, 1600, 1200 }, /* 16 bpp: 0x11E, or 286 */
{ 0, 0, 1408, 1056 }, /* 16 bpp: 0x19A, or 410 */
{ 0, 0, 1280, 1024 }, /* 16 bpp: 0x11A, or 282 */
{ 0, 0, 1152, 864 }, /* 16 bpp: 0x192, or 402 */
{ 0, 0, 1024, 768 }, /* 16 bpp: 0x117, or 279 */
{ 0, 0, 960, 720 }, /* 16 bpp: 0x18A, or 394 */
{ 0, 0, 800, 600 }, /* 16 bpp: 0x114, or 276 */
{ 0, 0, 800, 480 }, /* 新添加的800X480 */
{ 0, 0, 768, 576 }, /* 16 bpp: 0x182, or 386 */
{ 0, 0, 640, 480 }, /* 16 bpp: 0x111, or 273 */
{ 0, 0, 640, 400 }, /* 8 bpp: 0x100, or 256 */
{ 0, 0, 512, 384 },
{ 0, 0, 320, 240 },
{ 0, 0, 320, 200 },
{ 0, 0, 240, 320 },
{ 0, 0, 160, 160 },
{ 0, 0, 60, 60 }
};
static const struct {
int xres;
int yres;
int pixclock;
int left;
int right;
int upper;
int lower;
int hslen;
int vslen;
int sync;
int vmode;
} vesa_timings[] = {
#ifdef USE_VESA_TIMINGS /* Only tested on Matrox Millenium I */
{ 640, 400, 39771, 48, 16, 39, 8, 96, 2, 2, 0 }, /* 70 Hz */
{ 640, 480, 39683, 48, 16, 33, 10, 96, 2, 0, 0 }, /* 60 Hz */
{ 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */
{ 800, 600, 24038, 144, 24, 28, 8, 112, 6, 0, 0 }, /* 60 Hz */
{ 960, 720, 17686, 144, 24, 28, 8, 112, 4, 0, 0 }, /* 60 Hz */
{ 1024, 768, 15386, 160, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */
{ 1152, 864, 12286, 192, 32, 30, 4, 128, 4, 0, 0 }, /* 60 Hz */
{ 1280, 1024, 9369, 224, 32, 32, 4, 136, 4, 0, 0 }, /* 60 Hz */
{ 1408, 1056, 8214, 256, 40, 32, 5, 144, 5, 0, 0 }, /* 60 Hz */
{ 1600, 1200,/*?*/0, 272, 48, 32, 5, 152, 5, 0, 0 }, /* 60 Hz */
#else
/* You can generate these timings from your XF86Config file using
the 'modeline2fb' perl script included with the fbset package.
These timings were generated for Matrox Millenium I, 15" monitor.
*/
{ 320, 200, 79440, 16, 16, 20, 4, 48, 1, 0, 2 }, /* 70 Hz */
{ 320, 240, 63492, 16, 16, 16, 4, 48, 2, 0, 2 }, /* 72 Hz */
{ 512, 384, 49603, 48, 16, 16, 1, 64, 3, 0, 0 }, /* 78 Hz */
{ 640, 400, 31746, 96, 32, 41, 1, 64, 3, 2, 0 }, /* 85 Hz */
{ 640, 480, 31746, 120, 16, 16, 1, 64, 3, 0, 0 }, /* 75 Hz */
{ 768, 576, 26101, 144, 16, 28, 6, 112, 4, 0, 0 }, /* 60 Hz */
{ 800, 480, 39721, 64, 56, 23, 37, 120, 6, 3, 0 }, /*新添加的800X480 39721 是显示每像素时钟*/
{ 800, 600, 20000, 64, 56, 23, 37, 120, 6, 3, 0 }, /* 72 Hz */
像素时钟请参考显示驱动程序,远峰的显示驱动文件是drivers/video/s3c2440fb.c文件。
MiniGUI的触摸屏驱动可能也需要调整。我是用MiniGUI1.62版下面远峰带embest2410.c和embest2410.h拷贝到~/minigui/mingui/src/ial,将替换掉原2410.c和2410.h文件并对2410.c进行修改。如下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#ifdef _SMDK2410_IAL
#include <unistd.h>
#include <fcntl.h>
#define TS_DEVICE "/dev/touchscreen/0raw"
#include <sys/select.h>
#include "ial.h"
#include "2410.h"
/* for data reading from /dev/keyboard/0raw */
typedef struct {
short b;
short x;
short y;
short pad;
} POS;
static int ts = -1;
static int btn_fd = -1;
static unsigned char state[NR_KEYS];
static unsigned char btn_state=0;
static unsigned char keycode_scancode[MAX_KEYPAD_CODE + 1];
static int numlock = 0;
static int mousex = 0;
static int mousey = 0;
static POS pos;
#undef _DEBUG
/************************ Low Level Input Operations **********************/
/*
* Mouse operations -- Event
*/
static int mouse_update(void)
{
return 1;
}
static void mouse_getxy(int *x, int* y)
{
*x = mousex;
*y = mousey;
}
static int mouse_getbutton(void)
{
return pos.b;
}
#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;
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)) {
short data [4];
FD_CLR (ts, in);
read (ts, data, sizeof (data));
if (data[0]) {
pos.x = data[1];
pos.y = data[2];
printf ("posx = %d, posy = %d/n", pos.x, pos.y);
mousex = (pos.x - 100) * 800 / (931 - 100);
mousey = (pos.y - 835) * 480 / (191 - 835); /*这里是修正,说明见下*/
}
#ifdef _DEBUG
if (data[0]) {
printf ("mouse down: pos.x = %d, pos.y = %d/n", pos.x, pos.y);
}
#endif
pos.b = (data[0] ? 4 : 0);
retvalue |= IAL_MOUSEEVENT;
}
} else if (e < 0) {
return -1;
}
return retvalue;
}
BOOL Init2410Input (INPUT* input, const char* mdev, const char* mtype)
{
ts = open (TS_DEVICE, O_RDONLY | O_NONBLOCK);
if (ts < 0) {
fprintf (stderr, "EMBEST2410: 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;
pos.x = pos.y = pos.b = 0;
return TRUE;
}
void Term2410Input (void)
{
if (ts >= 0)
close(ts);
if (btn_fd >= 0)
close(btn_fd);
}
#endif /* _EMBEST2410_IAL */
坐标修正值可以打开MiniGUI的调试取得,在Make menuconfig时,system wide options里有打开调试信息的选项。
关尚明
2006年2月16日