楊立身,張安偉,王 磊,劉 康
(河南理工大學 計算機科學與技術學院,河南 焦作 454000)
隨著計算機與電子信息技術的快速發展、嵌入式MCU的價格越來越低性能越來越強大,嵌入式系統應用與研究不斷深入,已遍及通訊、汽車電子、醫學、導航、工業控制等眾多領域。基于Cortex-M3內核的STM32系列MCU作為其中的一個代表,以其低廉的價格、優異的性能,在各個領域也得到了廣泛的應用[1]。同時,嵌入式產品向著智能化、集成化、人性化發展,圖形化界面的人機接口以及并發的多任務顯得越來越重要,嵌入式實時操作系統μC/OS_II及嵌入式圖形軟件μC/GUI以其占用資源少、高性能、高可靠性等優點在嵌入式圖形開發中應用的也越來越多,液晶顯示系統作為嵌入式的主要直觀交互設備有著非常重要的作用。因此,通過移植整合μC/OS_II與μC/GUI配合液晶顯示設備來進行多任務、可視化的軟件開發會在以后的開發過程中扮演著重要角色。
文章主要研究了μC/OS_II與μC/GUI在ILI9320LCD、STM32F103X系列處理器基礎上的整合移植方法,同時針對μC/GUI對中文支持欠缺的不足增加了對中文的支持,并對μC/GUI的底層顯示接口函數進行了優化,提升了性能。
μC/OS_II是一個完整的、可移植、裁剪的搶占式實時多任務內核,并以其實時性強、高效而小巧等優點得到了比較廣泛的應用[2-3]。其絕大部分代碼用C語言編寫而成,具有執行效率高、占用空間小、實時性能優良等特點,可以運行在目前絕大多數的微處理器上。μC/OS_II提供了包含任務管理、時間管理、內存管理、信號量管理等在內的基本功能,具有很高的安全性與穩定性,并且得到了FAA的認證,在世界范圍內被廣泛使用。
μC/GUI是Micrium公司出品的一種專用于嵌入式應用的圖形支持軟件[4],它能為任何使用一個圖形LCD提供一個不依賴于處理器和LCD控制器的圖形用戶接口。μC/GU采用了模塊化設計,由在不同模塊中的不同層組成,適用于任何LCD控制器和CPU的任何尺寸的物理和虛擬顯示,它采用標準C代碼編寫,適用于任何CPU。μC/GUI具有適用于嵌入式系統的高性能、高可靠性、可移植、可配置等特點,可根據實際要求對μC/GUI進行組件裁剪,其最小系統只需要很小的內存空間即可運行[5-6]。
硬件平臺核心芯片選用STM32F10RBT6,該芯片集成20KSRAM、128KB FLASH、2個SPI接口、3個USART異步串行總線接口、2個12位ADC模數轉換器、通過內置的向量中斷控制器NVIC,支持43個可屏蔽中斷請求,且具有很低的中斷延時[7-8]。
LCD模塊選用顯尚光電的DST2001PH TFT-LCD,控制IC型號為ILI9320,采用26萬色的TFT-LCD屏,分辨率為320×240,同時該模塊自帶4導線制XPT2046觸摸屏控制芯片,內含12位分辨率125kHz轉換速率逐步逼近型AD轉換器[9-11],支持觸摸操作。
軟件平臺采用 Keil uVision v4.10集成開發環境,提供了包含C編譯器、庫管理、和功能強大的仿真調試器在內的完整開發方案,采用STM32 V3.5固件庫開發,避免了直接操作寄存器,便于學習與開發。μC/OS_II選用的版本為μC/OS_II V2.86,μC/GUI所選版本為μC/GUI V3.90。
要使μC/OS_II正常工作則處理器的C編譯器必須支持數據存儲硬件堆棧、能產生定時中斷為系統提供時鐘,并且處理器需包含從CPU寄存器存取數據的指令。由圖1μC/OS_II組織結構圖可知,移植所需修改的主要是與CPU相關的文件,主要有:os_cpu_a.asm、os_cpu_c.c等。

圖1 μC/OS_II組織結構圖Fig.1 Structure chart ofμC/GUI
OS_CPU_A.ASM主要包含了任務切換、中斷斷點的保存、進出臨界區方法的實現等于CPU密切相關的程序,主要函數有:OSCtrSw()、OSIntCtrSw()、PendSV_Handler()、OS_CPU_SR_Save()、OS_CPU_SR_Restore()等。其中 OSC-trSw()和OSIntCtrSw()函數分別為任務級別任務切換函數和中斷級別任務切換函數,PendSV_Handler()為PendSV中斷服務程序,OS_CPU_SR_Save()和OS_CPU_SR_Restore()為用方法3進入臨界區的實現函數。以上函數需要用匯編語言實現,此部分是移植過程的重點和難點。需要注意的是,任務級任務切換和中斷級別任務切換實則都是通過觸發PendSV中斷來實現的,PendSV_Handler()函數部分代碼如下:

OS_CPU_C.C文件在系統移植的時候需要寫10個函數,其中唯一必要的函數是OSTaskStkInit(),其他9個函數必須聲明,但并不一定要包含任務代碼。操作系統創建任務函數通過調用OSTaskStkInit(),初始化任務的棧結構,使得堆棧看起來就像中斷剛發生過一樣,所有寄存器都保存在堆棧中。OSTaskStkInit()函數部分代碼如下:

μC/OS_II需要一個周期性的信號源自身提供所需時鐘。本文利用STM32F103RBT6自帶的Systick定時器為系統提供一個穩定的周期為10ms的信號源,需要注意的是必須在多任務系統開啟以后再開啟時鐘節拍器。中斷服務函數Systick_Handler代碼如下:

μC/GUI移植涉及3個模塊:μC/GUI配置模塊、μC/OS_II配置模塊、LCD觸摸顯示模塊,如圖2所示。

圖2 μC/GUI體系結構圖Fig.2 Organization chart ofμC/GUI
此模塊修改主要涉及到GUIConf.h文件,該文件的功能主要為按照實際的實驗環境配置μC/GUI的相關支持功能。根據本實驗室要求,開啟多任務、觸摸、支持UNICODE碼、窗口支持、抗鋸齒等功能,其他功能可根據實際情況選擇開啟或關閉,相關代碼如下:

本文的 μC/GUI移植基于 μC/OS_II,μC/OS_II的移植第三部分已經詳細介紹。在μC/OS_II下使用μC/GUI的關鍵是需要內核接口函數來實現多任務之間的同步,通過任務調度使任務之間能協調工作,修改主要集中在GUI_X_uCOS.c文件,需要對 GUI_X_Execldle、GUI_X_Lock、GUI_X_Unlock等系統級函數針對硬件和μC/OS_II進行修改,并添加3個簡單的函數,部分函數代碼如下:

LCD觸摸顯示模塊的移植是整個μC/GUI移植中的難點,μC/GUI提供了一個現成的硬件接口通過調用底層的LCD驅動函數從而實現μC/GUI的圖像功能,同時也提供了觸摸驅動的硬件接口,此時需要針對實際的觸摸層實現進行相應的修改。
5.3.1 LCD驅動
LCD的顯示屏的顯示原理是逐行掃描的掃描方式[12-13]。使用 LCD之前,需要根據其控制IC的DataSheet對屏幕顯示方向、GRAM更新方向、色彩位數、行列GRAM地址位置設置等基礎設置進行初始化,并且需編寫讀寫寄存器函數、讀寫數據函數、設置坐標函數等重要函數。部分初始化函數與重要函數代碼如下:


5.3.2 μC/GUI硬件接口移植
μC/GUI在LCDDriver文件夾中提供了3種LCD 驅 動 模 板:LCDDummy.c 、LCDWin.c、LCDNull.c,可以任選其中一個與自己的LCD驅動進行鏈接,本文選擇了LCDDummy.c,涉及到需修改的文件主要有:LCDConf.h、LCDDummy.c。
該文件為μC/GUI的底層配置文件[14],通過宏定義描述了LCD硬件特性,需根據所選用的LCD屏做相應修改,相關代碼如下:

μC/GUI是通過最基礎的畫點函數來實現畫線、畫圓、位圖等函數的,因此讀寫像素點函數是驅動程序最為重要的函數。μC/GUI里的讀寫像素點函數分別為LCDDummy.c文件中的LCD_L0_GetPixelIndex()和LCD_L0_SetPixelIndex()兩個函數,這兩個函數只是一個框架,μC/GUI在這兩個函數中為真正實現讀寫像素點的函數預留了空間,方便針對各類LCD的移植。本文真正實現讀寫像素點的是底層LCD驅動的LCD_Read-Point()函數和ili9320_SetPoint()函數,這兩個函數需要根據所選用的LCD屏編寫實現,部分代碼如下:


5.3.3 觸摸驅動
本文所選LCD屏內含XPT2046觸控芯片,支持觸摸。觸摸模塊的修改主要集中在GUITouchConf.h、GUI_X_Touch.c文件中。
(1)GUITouchConf.h文件
需要對 GUI_TOUCH_AD_LEFT、GUI_TOUCH_AD_RIGHT、GUI_TOUCH_TOP、GUI_TOUCH_BOTTOM、GUI_TOUCH_SWAP_XY幾個宏定義進行重新賦值,其中前四個宏定義分別表示觸摸屏幕四個邊緣所時得到的AD轉換值,需要注意的是這些值并非所對應的坐標值。屏幕的四個邊緣所對應的AD值需要單獨寫程序實現,具體實現過程不再贅述,GUI_TOUCH_SWAP_XY宏表示的是是否支持XY切換。本文的相關設置如下:

在μC/GUI中實現觸摸功能需要在該文件中實現最為重要的是兩個觸摸屏ADC采樣函數GUI_TOUCH_X_MeasureX()和 GUI_TOUCH_X_MeasureY(),μC/GUI給出了這兩個函數的框架,具體內容的實現需要自己調用底層的觸摸驅動。本文分別調用Read_ADS2_X()和Read_ADS2_Y()兩個獲取XY坐標AD采樣值的底層驅動函數來實現ADC采樣,這兩個函數的實現需要根據所選用的觸摸芯片來重新編寫,部分代碼如下:


6.1.1 μC/GUI字體類型
μC/GUI提供兩種類型的字體,等寬字體(Monospacde Font)和均衡字體(Proportional Font)。等寬字體的寬度和高度都是相同的,所有的點陣數據都存放在一個數組中。而對于均衡字體,由于每個字都有獨自的寬度和高度,則需要通過定義單獨的數組來實現每個字,對于既支持中文和英文的顯示,一般選用的是均衡字體。
老婆忙問:能看出來他氣管里長什么了嗎?段主任說:這哪看的出來?他這種情況,必須住院做個氣管鏡,取出一塊組織,再做個病理,才能知道是什么。一聽要做病理,老婆頓時蒙了,眼圈兒霎時紅潤。王姐忙替老婆問:他這病不重吧?
6.1.2 μC/GUI中文顯示實現
μC/GUI默認只支持英文顯示,不支持中文,通過增加漢字字庫,修改相應的數據結構來實現漢字的顯示。對于等寬字體和均衡字體,兩種字體類型都通過數據結構GUI_FONT來記錄字體的屬性及相關的驅動函數等,GUI_FONT結構體定義了字體大小和GUI_FONT_PROP結構體的入口地址。等寬字體對應的字模數據結構主要是GUI_FONT_MONO,均衡字體相對應的結構體為GUI_FONT_PROP,并且由于每個字都是單獨的數組來表示,所以還需要GUI_CHARINFO來存儲相應的字符信息。GUI_FONT_PROP中包含了字母在字庫中的編碼、字母對應的GUI_CHARINFO結構體入口地址,同時pNext字段指針指向下一個GUI_FONT_PROP結構體,這樣所有的結構體就形成一個單項鏈表,很好的解決了字模數據連續存儲的問題,整體的字庫結構如圖3所示。

圖3 字庫結構圖Fig.3 Organization chart of font library
由于傳統漢字字庫占用存儲空間太大,和單片機內部寶貴的存儲空間矛盾,文章選擇了自定義字庫。自定義字庫選擇字母和工程中使用常用到的漢字,這就避免浪費過多的單片機內部存儲空間。了解字體數據結構知識之后,就可以利用μC/GUI字庫生成器生成指定字體矢量中文的字庫文件了,同時需要在GUI.h文件中聲明所添加的字庫,即 extern GUI_FLASH const GUI_FONT GUI_FontHZ_hpu_font,之后就可以調用μC/GUI顯示函數在液晶屏上顯示相應的字符了。
μC/GUI最為重要且基礎的功能就是畫線、畫圖、矩形填充,對應的函數分別為:LCD_L0_DrawLine函數、DrawBitLine16BPP函數和LCD_L0_FillRect函數,則對這些函數的優化就顯得尤為重要。μC/GUI中這3個函數都是最終調用畫點函數來實現其功能,然后設置一個點坐標填充一個像素點,大量的系統時間浪費在設置坐標上。通常LCD都有自帶的GRAM,在進行像素填充的時候設置好繪圖區,地址指針就會自動增加,而不用填充一個像素點設置一個坐標,這樣就省去了每個像素都要設置坐標的時間。本文利用LCD屏地址指針自動增加的特點對以上幾個函數進行了改寫,并在畫豎線時動態調整R3寄存器的值,使得GRAM內部地址自動增加的方向和畫線方向一致,從而大大提高了屏幕的刷新率。

圖4 實驗結果對比圖Fig.4 Figure of experimental results contrast
本文建立了4個任務用以測試μC/OS_II與μC/GUI協同工作是否正常,同時檢測對中文的支持情況及優化后性能是否提升。任務led1_task和led2_task為led燈任務,控制紅、藍led燈閃爍;touch_task為觸摸任務,用以在LCD上顯示觸摸點的坐標并同時在觸摸位置上顯示鼠標箭頭;gui_task為刷屏任務,用以顯示漢字并在屏幕上半部分以一定的時間間隔填充不同的顏色,用以測試LCD的像素填充率。由圖4的實驗結果對比圖可知,4個任務正常切換,說明μC/OS_II和μC/GUI正常工作,同時像素填充率Piexls/sec提升了大約63%。
文章實現了在STM32F103VCT6上對μC/OS_II和μC/GUI的整合移植并針對μC/GUI中文支持不足和屏幕刷新率過低的問題做出優化,實驗結果表明μC/OS_II與μC/GUI移植整合成功,兩者協同工作正常,中文顯示正常,同時像素填充率由之前的996080/s上升到優化后的1629060/s,提升了大約63%,說明優化帶來了性能的提升。通過將 μC/OS_II、μC/GUI與STM32相結合,初步建立起一個支持多任務的嵌入式圖形應用開發平臺,使得基于STM32的嵌入式應用開發工作更為方便、快捷和直觀。
[1]馬舜峰,金龍旭,安少婷,等.一種基于 ARM9的彩色TFT-LCD模塊設計及實現[J].液晶與顯示,2010,25(5):718-723.Ma S F,Jin L X,An S T,et al.Design and implementation of chromatic TFT-LCD module based on ARM9 [J].Chinese Journal of Liquid Crystals and Displays,2010,25(5):718-723.(in Chinese)
[2]尹作為,郭兵,沈艷.μC/OS_II內核任務模塊調度的擴展[J].計算機應用,2011,31(10):2606-2608.Yin Z W,Guo B,Shen Y.Expansion of task scheduling module inμC/OS_II kernel[J].Journal of Computer Application,2011,31(10):2606-2608.(in Chinese)
[3]曾偉,廖立清.實時操作系統μC/OS_II在DSP上移植的實現[J].計算機工程,2007,33(17):270-272.Zeng W,Liao L Q.Implementation of porting RTOSμC/OS_II to DSP[J].Computer Engineering,2007,33(17):270-272.(in Chinese)
[4]葛欣,孟凡榮.使用μC/GUI開發圖形用戶界面[J].計算機工程與設計,2005,26(1):1-3.Ge X,Meng F R.UsingμC/GUI to develop graphical user interface[J].Computer Engineering and Design,2005,26(1):1-3.(in Chinese)
[5]田志宏,徐軍.嵌入式μC/GUI的移植與平臺開發[J].自動化與儀表,2007(3):76-79.Tian Z H,Xu J.Transplant of embeddedμC/GUI and development of platform [J].Automation &Instrumentation,2007(3):76-79.(in Chinese)
[6]劉濱,劉兵,趙艷華.基于μC/GUI的嵌入式圖形界面設計[J].液晶與顯示,2005,20(6):558-662.Liu B,Liu B,Zhao Y H.Embedded graphical interface design based onμC/GUI[J].Chinese Journal of Liquid Crystals and Displays,2005,20(6):558-662.(in Chinese)
[7]孫林軍,賀鋒濤.基于STM32控制液晶的接口實現[J].電視技術,2013,37(1):77-79.Sun L J,He F T.Implementation of interface based on stm32control LCD [J].Video Engineering,2013,37(1):77-79.(in Chinese)
[8]羅衛兵,胡健生.基于STM32+ucGUI的北斗導航定位系統設計[J].液晶與顯示,2014,29(2):195-201.Luo W B,Hu J S.Design of Beidou navigation system based on STM32&ucGUI[J].Chinese Journal of Liquid Crystals and Displays,2014,29(2):195-201.(in Chinese)
[9]童超,金慶輝,趙建龍.一種用于POCT的嵌入式實時圖像采集處理系統[J].光學精密工程,2008,16(4):720-725.Tong C,Jin Q H,Zhao J L.Novel real time image collection system for point-of-care test[J].Optice and Precision Engineering,2008,16(4):720-725.(in Chinese)
[10]陳健,高慧斌,郭勁,等.數字化單桿控制系統設計[J].光學精密工程,2013,21(11):2844-2851.Chen J,Gao H B,Guo J,et al.Design of digital handle control system [J].Optice and Precision Engineering,2013,21(11):2844-2851.(in Chinese)
[11]褚金奎,陳文靜,王洪青,等.基于偏振光傳感器的移動機器人導航試驗[J].光學精密工程,2011,19(10):2419-2426.Chu J K,Chen W J,Wang H Q,et al.Mobile robot navigation tests with polarization sensors[J].Optice and Precision Engineering,2011,19(10):2419-2426.(in Chinese)
[12]孫之旭,張傳勝.基于SOPC的 TFT液晶顯示驅動控制器[J].液晶與顯示,2012,27(2):212-216.Sun Z X,Zhang C S.Controller for TFT LCD driver based on SOPC [J].Chinese Journal of Liquid Crystals and Displays,2012,27(2):212-216.(in Chinese)
[13]王海霞,武一.基于SOPC的LCD顯示模塊的設計[J].液晶與顯示,2012,27(4):508-514.Wang H X,Wu Y.Design and implementation of LCD module based on SOPC [J].Chinese Journal of Liquid Crystals and Displays,2012,27(4):508-514.(in Chinese)
[14]吳燕燕,賀鋒濤,孫林軍.基于LPC214X平臺的μC/GUI移植研究[J].液晶與顯示,2012,27(3):338-341.Wu Y Y,He F T,Sun L J.Transferability ofμC/GUI on LPC214Xplatform [J].Chinese Journal of Liquid Crystals and Displays,2012,27(3):338-341.(in Chinese)