基于ulTRON操作系統的嵌入式GUI設計
本設計是在東南大學國家專用集成電路系統工程技術研究中心自主研發的,并在遵循uITRON 3.0標準的RTOS-ASIX OS基礎上設計出一套適合于手持設備、儀器儀表等應用的圖形用戶界面一一ASIX Window。該圖形用戶界面采用面向對象的設計思想,基于消息循環和事件驅動機制,構建了比較完整的窗口系統,為用戶提供了類Win32 API的用戶編程接口。考慮到一般嵌入式應用的屏幕較小,以及嵌入式系統處理器與存儲器容量的限制,ASIX Window在設計上放棄了窗口剪切等復雜特性,大大降低了系統的復雜性,減少了對系統資源的占用。由于采用基于控件的設計概念,ASIX Window非常適合裁減,可以根據用戶的需求方便地增加或刪減控件,增加了系統的可裁減性。該圖形用戶界面已成功應用于PDA,電子詞典,稅控收款機等多款產品設計中。
1 與操作系統內核的接口
ASIX Window的整體架構是基于消息分發,消息循環以及消息處理之上的。整個ASIX OS平臺的結構如圖1所示。圖1中,最底層的是系統的消息源,包括中斷(鍵盤、觸摸屏等)和定時器,一般將它們統稱為中斷源。中斷發生后,進入中斷處理程序,該中斷處理程序維護其對應的緩沖區后(如果它需要緩沖區),設置事件發生(通過調用內核的事件標志系統調用)。因為系統任務是阻塞在這個事件標志上的,而且系統任務的優先級最高,系統任務將被內核調度運行,系統任務根據所發生事件的類型,來進行相應的處理。比如說,如果是筆中斷事件,中斷處理程序將筆的坐標信息存放在相應的緩沖區中,并設置相應的事件標志,系統任務將筆坐標的數據轉換為相應活動區域(Active Area)的消息,并由系統任務將這個消息發送到當前需要該中斷事件的任務中。LCD顯示,鍵盤和筆中斷一定是由前臺任務(擁有屏幕的任務)接管的,其他外圍設備所對應的中斷源則由占用該資源的任務接管。
每個任務都有一個自己的信箱(Mail B0x),在每個信箱上都維護著一條消息隊列,所有發往該任務的消息都連接在這個隊列中。任務代碼應該通過消息循環不斷地從該隊列中取消息并處理,如果消息隊列為空,則該任務阻塞,由ASIX OS內核選擇下一個就緒的高優先級任務運行。
系統任務是內核的擴展,提供系統基本的服務功能和接口。它接管系統所有的中斷資源并將相應的中斷事件翻譯成為相應的系統消息,并將該消息分發到對應的應用程序任務;系統任務同時維護系統中所有任務的信息,負責確定前臺任務(擁有顯示屏幕和用戶輸入焦點的任務,前臺任務不一定是CPU正在運行的任務)以及前臺任務的切換。系統任務阻塞在底層中斷的事件標志上,系統任務擁有最高的優先級。
在系統任務之上是服務任務。服務任務負責提供系統的其他擴展服務。服務任務沒有屏幕顯示(類似于Linux中的守護進程),服務任務阻塞在自己的消息隊列
上。服務任務擁有第二高的優先級。
應用程序任務是用戶使用的各個應用。應用任務阻塞在自己的消息隊列上,所有的應用程序一般都應該擁有屏幕顯示,所有的應用程序在同一優先級上。
2 窗口管理
ASlX Windows是基于消息驅動的圖形用戶接口。從ASIXWindows的角度來看,應用程序是由一組窗口和控件組成的,程序的功能是通過窗口的操作來實現的。控件是在ASIX Windows中定制的具有特定功能的獨立模塊,例如:按鈕、菜單、下拉框、軟鍵盤等。在ASIX Windows中,每一個控件在數據結構上都被描述為一個窗口(也就是說,在數據結構上,窗口和控件是一樣的),不同的是,控件是作為某個窗口的子窗口。在數據結構上將窗口與控件統一,使得整個系統的結構更簡單,對窗口的操作與對控件的操作可以統一到一起,這使得系統的編程接口可以統一到窗口的操作函數上。在ASIX Windows中所有的窗口操作,不管是窗口或是控件,都使用這些統一的函數。系統通過下面這個統一的數據結構來對所有的控件進行管理。
typedef struct asix_window
{ struct asix window *prey}//指向前一個兄弟窗口
struct asix_window *next;//指向后一個兄弟窗口
struct asix_window *child;//指向子窗口鏈表
/*本窗口的相關ID*/
WNDCLASS *wndclass;//指向本窗口的窗口類
U32 task_id; //本窗口所屬任務的任務號
U32 wnd_id; //本窗口ID號
U32 parent_id; //本窗口的父窗口 ID號
/*本窗口的位置、狀態、風格以及窗口標題等*/
U32 status; //本窗口狀態
U16 x; //本窗口左上角x坐標
U16 v; //本窗口左上角Y坐標
U16 width; //本窗口的寬度
U16 hight; //本窗口的高度
char *caption} //本窗口標題
U32 style; //本窗口風格
/*指向本窗口私有數據結構的指針*/
void *etrl_str; //指向本窗口的私有數據結構
}ASIX_WINDOW;
實際上,不同的控件擁有不同的功能和結構,所以它們的操作是不同的。為了擁有統一的操作函數接口,為每一個不同的窗口或控件定義了相應的窗口類,窗口類實際上是每種控件的模版,這個模版定義了與該控件相關的內容。當應用程序員調用CreatWindow函數創建某類控件時,CreatWindow查找該類控件的窗口類,并根據窗口類中的定義,調用與該控件相關的創建函數,進行實際的創建工作。然后CreatWindow填寫相應的數據結構,描述該控件類的實例,并將其鏈接到系統窗口鏈表中去,以便后續的管理。利用窗口類描述不同控件設計的同時,可以將不同控件的開發獨立于系統構架的實現,使得控件的開發可以獨立進行。使用獨立窗口類來描述每個控件的另一個好處是可以非常方便的對ASIX Window進行裁減。下面給出窗口類數據結構的定義。
typedef struct window_class
{ U8 wndclass_id; //窗口類的ID號
//CreateWindow()調用本函數執行控件的具體創建
STATUS (。create)(char‘caption,U32 style,U16 x,
U16 Y,U16 width,U16 hight,U32 wndid,U32 menH,void*
*etrl_str,void*exdata);
//DestroyWindow()調用本函數執行控件的具體刪除
STATUS (*destroy)(void*ctrl_str);
//DefWindowProc()調用本函數進行消息處理
STATUS (。msg_proe)(U32 win_id,U16 asix_msg
評論