淺談MiniGUI的VxWorks環(huán)境移植
首先,需要準(zhǔn)備好MiniGUI1.6.10的庫(kù)文件,和一些示例文件,可以到MiniGUI.org上下載.(可能我機(jī)器上的版本和下載的開(kāi)源版本不一樣,但是這個(gè)文章寫(xiě)出來(lái)就是為了備忘的。所以以我自己的版本為主介紹)
1. Cygwin環(huán)境安裝
這個(gè)就不多說(shuō)了,windows上很有名的模擬linux平臺(tái)的工具軟件。可以很方便的下載到。安裝的時(shí)候注意安裝make, vim兩個(gè)東西即可。
2. 在cygwin上交叉編譯MiniGUI的產(chǎn)品
由于我這里的目標(biāo)板是mips的核,那我就以mips為例:
MiniGUI源代碼中編譯文件:
makefile.ng是用來(lái)VxWorks的編譯的文件.打開(kāi)這個(gè)文件可以看到include rules.make,打開(kāi)rules.make文件,可以看到這個(gè)文件中做了一些相關(guān)的設(shè)置。注意第一句TARGET_RULES=build/rules-mipse.vxworks。看來(lái)用的定義是放在這個(gè)build/rules-mipse.vxworks文件中的,那我再打開(kāi)這個(gè)文件。
這個(gè)文件中有幾個(gè)定義需要注意:
1.PREFIX:這個(gè)地方定義了編譯好的MiniGUI庫(kù)文件和頭文件放置的位置
2.TARGET_DIR:這個(gè)地方定義了tornado工具安裝的路徑,方便尋找vxworks的庫(kù)文件和交叉編譯鏈工具
3.CFLAGS:定義了MiniGUI編譯時(shí)候的參數(shù),有類(lèi)似下面的參數(shù)
-g -mips3 -EL -D__LITTLE_ENDIAN__ -Wall -DTOOL_FAMILY=gnu -DTOOL=gnu -D_WRS_KERNEL -DMIPSEL -DCPU=MIPS64 -D__mips__ -D__MIPSEL__
我們需要注意修改的地方有兩個(gè)
-D__LITTLE_ENDIAN__ 大小端,根據(jù)不同的客戶(hù)機(jī)有不同的要求,可能是__BIG__ENDIAN__ __LITTLE_ENDIAN__
-DCPU=MIPS64 cpu類(lèi)型:也需要根據(jù)不同的客戶(hù)機(jī)的要求,MIPS64 MIPS32等
上面的內(nèi)容都設(shè)置好了之后,我們還需要根據(jù)板子不同需要做一些代碼定制,如下:關(guān)閉鼠標(biāo),關(guān)閉png,jpeg,commlcd(為了排除問(wèn)題,只打開(kāi)dummy 引擎);打開(kāi)DUMMY引擎。
也就是注釋掉:……_CURSOR_SUPPORT 1……
……_PNG_FILE_SUPPORT 1……
……_JEPG_FILE_SUPPORT 1……
修改配置
vim src/sysres/mgetc-vxi386.c
修改為:
static char *SYSTEM_VALUES[]={"dummy","dummy","/dev/ts","none"};
下面我們就可以進(jìn)行交叉編譯了:
交叉編譯時(shí),必須使用cygwin內(nèi)置的make命令來(lái)編譯。所以輸入如下
$/bin/make -f makefile.ng clean
$/bin/make -f makefile.ng
$/bin/make -f makefile.ng install
編譯完成后,就可以在已經(jīng)定義好的目錄下找到編譯好的libMiniGUI.a文件和MiniGUI相關(guān)的頭文件.
3. tornado產(chǎn)品上運(yùn)行編譯出來(lái)的MiniGUI示例
還記得上個(gè)文章說(shuō)到怎么創(chuàng)建項(xiàng)目吧。那我們新創(chuàng)建一個(gè)項(xiàng)目,這里有幾點(diǎn)需要注意
◆如果我們是對(duì)一個(gè)已經(jīng)編譯好內(nèi)核的板子來(lái)說(shuō)。我們需要準(zhǔn)備好這個(gè)內(nèi)核文件,方便 我們寫(xiě)好的程序downloading到板子上
◆如果是一個(gè)已經(jīng)編譯好內(nèi)核的板子,我們就只需要建立一個(gè)downloadable的應(yīng)用程序就可以了。
◆我們?cè)谶x擇toolchain的設(shè)置的時(shí)候(如圖),需要按照不同的板子環(huán)境設(shè)置不同的toolchain,這里必須注意的是剛才編譯MiniGUI設(shè)置的CPU和大小端的內(nèi)容,必須和這里選擇的一樣。
先給出一個(gè)MiniGUI的helloworld實(shí)例
Code
1 /*
2 ** $Id: helloworld.c,v 1.38 2007-10-25 07:56:45 weiym Exp $
3 **
4 ** Listing 2.1
5 **
6 ** helloworld.c: Sample program for MiniGUI Programming Guide
7 ** The first MiniGUI application.
8 **
9 ** Copyright (C) 2004 ~ 2007 Feynman Software.
10 **
11 ** License: GPL
12 */
13 #include <stdio.h>
14 #include <string.h>
15 #include <MiniGUI/common.h>
16 #include <MiniGUI/MiniGUI.h>
17 #include <MiniGUI/gdi.h>
18 #include <MiniGUI/window.h>
19 #include <MiniGUI/mywindows.h>
20 static char welcome_text [512];
21 static char msg_text [256];
22 static RECT welcome_rc = {10, 100, 600, 400};
23 static RECT msg_rc = {10, 100, 600, 400};
24 static const char* syskey = "";
25 static int last_key = -1;
26 static int last_key_count = 0;
27 static void make_welcome_text (void)
28 {
29 const char* sys_charset = GetSysCharset (TRUE);
30 const char* format;
31 if (sys_charset == NULL)
32 sys_charset = GetSysCharset (FALSE);
33 SetRect (&welcome_rc, 10, 10, g_rcScr.right - 10, g_rcScr.bottom / 2 - 10);
34 SetRect (&msg_rc, 10, welcome_rc.bottom + 10, g_rcScr.right - 10, g_rcScr.bottom - 20);
35 if (strcmp (sys_charset, FONT_CHARSET_GB2312_0) == 0
36 || strcmp (sys_charset, FONT_CHARSET_GBK) == 0) {
37 format = "歡迎來(lái)到 MiniGUI 的世界! 如果您能看到該文本, 則說(shuō)明 MiniGUI Version %d.%d.%d 可在該硬件上運(yùn)行!";
38 }
39 else if (strcmp (sys_charset, FONT_CHARSET_BIG5) == 0) {
40 format = "歡迎來(lái)到 MiniGUI 的世界! 如果您能看到該文本, 則說(shuō)明 MiniGUI Version %d.%d.%d 可在該硬件上運(yùn)行!";
41 }
42 else {
43 format = "Welcome to the world of MiniGUI. \nIf you can see this text, MiniGUI Version %d.%d.%d can run on this hardware board.";
44 }
45 sprintf (welcome_text, format, MiniGUI_MAJOR_VERSION, MiniGUI_MINOR_VERSION, MiniGUI_MICRO_VERSION);
46 strcpy (msg_text, "No message so far.");
47 }
48 static int HelloWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
49 {
50 HDC hdc;
51 syskey = "";
52 switch (message) {
53 case MSG_CREATE:
54 make_welcome_text ();
55 SetTimer (hWnd, 100, 200);
56 break;
57 case MSG_TIMER:
58 sprintf (msg_text, "Timer expired, current tick count: %ul.",
59 GetTickCount ());
60 InvalidateRect (hWnd, &msg_rc, TRUE);
61 printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");
62 break;
63
64 case MSG_LBUTTONDOWN:
65 strcpy (msg_text, "The left button pressed.");
66 InvalidateRect (hWnd, &msg_rc, TRUE);
67 break;
68 case MSG_LBUTTONUP:
69 strcpy (msg_text, "The left button released.");
70 InvalidateRect (hWnd, &msg_rc, TRUE);
71 break;
72 case MSG_RBUTTONDOWN:
73 strcpy (msg_text, "The right button pressed.");
74 InvalidateRect (hWnd, &msg_rc, TRUE);
75 break;
76 case MSG_RBUTTONUP:
77 strcpy (msg_text, "The right button released.");
78 InvalidateRect (hWnd, &msg_rc, TRUE);
79 break;
80 case MSG_PAINT:
81 hdc = BeginPaint (hWnd);
82 DrawText (hdc, welcome_text, -1, &welcome_rc, DT_LEFT | DT_WORDBREAK);
83 DrawText (hdc, msg_text, -1, &msg_rc, DT_LEFT | DT_WORDBREAK);
84 EndPaint (hWnd, hdc);
85 return 0;
86 case MSG_SYSKEYDOWN:
87 syskey = "sys";
88 case MSG_KEYDOWN:
89 if(last_key == wParam)
90 last_key_count++;
91 else
92 {
93 last_key = wParam;
94 last_key_count = 1;
95 }
96 sprintf (msg_text, "The %d %skey pressed %d times",
97 wParam - 1, syskey, last_key_count);
98 InvalidateRect (hWnd, &msg_rc, TRUE);
99 return 0;
100 case MSG_KEYLONGPRESS:
101 sprintf (msg_text, "=======The %d key pressed over a long term", wParam);
102 InvalidateRect (hWnd, &msg_rc, TRUE);
103 break;
104 case MSG_KEYALWAYSPRESS:
105 sprintf (msg_text, "=======The %d key pressed always", wParam);
106 InvalidateRect (hWnd, &msg_rc, TRUE);
107 break;
108 case MSG_KEYUP:
109 sprintf (msg_text, "The %d key released", wParam - 1);
110 InvalidateRect (hWnd, &msg_rc, TRUE);
111 return 0;
112 case MSG_CLOSE:
113 KillTimer (hWnd, 100);
114 DestroyMainWindow (hWnd);
115 PostQuitMessage (hWnd);
116 return 0;
117 }
118 return DefaultMainWinProc(hWnd, message, wParam, lParam);
119 }
120 int MiniGUIMain (int argc, const char* argv[])
121 {
122 MSG Msg;
123 HWND hMainWnd;
124 MAINWINCREATE CreateInfo;
125 #ifdef _MGRM_PROCESSES
126 JoinLayer(NAME_DEF_LAYER , "helloworld" , 0 , 0);
127 #endif
128 CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;
129 CreateInfo.dwExStyle = WS_EX_NONE;
130 CreateInfo.spCaption = "Hello, world!";
131 CreateInfo.hMenu = 0;
132 CreateInfo.hCursor = GetSystemCursor(0);
133 CreateInfo.hIcon = 0;
134 CreateInfo.MainWindowProc = HelloWinProc;
135 CreateInfo.lx = 0;
136 CreateInfo.ty = 0;
137 CreateInfo.rx = g_rcScr.right;
138 CreateInfo.by = g_rcScr.bottom;
139 CreateInfo.iBkColor = COLOR_lightwhite;
140 CreateInfo.dwAddData = 0;
141 CreateInfo.hHosting = HWND_DESKTOP;
142
143 hMainWnd = CreateMainWindow (&CreateInfo);
144
145 if (hMainWnd == HWND_INVALID)
146 return -1;
147 ShowWindow(hMainWnd, SW_SHOWNORMAL);
148 while (GetMessage(&Msg, hMainWnd)) {
149 TranslateMessage(&Msg);
150 DispatchMessage(&Msg);
151 }
152 MainWindowThreadCleanup (hMainWnd);
153 return 0;
154 }
155 #ifndef _LITE_VERSION
156 #include <MiniGUI/dti.c>
157 #endif
158
把這個(gè)實(shí)例添加到新建的tornado項(xiàng)目中,假設(shè)命名為helloworld.c文件,接下來(lái),就需要把MiniGUI的頭文件路徑和庫(kù)文件給鏈接到tornado的項(xiàng)目中.
打開(kāi)tornado的workspace窗口中的build標(biāo)簽,我們?cè)谶@里面設(shè)置MiniGUI的頭文件和鏈接文件
1)雙擊demo builds下面的MIPS64gnule。
2)在打開(kāi)的窗口中選擇c/c++ compile tag
這里有tornado在編譯的時(shí)候使用的參數(shù),
首先我們要?jiǎng)h除-ansi, MiniGUI在開(kāi)發(fā)的過(guò)程中,一些代碼中沒(méi)有按照ansi標(biāo)準(zhǔn),所以我們需要先刪除這個(gè)參數(shù)。
然后, 我們可以像使用gcc編譯選項(xiàng)的參數(shù)一樣加入我們的頭文件路徑,或者通過(guò)下面的“Include path...”按鈕來(lái)添加
-IC:/cross/mipse/include
3)添加鏈接,這里注意不是在link標(biāo)簽下,是在Macro宏標(biāo)簽下添加
打開(kāi)PRJ_LIBS宏,把庫(kù)文件路徑復(fù)制到value值里,然后按“add/set...”按鈕
C:/cross/mipse/lib/libMiniGUI.a
這樣,我們就把MiniGUI的庫(kù)文件鏈接上了,而且也加好了MiniGUI的頭文件路徑.
下面,我們就可以編譯我們剛寫(xiě)的MiniGUI的helloworld程序了。
4)設(shè)置目標(biāo)板
現(xiàn)在我們需要連接上我們的目標(biāo)版上的vxworks系統(tǒng),把我們編譯好的程序燒上去了。首先,在菜單tools->target server...的選項(xiàng)中選擇configure,新建一個(gè)configuration,修改了configuration默認(rèn)的名稱(chēng)后,選擇target server properties下拉菜單,選擇core file and symbols,然后指定file路徑,這個(gè)所說(shuō)的file就是前面提醒大家準(zhǔn)備好的vxworks的內(nèi)核文件"vxWorks"
然后在target server中填入本機(jī)的ip地址, 在target name/IP address里面填入目標(biāo)板的ip地址,確認(rèn)。這時(shí)主界面的toolbar中的combobox里面就可以選擇當(dāng)前的這個(gè)配置了。選中當(dāng)前的配置后,就可以嘗試啟動(dòng)鏈接了
5)讓我們的MiniGUI程序跑起來(lái)
目標(biāo)板設(shè)置完成之后,我們可以把編譯好的download到目標(biāo)機(jī)器上,啟動(dòng)windsh,敲入MiniGUI_entry,就可以把剛才燒入的helloworld跑起來(lái)了~
【編輯推薦】