2.2.2 字節(jié)對齊
有的嵌入式處理器的尋址方式?jīng)Q定了在內(nèi)存中占2字節(jié)的int16、uint16等類型數(shù)據(jù)只能存放在偶數(shù)內(nèi)存地址處,占4字節(jié)的int32 、uint32 等類型數(shù)據(jù)只能存放在4的整數(shù)倍的內(nèi)存地址處;占8字節(jié)的類型數(shù)據(jù)只能存放在8的整數(shù)倍的內(nèi)存地址處;而在內(nèi)存中只占1字節(jié)的類型數(shù)據(jù)可以存放在任意地址處。由于這些限制,在這些平臺上編程時有很大的不同。首先,結(jié)構(gòu)體成員之間會有空洞,比如這樣一個結(jié)構(gòu):
typedef struct test{
char a;
uint16 b;
}TEST
結(jié)構(gòu)TEST在單字節(jié)對齊的平臺上占內(nèi)存三個字節(jié),而在以上所述的嵌入式平臺上有可能占三個或四個字節(jié),視成員a的存儲地址而定。當(dāng)a存儲地址為偶數(shù)時,該結(jié)構(gòu)占四個字節(jié),在a與b之間存在一個字節(jié)的空洞。對于通信雙方都是對結(jié)構(gòu)成員操作的,這種情況不會出錯,但如果有一方是逐字節(jié)讀取內(nèi)容的(通信協(xié)議大都如此),就會錯誤地讀到其它字節(jié)的內(nèi)容。其次,若對內(nèi)存中數(shù)據(jù)以強制類型轉(zhuǎn)換的方式讀取,字節(jié)對齊的不同會引起數(shù)據(jù)讀取的錯誤。因為假如指針指在基數(shù)內(nèi)存地址處,我們想取得占內(nèi)存兩個字節(jié)的數(shù)據(jù)存放在uint16型的變量中,強制類型轉(zhuǎn)換的結(jié)果是取得了該指針?biāo)傅刂放c前一地址處的數(shù)據(jù),并沒有按照我們的愿望取該指針?biāo)傅刂放c后一地址處的數(shù)據(jù),這樣就導(dǎo)致了數(shù)據(jù)讀取的錯誤。 解決字節(jié)對齊有許多方法,比如可以在GCC的項目管理文件MakeFile中增加編譯選項--pack-struct;但這種方法只能去除結(jié)構(gòu)中的空洞,并不能解決強制類型轉(zhuǎn)換引起的錯誤。為了增強軟件的可移植性以及和同類其它平臺產(chǎn)品的互通性,我們在收數(shù)據(jù)包處增加了拆包的函數(shù),發(fā)數(shù)據(jù)包處增加了組包的函數(shù)。這兩個函數(shù)解決了字節(jié)序的問題,也解決了字節(jié)對齊的問題。即組包時根據(jù)參數(shù)中的格式字符串將內(nèi)存中的不同數(shù)據(jù)類型的某段數(shù)據(jù)放在指定地址處,組成包發(fā)給下層;拆包時,根據(jù)參數(shù)中的格式字符串將收到的內(nèi)存中的數(shù)據(jù)存放在不同類型的變量或結(jié)構(gòu)成員中。在函數(shù)中針對不同的數(shù)據(jù)類型作不同的處理。 2.2.3 位 段
由于位段的空間分配方向因硬件平臺的不同而不同,對X86平臺,位段是從右向左分配的;而一些嵌入式平臺,位段是從左向右分配的。分配順序的不同導(dǎo)致了數(shù)據(jù)存取的錯誤。解決這一問題的一種方法是采用條件編譯的方式,針對不同的平臺定義順序不同的位段;也可以在前面所述的兩個函數(shù)中加上對位段的處理。
2.2.4 代碼優(yōu)化
嵌入式系統(tǒng)對應(yīng)用軟件的質(zhì)量要求更高,因而在嵌入式開發(fā)中尤其須注意對代碼進行優(yōu)化,盡可能地提高代碼的效率,減少代碼的大小。雖然現(xiàn)代C和C++編譯器都提供了一定程度的代碼優(yōu)化,但大部分由編譯器執(zhí)行的優(yōu)化技術(shù)僅涉及執(zhí)行速度和代碼大小的平衡,不可能使程序既快又小,因而必須在編寫嵌入式軟件時采取必要的措施。
(1)提高代碼的效率
、賡witch-case 語句。在程序中經(jīng)常會使用switch-case語句,每一個由機器語言實現(xiàn)的測試和跳轉(zhuǎn)僅僅是為了決定下一步要做什么,就浪費了處理器時間。為了提高速度,可以把具體的情況按照它們發(fā)生的相對頻率排序。即把最可能發(fā)生的情況放在第一,最不可能發(fā)生的情況放在最后,這樣會減少平均的代碼執(zhí)行時間。
、 全局變量。使用全局變量比向函數(shù)傳遞參數(shù)更加有效率,這樣做去除了函數(shù)調(diào)用前參數(shù)入棧和函數(shù)完成后參數(shù)出棧的需要。當(dāng)然,使用全局變量會對程序有一些負作用。
(2)減小代碼的大小
嵌入式系統(tǒng)編程應(yīng)避免使用標(biāo)準(zhǔn)庫例程,因為很多大的庫例程設(shè)法處理所有可能的情況,所以占用了龐大的內(nèi)存空間,因而應(yīng)盡可能地減少使用標(biāo)準(zhǔn)庫例程。
(3)避免內(nèi)存泄漏
用戶內(nèi)存空間(堆)為RAM中全局?jǐn)?shù)據(jù)和任務(wù)堆?臻g都分配后的剩余空間,為了使程序能有足夠的內(nèi)存運行,必須在申請的內(nèi)存不用后及時地將其釋放,以確保再次申請時能有空間。如果程序中存在內(nèi)存泄漏(即申請內(nèi)存后沒有及時釋放)的情況,程序最終會因為沒有足夠的內(nèi)存空間而無法運行。 3 嵌入式系統(tǒng)的廣泛應(yīng)用
嵌入式系統(tǒng)的應(yīng)用前景是非常廣泛的,人們將會無時無處不接觸到嵌入式產(chǎn)品,從家里的洗衣機、電冰箱,到作為交通工具的自行車、小汽車,到辦公室里的遠程會議系統(tǒng)等等。特別是以藍牙為代表的小范圍無線接入?yún)f(xié)議的出現(xiàn),使嵌入式無線電的概念悄然興起。當(dāng)嵌入式的無線電芯片的價格可被接受時,它的應(yīng)用可能會無所不在。在家中、辦公室、公共場所,人們可能會使用數(shù)十片甚至更多這樣的嵌入式無線電芯片,將一些電子信息設(shè)備甚至電氣設(shè)備構(gòu)成無線網(wǎng)絡(luò);在車上、旅途中,人們利用這樣的嵌入式無線電芯片可以實現(xiàn)遠程辦公、遠程遙控,真正實現(xiàn)把網(wǎng)絡(luò)隨身攜帶。下面介紹幾種具體的應(yīng)用。
(1)嵌入式移動數(shù)據(jù)庫
所謂的移動數(shù)據(jù)庫是支持移動計算的數(shù)據(jù)庫,有兩層含義:① 用戶在移動的過程中可以聯(lián)機訪問數(shù)據(jù)庫資源。② 用戶可以帶著數(shù)據(jù)庫移動。典型的應(yīng)用場合有在開著的救護車上查詢最近的醫(yī)院。該系統(tǒng)由前臺移動終端、后臺同步服務(wù)器組成,移動終端上有嵌入式實時操作系統(tǒng)和嵌入式數(shù)據(jù)庫。中國人民大學(xué)正在開發(fā)該系統(tǒng),他們和Hopen公司合作,開發(fā)了前臺移動終端"小精靈"。
(2)嵌入式系統(tǒng)在智能家居網(wǎng)絡(luò)中的應(yīng)用
智能家居網(wǎng)絡(luò)(E-Home)指在一個家居中建立一個通信網(wǎng)絡(luò),為家庭信息提供必要的通路;在家庭網(wǎng)絡(luò)操作系統(tǒng)的控制下,通過相應(yīng)的硬件和執(zhí)行機構(gòu),實現(xiàn)對所有家庭網(wǎng)絡(luò)上家電和設(shè)備的控制和監(jiān)測。其網(wǎng)絡(luò)結(jié)構(gòu)的組成必然有家庭網(wǎng)關(guān)。家庭網(wǎng)關(guān)主要實現(xiàn)控制網(wǎng)絡(luò)和信息網(wǎng)絡(luò)的信號綜合并與外界接口,以便作遠程控制和信息交換。不論是網(wǎng)關(guān)還是各家電上的控制模塊,都需有嵌入式操作系統(tǒng)。這些操作系統(tǒng)必須具有內(nèi)嵌式、實時性好、多用戶的特點。南京東大移動互聯(lián)技術(shù)有限公司研制的智能多媒體家庭網(wǎng)關(guān),就是以嵌入式Linux作為該嵌入式設(shè)備的操作系統(tǒng),設(shè)備之間的相互通信遵從藍牙通信協(xié)議,可以支持多個設(shè)備同時接入到固定電話網(wǎng)、國際互聯(lián)網(wǎng)等其它外部網(wǎng)絡(luò)。
更多軟考資料請訪問:考試吧軟件水平考試欄目
希望與更多網(wǎng)友交流,請進入考試吧軟件水平考試論壇