S3C2416裸機(jī)開發(fā)系列十四_GCC下UCGUI的移植(2)
掃描二維碼
隨時(shí)隨地手機(jī)看文章
現(xiàn)在主要講解一下在GCC移植UCGUI,Makefile工程如何加入目錄,加入源碼,c標(biāo)準(zhǔn)庫(kù),編譯選項(xiàng)的設(shè)置。
筆者的Makefile模板提取自u(píng)boot,工程中加入目錄,加入源碼都是很簡(jiǎn)單的,詳細(xì)的介紹請(qǐng)參考前面章節(jié)” GCC啟動(dòng)代碼工程應(yīng)用實(shí)例”。下面主要介紹UCGUI目錄下很多的源碼文件Makefile的編寫,一種可行的方式就是把GUI目錄上所有的c文件,不管有無用到,均加入工程進(jìn)行編譯,第一次編譯時(shí)間較長(zhǎng),但以后不用重復(fù)編譯。因此這部分的Makefile實(shí)現(xiàn)如下:
include $(TOPDIR)/config.mk
SRCS := $(wildcard *.c)$(wildcard *.C)
OBJS := $(SRCS:.c=.o)$(SRCS:.C=.o)
CURDIR := $(shell pwd)
FOLDER := $(notdir $(CURDIR))
LIB := lib$(FOLDER).a
.PHONY: all clean
all: .depend $(LIB)
$(LIB): $(OBJS)
@$(AR) $(ARFLAGS) $@ $(OBJS)
clean:
rm -f .depend *.o $(LIB)
#########################################################################
# defines$(obj).depend target
include$(TOPDIR)/rules.mk
sinclude .depend
#########################################################################
把這個(gè)Makefile模板加入到GUI下所有的子目錄和GUIDemo目錄中,其它目錄的Makefile也類似編寫加入,這樣即可把所有要編譯的源碼加入工程。每個(gè)子目錄的Makefile需加入該目錄下要編譯的源碼文件,生成該目錄下的源碼依賴關(guān)系文件.depend,最終生成該目錄下的靜態(tài)庫(kù)文件,以供頂層目錄的Makefile鏈接輸出相應(yīng)的可執(zhí)行代碼文件,工作方式與uboot是完全一致的。
修改頂層目錄的Makefile,加入各個(gè)子目錄Makefile的路徑,以調(diào)用編譯該目錄下的源碼。子目錄路徑SUBDIRS變量的修改如下:
SUBDIRS = $(TOPDIR)/start_code$(TOPDIR)/apps
SUBDIRS += $(TOPDIR)/GUI/AntiAlias$(TOPDIR)/GUI/ConvertColor
$(TOPDIR)/GUI/ConvertMono $(TOPDIR)/GUI/Core
$(TOPDIR)/GUI/Font $(TOPDIR)/GUI/LCDDriver
$(TOPDIR)/GUI/MemDev $(TOPDIR)/GUI/MultiLayer
$(TOPDIR)/GUI/Widget $(TOPDIR)/GUI/WM
SUBDIRS += $(TOPDIR)/GUI_X$(TOPDIR)/GUIDemo
修改頂層目錄的config.mk,對(duì)編譯選項(xiàng)如-O2二級(jí)編譯優(yōu)化或-g加入調(diào)試等進(jìn)行設(shè)置,此處需加入工程c編譯器的頭文件的搜索路徑,對(duì)于UCGUI頭文件搜索路徑只需加入Config、GUI/Core、GUI/Widget、GUI/WM這四個(gè)目錄路徑即可。頭文件搜索路徑CFLAGS變量的修改如下,s3c2416沒有硬件浮點(diǎn)單元,加-msoft-float防止配置成只支持硬浮點(diǎn)的交叉工具通過編譯。
CFLAGS := -Wall -Wstrict-prototypes -mcpu=arm920t -msoft-float
CFLAGS += -I $(TOPDIR)/start_code -I$(TOPDIR)/apps
CFLAGS += -I $(TOPDIR)/GUI/Core -I$(TOPDIR)/GUI/Widget
-I $(TOPDIR)/GUI/WM -I $(TOPDIR)/Config
CFLAGS += -I $(TOPDIR)/GUIDemo
設(shè)置庫(kù),嵌入式開發(fā)很大程度上依賴于標(biāo)準(zhǔn)c庫(kù)。在linux操作系統(tǒng)下,標(biāo)配的c庫(kù)為glibc,glibc囊括了幾乎所有的UNIX通行標(biāo)準(zhǔn),可見其內(nèi)容包羅萬象。因此glibc對(duì)于很多嵌入式系統(tǒng)來說過于臃腫和龐大,并且很多函數(shù)嚴(yán)重依賴于linux的系統(tǒng)調(diào)用。筆者在較老版本交叉編譯工具開發(fā)裸機(jī)代碼,可以鏈接glibc,但新版本的工具卻無法順利鏈接glibc。為了解決glibc在嵌入式應(yīng)用中的不足,很多面向嵌入式的c標(biāo)準(zhǔn)庫(kù)已經(jīng)被開發(fā)出來,如uclibc、newlib、eglibc等。這些嵌入式c庫(kù)特點(diǎn)就是比glibc小很多,相對(duì)獨(dú)立,可不需要操作系統(tǒng)支持,不支持glibc的完整實(shí)現(xiàn),很多功能可以根據(jù)空間需求進(jìn)行取舍。一般開發(fā)linux系統(tǒng),可以用glibc,如果對(duì)代碼容量等方面有要求,也可使用嵌入式c庫(kù)。筆者測(cè)試用相同的UCGUI移植代碼分別鏈接uclibc和glibc,代碼容量差距相當(dāng)明顯,鏈接uclibc時(shí),可執(zhí)行代碼只有270k,而glibc達(dá)到700k。此處采用uclibc作為c庫(kù),對(duì)于在linux下做開發(fā)而采用glibc的讀者,可以下載uclibc的最新源碼庫(kù),通過make menuconfig簡(jiǎn)單配置,用交叉編譯工具編譯源碼庫(kù),即可生成交叉編譯工具可使用的c庫(kù)。嵌入式開發(fā)最常使用到字符處理、數(shù)學(xué)處理方面的庫(kù)函數(shù),非linux操作系統(tǒng)開發(fā),只能鏈接靜態(tài)庫(kù),在linux下對(duì)應(yīng)庫(kù)名為libc.a和libm.a。由于不使用glibc,因此標(biāo)準(zhǔn)c庫(kù)應(yīng)指定uclibc的庫(kù)存放路徑。同時(shí),對(duì)于沒有硬件除法器,浮點(diǎn)處理單元的arm,對(duì)取余和除法操作,浮點(diǎn)處理都需要libgcc.a的支持。UCGUI移植用到了這三個(gè)庫(kù),因此需要在Makefile中指定這三個(gè)庫(kù)的路徑,庫(kù)路徑設(shè)置如下,對(duì)于uclibc中的libc.a和libm.a庫(kù)路徑,需要讀者根據(jù)自己的嵌入式庫(kù)路徑進(jìn)行修改。
PLATFORM_LIBS :=
# 加入uclibc標(biāo)準(zhǔn)c庫(kù)以及數(shù)學(xué)函數(shù)庫(kù)
PLATFORM_LIBS += -L /opt/crosstool/uClibc-0.9.33.2/lib -lm -lc
# 加入gcc庫(kù)
PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS)-print-libgcc-file-name`) –lgcc
至此,Makefile工程設(shè)置完畢,跳轉(zhuǎn)到頂層目錄,執(zhí)行make即可開始編譯工程。編譯時(shí)產(chǎn)生一大堆錯(cuò)誤,主要是提示頭文件未找到,micrium給出的GUIDemo目錄下的測(cè)試代碼寫的不夠嚴(yán)謹(jǐn),源代碼中include頭文件名不區(qū)分大小寫。例如實(shí)際要#include“GUI.h”,但有些源碼中是#include"GUI.H",這對(duì)于windows來說是沒有區(qū)別的,因?yàn)閣indows文件系統(tǒng)不區(qū)分大小寫,但linux卻是區(qū)分大小的,因此會(huì)提示找不到文件。windows操作系統(tǒng)假定它的用戶是兒童,對(duì)一般用戶來說,apple和Apple都是蘋果,沒有區(qū)別。但linux/unix操作系統(tǒng)假定它的用戶是專業(yè)人士,apple和Apple雖然都是蘋果,但它們的大小、產(chǎn)地、口感等均是不同的,因此是有區(qū)別的。為了代碼的可重用,這些問題都是需要注意的,尤其是同時(shí)在windows和linux下做開發(fā),應(yīng)保證一定的規(guī)范性。如在windows下文件目錄名區(qū)分大小寫,在linux下文件名加后綴(如.c、.h)表示這個(gè)文件的用途等。此處沒有好的方法,只能修改GUIDemo下所有不區(qū)分頭文件名大小寫的源碼。
6. 代碼燒錄修改編譯通過后,會(huì)在頂層目錄生成三個(gè)比較重要的文件,ucgui.map為鏈接Mapping文件,這里可以看到各個(gè)全局符號(hào)、各個(gè)段內(nèi)存鏈接位置、大小等信息。s3c2416.dis為工程的匯編生成文件,這是編譯器經(jīng)過編譯所有的源碼并進(jìn)行鏈接最終給出的匯編文件,這是最權(quán)威的查錯(cuò)文件,編譯器的bug以及任何用戶的失誤造成編譯器未能很好地按照用戶的本意編譯等出現(xiàn)的問題,在這里都可以查找出。s3c2416.bin即為我們用來燒錄進(jìn)SD卡或nand等存儲(chǔ)器的二進(jìn)制代碼文件。
此處說明一點(diǎn),筆者此系列的裸機(jī)例程都是有啟動(dòng)代碼的,可以自動(dòng)從sd/mmc卡、nand啟動(dòng)的,代碼的燒錄與一般的bootloader的燒錄方式無異。最常用的燒錄方式是把裸機(jī)bin代碼通過SdBoot工具進(jìn)行格式轉(zhuǎn)換,再通過三星sd卡燒寫工具IROM_Fusing_Tool把轉(zhuǎn)換后的bin代碼燒寫進(jìn)sd卡,設(shè)置成sd卡啟動(dòng)即可。從sd卡啟動(dòng)成功后,通過調(diào)用相關(guān)的Nand模塊接口函數(shù),實(shí)現(xiàn)代碼固化進(jìn)Nand,以后即可從Nand啟動(dòng)。詳細(xì)教程請(qǐng)參考筆者前面章節(jié)的” GCC啟動(dòng)代碼工程應(yīng)用實(shí)例”或” MDK啟動(dòng)代碼工程應(yīng)用實(shí)例”。
7. 編譯工具性能對(duì)比筆者采用了相同的UCGUI移植源碼在MDK、GCC下進(jìn)行編譯,MDK和GCC均設(shè)置成二級(jí)優(yōu)化條件下,對(duì)比這兩個(gè)平臺(tái)下編譯器、標(biāo)準(zhǔn)c庫(kù)的差異。
7.1. 代碼容量編譯后,MDK下生成的二進(jìn)制可執(zhí)行代碼大小為250k,而GCC在采用uclibc標(biāo)準(zhǔn)庫(kù)時(shí)可執(zhí)行代碼大小為273k,在老版本的GCC交叉編譯工具上,采用glibc生成的代碼大小為700k,從代碼容量看,MDK生成的代碼更小,采用GCC加uclibc并不比商業(yè)公司開發(fā)的平臺(tái)工具差很多。在linux下做嵌入式開發(fā),對(duì)代碼容量、性能有要求的話,無特殊情況,采用嵌入式c庫(kù)如uclibc、newlib等更適合。
7.2. 編譯速率均把所有源碼加入工程中進(jìn)行全部編譯,MDK下編譯時(shí)間需225秒,可以明顯看到提示窗口的源碼在一個(gè)一個(gè)編譯,GCC下編譯時(shí)間為42秒,源碼編譯時(shí)可看到窗口是在刷屏的,編譯速度不是MDK能比的。
7.3. 代碼生成質(zhì)量此處并不能準(zhǔn)確對(duì)比MDK與GCC代碼生成質(zhì)量的優(yōu)劣,只能以UCGUI多層裁剪測(cè)試作為一個(gè)對(duì)比項(xiàng)。MDK生成的可執(zhí)行代碼裁剪打點(diǎn)速度為11526060 pixel/秒,而GCC生成的可執(zhí)行代碼打點(diǎn)速度為11985690 pixel/秒,打點(diǎn)速度GCC高出4%,可以看出開源免費(fèi)的GCC編譯器以及c庫(kù)uclibc同樣高效優(yōu)越。
對(duì)比可以看出,GCC與MDK不分上下,某些方面GCC做的更好,如編譯速度。當(dāng)然,MDK還有必殺技MicroLIB,這是MDK專為arm嵌入式應(yīng)用高度優(yōu)化的庫(kù),用了這個(gè)外掛庫(kù)后,任何其它編譯器的標(biāo)準(zhǔn)c庫(kù)都暗然失色,當(dāng)然只能夠支持部分c庫(kù)的實(shí)現(xiàn)。總體來說,對(duì)于移植平臺(tái)多、開源免費(fèi)的GNU軟件來說,能達(dá)到絲毫不輸商業(yè)軟件的性能,確實(shí)令人尊敬,選擇GNU軟件進(jìn)行開發(fā)也是相當(dāng)不錯(cuò)的。
移植后的UCGUI效果:
對(duì)于ucgui的移植,總體還是比較簡(jiǎn)單的,主要是根據(jù)特定的LCD和觸摸屏進(jìn)行相應(yīng)的接口移植,這只需要實(shí)現(xiàn)相應(yīng)的LCD、觸摸屏驅(qū)動(dòng)模塊即可。如果讀者在windows下進(jìn)行過win32窗口編程(非MFC),那么對(duì)于ucgui的界面編程也會(huì)是得以應(yīng)手的。
ucgui_MDK.rar,MDK平臺(tái)下的UCGUI 3.98版移植源碼工程,需根據(jù)特定LCD、觸摸屏進(jìn)行驅(qū)動(dòng)模塊的更改。
http://pan.baidu.com/s/1eQvcNWe
u