Global Sources
電子工程專輯
 
電子工程專輯 > 介面技術
 
 
介面技術  

嵌入式系統的人機介面原型設計策略

上網時間: 2003年08月30日     打印版  Bookmark and Share  字型大小:  

關鍵字:User Interface Prototype,人機介面原型,target hardware,目標硬體,GUI,圖形人機介面,C,C++,Borland C++,CPB,software,軟體,Panelform,面板表格,Embedded,嵌入式,code size,程式碼長度,PC,compiler,編譯器,class,類,event driven,事件驅動,object oriented,針對對象,physical prototype,實體原型,bitmap,位圖 

在硬體設計完成之前實現對人機介面的模擬,需要設計工程師在PC上用軟體建構人機介面原型。本文針對建構人機介面原型時所採用的工具語言和程式碼編寫風格,以及不同語言編寫的文件之間的介面問題進行了分析,以提供設計人員有用的參考。

建構一個人機介面原型能夠幫助設計工程師在設計早期理解介面對設計要求和介面的可用性。下面將探討一種當硬體開發還尚未實現時,在PC上建構人機介面原型的方法。建構這類原型的主要目的有二。1. 使同一個設計組中的其他成員能夠看到該設備的工作過程。當我們在紙上設計一台互動式設備時,要判斷設計中所描述的交互性能否實際實現,需要很大的想像力。而如果建構一個工作原型,就會使情況清晰許多,並且允許更多的旁觀者來評論正計畫中的介面設計得怎樣。很多時候,用介面原型進行試驗,還能幫助設計工程師決定真正設計出的硬體需要多少按鈕、多少LED、多少數位顯示器或文件顯示器。2. 當硬體沒有工作時,利用介面原型來為人機介面編寫軟體。為達到這一目的,出現在PC顯示器上的介面原型必須採用C、C++或者其它適用於嵌入式開發的語言來控制。對於其它部份,則可以假設C是用於最終目標硬體的語言。

然後大概考慮一下需要模擬的是哪部份軟體。在最簡單的情況下,軟體可用來打開或關閉一個LED,或者向一個小型字符顯示器輸出一個字符串。控制人機介面上的實體元件只是一項很普通的功能,所以能夠在PC上編寫這種軟體的優點是微不足道的。因為開關一個LED可能只需要一行程式碼,在一個LCD文件顯示器上顯示一個文件字符串也只需要調用一個10行或20行的函數。

真正困難的是如何編寫軟體來決定究竟是打開LED還是關閉LED,以及決定顯示什麼字符串。例如,當一個被測感測器的值持續超過警戒線一段時間,而一組使警戒有效的條件也滿足了之後,軟體也許應選擇打開LED。再如,當用戶按下一個按鈕來選擇選單中的下一項時,軟體也許應查閱一個描述該選單的字符串表和作業表,以決定下一個顯示的應該是哪一項。這種控制選單之類的軟體,其程式碼長度就會超過底層軟體。

在本例中,我們的目的是編寫一個文件顯示和LED控制的模擬軟體,以表示PC螢幕的變化。我們可以編寫警戒檢查程式碼和選單控制程式碼,使其既能執行在PC上,又能執行在目標設備上。

這種模擬的方法並不新穎。但在為諸如PDA和遊戲機之類並沒有自己的開發環境的目標設備上編寫軟體時,通常需要用到這種方法。

編寫模擬軟體所需的工具

用Visual Basic在PC上顯示幾個按鈕和兩行文件並不困難,但當將該原型與C程式碼介面時,就會顯得十分麻煩。

如今有許多針對嵌入式開發的原型編寫工具,用這些工具往往會迫使設計工程師依賴於它們的事件模型,因而導致設計過多地依賴這些工具。如果設計工程師遵從它們的介面設計風格,那麼這些工具確實可以產生程式碼,但它們並不是對所有平台都具備足夠的靈活度,而且它們產生的程式碼可能並不適合小型的微控制器。

我所採用的工具是Borland C++(後面將簡寫為CPB)。Borland C++並不是專門配合嵌入式系統的軟體編寫工具,但我發現它非常適合設計需要,而且採用Borland C++不會將設計束縛在任何一個處理器或者任何一種軟體結構上。

CPB中有一組預定義的圖形組件,其中大多數並非針對嵌入式計畫,而是針對桌面應用(類似下拉選單)。但還是有一個小的子組件適用於我們本文所述的目的。像LED這樣的UI元素就可以用圖像來模擬。

CPB有三種版本:標準版、專業版和企業版。對於我們將要討論的介面而言,標準版已經足夠。

按鈕、滑動塊、標籤和其它UI元素均可透過drag-and-drop環境插入一個表格(一個簡單的對話窗口)中去。產生一個這樣的表格就會產生一個C++類的框架。例如,每當用戶點選一個圖像或行動一個滑動塊時,都會產生一組事件,而該表格中的每個元素都有這樣一組事件與其對應。究竟需要對哪些事件作出反映則由程式員來選擇。這些響應就被寫成該表格所產生的類的成員函數。

如果前面板是由一個產業設計小組設計,那麼就會有整個顯示圖像可供利用。或者如果實體原型已經存在,那麼一幅該實體原型的數位相片就可以用來作為背景。

我採用圖像目標(在CPB內也叫作Timage)來顯示大多數實體元件。因為採用了圖像目標就可以導入位圖,然後進行顯示。例如可以導入一個發光二極體的圖像。在該應用中,顯示了一個包含5個按鈕和4個LED的介面原圖,如圖1所示。背景圖像中LED處於切斷狀態。一旦軟體決定其中的一個LED應打開,那麼這個發光LED圖像的可見屬性就被設為真,於是點亮的LED圖像就覆蓋了不亮的LED圖像。

有了這種簡單的重疊多幅圖像的訣竅,我們就可以模擬一個實體顯示螢幕的其它部份。例如,假設我們採用CPB IDE來製作一個包含單詞‘ALARM’的標註,並將這一元素命名為AlarmIndicator,那麼我們就可以編寫一個函數來控制它:

void setAlarmState(Boolean state)


{


PanelForm->AlarmIndicator


->Visible = state;


}

面板表格中包含了我們模擬時所用到的所有圖形對象。Alarm-Indicator就是我們將一個標籤放到面板表格上之後為其分配的名字。當我們將該標籤透過拖拽到表格窗口中的方式加入該表格時,它就成為了該表格的一個數據成員。

在CPB中,顯示螢幕上的一個元素的所有屬性都可以作為表徵該元素的類的公共數據成員。因此,Visible屬性只需進行一個簡單的分配作業就能改變。公共數據成員可以在程式中的任何地方透過分配而改變。在CPB中,各屬性也有其特殊狀態,允許在IDE中透過該狀態改變屬性。開發者可以點選一個標注,並在屬性窗口設置Visible屬性。顯示的顏色和字體也可以透過類似的方法改變。

現在來看一個setAlarmState()程式,該程式用於驅動基於CPB的模擬。以下程式碼為CPB專用程式碼,在最終的目標上無法執行。不用多久,我們將不得不為目標介面編寫該函數的另一個版本,形式如下:


void setAlarmState(Boolean state)


{


if (state)


{


ledRegister |= 0x02;


}


else


{


ledRegister &= ~0x02;


}


}

有時,編程的風格會導致一些小函數造成函數調用開銷。在較小的系統中這一問題較受關注,而這些函數中有一些可以寫成巨集或者內聯(inline)函數。我通常只在計畫的最後階段才開始進行這類最佳化。

程式碼的組織

如果我們已經編寫了兩個版本的setAlarm-State()函數,那麼我們必須保證一次只編譯其中的一個。要達到這一目的,一種方法是一直採用CPB程式碼,直到目標硬體設計好之後,再用目標專用的程式碼代替其中所有CPB專用的程式碼。如果我們這樣做,那麼在我們開始目標硬體的開發工作之後,就無法再執行模擬了。讀者可能認為這不是什麼問題,但事實上,即使硬體設計好之後,模擬也是有用的。

例如,模擬中基於PC的除錯環境往往就比目標硬體的開發環境要好。因為目標硬體的下載速度可能較慢,或者每次修改軟體都必須重新燒錄一塊一次性可程式晶片。而且目標硬體的除錯環境中可能也不支援單步除錯和斷點除錯。即使目標硬體的除錯環境較好,相對而言,PC模擬還是有其它優勢。開發者可以將.exe文件透過電子郵件發送給不在同一工作地點的工作夥伴,以獲得他們的反饋資訊。

一旦開發者決定要在整個計畫的開發周期中同時保留兩個版本的函數,那麼分隔它們就很容易。在CPB中的Project/Options下,可以定義巨集。我通常會定義USING_CPB,然後在我的原始程式碼中,利用一個#ifdef來區分不同的函數版本。另一種區分函數版本的方法就是將目標程式碼和模擬程式碼存放在不同的文件中,但讓二者共享同一個頭文件,以保證二者採用同樣一組函數標記。

CPB環境是基於C++的一種環境,但許多嵌入式目標幾乎都不支援C。這時,開發者只能採用共享程式碼中由交叉編譯器所支援的C++子集,這其實並沒有想像中的困難。解決該問題的方法之一就是針對嵌入式目標來編譯程式碼,即使目前並沒有硬體可以執行這些程式碼。這時那些在PC上可用的而在目標硬體上則可能屬於非法的特性就顯得突出起來。例如,有些較小型的處理器就不支援遞迴。同時,在嵌入式編譯器上檢查軟體,還能快速地在程式中標出那些偶然被包含進目標可執行文件中的CPB專用程式碼。我本人就發覺這種方法在追蹤軟體的大小時非常有用,因為CPB庫過於龐大,會完全扭曲程式的大小,所以PC中進行編譯時提供的軟體大小並不真實。

這裡採用了三種類型的程式碼。其中有些屬於CPB專用程式碼,只能在PC上編譯;有些屬於目標專用程式碼,只能在目標上編譯;而其它的則屬於公共程式碼,應該既能在PC平台上執行,也能在目標平台上執行。在理想情況下,每個原始文件應該都只包含一種類型的程式碼。設計工程師的IDE或makefile應允許其選擇在每次製作可執行文件時需要包含哪些文件。

建議在命名文件時,將所有CPB專用的文件命名為.cpp文件,所有目標專用的文件和共享文件均取.c為附檔名。那麼在目標環境中編譯時,就只需編譯附檔名為.c的文件,而不編譯附檔名為.cpp的文件。

如果設計工程師遵循以上風格,那麼在CPB環境中編譯時還會遇到一個問題。CPB環境將.c文件假設為C程式碼編寫的文件,而將.cpp文件假設為C++程式碼編寫的文件。當從一個文件到另一個文件產生呼叫時,將會因C++產生破損函數名的方式不同而產生鏈接錯誤。我們可以透過採用‘extern C’構造來迴避這個問題。但這樣有點麻煩,尤其當調用產生在從C到C++或從C++到C時。可以為Borland編譯器設置一個標誌,告訴它,不論文件的附檔名是什麼,均將其作為C++文件來編譯。遺憾的是IDE中沒有這樣的標誌。於是我們只能手工編輯計畫配置文件來實現這一功能。

程式碼舉例

讀者可以在www.panelsoft.com/cpb處找到一個可執行文件five.exe,文件中包含一行5個按鈕和一組LED。按下前4個按鈕中的任何一個都會打開相應的一個LED。第5個按鈕是RESET(重設)按鈕,按下該按鈕會切斷所有LED。當然,在構造這樣一個計畫時,並不需要進行模擬。但該例旨在說明,只要具備初始的介面介面圖像,那麼模擬時,只需稍作努力就可得到與真實設備看起來相似的執行結果。同時,該例還說明,key.c模組中包含的程式碼既可在目標環境中執行,也可在模擬環境中執行,而且該程式碼不會因目標環境和模擬環境這兩種平台之間的差異而需要任何條件程式碼才能執行。用於構造該應用的所主動程式碼和初始位圖均可從該站點下載。

設立類似的模擬需要設計工程師具備一定的C++知識,學習CPB開發環境也需要一定的過程,當設計工程師從未用過這種針對對象的事件驅動環境時尤其如此。然而只要設立起一個模擬,那麼其它工作只需按相同的步驟進行即可。設計工程師如果曾編寫過基於PC的程式,而且程式中用到了GUI,那麼這一經驗會有助於對CPB的學習。我過去就曾利用這樣一個程式來完成過一個簡單的下載應用,實現與嵌入式目標的串列通訊。

作者簡介:

Niall Murphy從事人機介面和醫學系統軟體的設計工作已有10年。他是《Front Panel: Designing Software for Embedded User Interfaces》一書的作者。可透過nmurphy@panelsoft.com與作者聯繫。





投票數:   加入我的最愛
我來評論 - 嵌入式系統的人機介面原型設計策略
評論:  
*  您還能輸入[0]個字
*驗證碼:
 
論壇熱門主題 熱門下載
 •   將邁入40歲的你...存款多少了  •  深入電容觸控技術就從這個問題開始
 •  我有一個數位電源的專利...  •  磷酸鋰鐵電池一問
 •   關於設備商公司的工程師(廠商)薪資前景  •  計算諧振轉換器的同步整流MOSFET功耗損失
 •   Touch sensor & MEMS controller  •  針對智慧電表PLC通訊應用的線路驅動器
 •   下週 深圳 llC 2012 關於PCB免費工具的研討會  •  邏輯閘的應用


EE人生人氣排行
 
返回頁首