上回我們提到,嵌入式應(yīng)用軟件開發(fā)主要包括以下5個基本階段:開發(fā)環(huán)境的建立、源代碼編輯階段、交叉編譯和鏈接、重定位和下載、聯(lián)機調(diào)試。下面嵌入式培訓(xùn)分別對這幾個階段進行介紹:
1.開發(fā)環(huán)境的建立
在開發(fā)之前,必須了解在嵌入式編程中使用的交叉開發(fā)環(huán)境。交叉開發(fā)環(huán)境的原理比較簡單,只是在主機和目標機體系結(jié)構(gòu)不同的情況下,在主機開發(fā)將在目標機器上運行的程序。
按照發(fā)布的形式,交叉開發(fā)環(huán)境主要分為開放和商用2種類型。開發(fā)式交叉開發(fā)環(huán)境實例主要有g(shù)cc,它可以支持多種交叉平臺的編譯器。使用gcc作為交叉開發(fā)平臺,要遵守GPL的規(guī)定。
按照使用方式,交叉開發(fā)工具主要分為使用Makefile和IDE開發(fā)環(huán)境2種類型。使用Makefile的開發(fā)環(huán)境需要編譯Makefile來管理和控制項目的開發(fā),可以自己手寫,優(yōu)勢也可以使用一些自動化的工具。這種開發(fā)工具是gcc、SDS Cross Compiler等。新類型的開發(fā)環(huán)境一般由一個用戶友好的IDE界面,方便管理和控制項目的開發(fā),如Code Warrior等。有些開發(fā)環(huán)境既可用Makefile管理項目,又可使用IDE,給使用者留下很大的余地。
對交叉開發(fā)環(huán)境有了一定的了解后,就要根據(jù)開發(fā)需求選擇一種開發(fā)環(huán)境進行代碼編寫。編寫程序的件事情就是要會寫程序,即要先會程序的規(guī)劃,將問題需求跟蹤程序功能明確地寫下來,依據(jù)規(guī)劃好的函數(shù)逐個寫好。
當(dāng)嵌入式系統(tǒng)編程升級時,要考慮到跨平臺的問題。跨平臺就是把原始程序拿到不同的CPU的平臺和編譯環(huán)境中,仍然能夠不用修改太多的代碼就可達到程序原始目的。因為嵌入式系統(tǒng)所用的硬件平臺不盡相同,若是為了不同的硬件平臺而讓程序做大幅度修改,就會變得非常不經(jīng)濟,特別是在當(dāng)時嵌入式系統(tǒng)硬件百家爭鳴的狀況下,如何讓寫出的程序快速移植到各種不同的硬件上,已成為嵌入式培訓(xùn)應(yīng)用程序開發(fā)飛主要考慮因素之一。
2.源文件編輯階段
源程序的啟動代碼、硬件初始化代碼要用匯編語言編寫,這樣可以發(fā)揮匯編語言短小精悍的優(yōu)勢,以提高代碼的執(zhí)行效率。匯編語言編寫完成后,代碼轉(zhuǎn)向c語言的程序入口點,執(zhí)行c語言代碼。C語言在開發(fā)大型軟件的開發(fā)中常用的語言。但是在與硬件關(guān)聯(lián)較緊密的編程中,c語言要結(jié)合匯編語言進行混合編程,也即內(nèi)嵌匯編。
3.編譯
通常所說的翻譯程序能夠把某一種語言的程序轉(zhuǎn)換成另一種語言程序,而后者與前者在邏輯上是等價的,如果匯編語言是諸如FORTRAN、Pascal、C、Ada或Java這樣的“語言”,而目標語言是諸如匯編語言或機器語言之類的“低級語言”,這樣的一個翻譯程序成為編譯程序。編譯就是將“語言”轉(zhuǎn)化為“低級語言”的過程。
編譯器主要負責(zé)的工作就是將源代碼編譯成特定的目標代碼,順便檢查語法的錯誤,所產(chǎn)生的代碼是不能執(zhí)行的,不過可從目標代碼找出許多有用的信息。現(xiàn)在目標代碼有2類:COFF與ELF。在目標文件中規(guī)定信息的組織方式,也即目標文件格式。目標文件格式的規(guī)定是為了不同的供應(yīng)商提供的開發(fā)工具可以遵循很好的標準,以實現(xiàn)相互操作的。
4.鏈接
一個程序員想在內(nèi)存中運行,除了編譯之外,還要經(jīng)過鏈接的步驟。編譯器只能在一個模塊內(nèi)部完成符號名到地址的轉(zhuǎn)換工作,不同模式間的符號解析需要由連接器完成。為了解決不同模式間的鏈接問題,鏈接器主要有2項工作要做。
1)符號解析
當(dāng)一個模塊使用了在該模塊中沒有定義過的函數(shù)或全局變量時,編譯器生成的符號表會標記出所有這樣的函數(shù)或全局變量;而鏈接器的責(zé)任就是要到其他模塊中去查找他們的定義,如果沒有合適的定義或者找到的合適的定義不,符號解析都無法正常完成。
2)重定位
編譯器在編譯生成文件時,通常使用從零開始的相對地址。然而,在鏈接過程中,鏈接器將從一個指定的地址開始,根據(jù)輸入的目標文件的順序以段為單位將它們一個接一個地拼裝起來。除了目標文件的拼裝之外,在重定位的過程中還完成了2個任務(wù):一是生成終的符號表;二是對代碼中的某些位置進行修改,所有需要修改的位置都由編譯器生成的重定位表指出。
鏈接器將所有目標代碼及l(fā)ib里的數(shù)據(jù)區(qū)段,包括“.text”“.data”及“.bss”區(qū)段的數(shù)據(jù)合并,而且會將所有尚未編譯的函數(shù)及變量調(diào)用彼此對應(yīng)起來。
在鏈接過程中,對于嵌入式系統(tǒng)的開發(fā)而言,都希望使用小型的函數(shù)庫,以使產(chǎn)的可執(zhí)行代碼盡量小。因此在編譯中使用的一般是經(jīng)過特殊定制的函數(shù)庫,比如使用c語言進行嵌入式開發(fā)者一般使用的嵌入式函數(shù)庫有:μClibc/μClibm、μC-libc/μC-libm和newlib等。
5.下載
就是把可執(zhí)行映像文件燒寫到ROM里,如本系列教程中使用的Embest ARM開發(fā)環(huán)境具有Flash編譯器功能,燒寫前使用Elf to Bin工具將映像文件(ELF格式轉(zhuǎn)換為二進制格式),也可通過其他方式下載調(diào)試好的代碼。
當(dāng)可執(zhí)行的程序映像文件下載完成后,就可打開電源來運行系統(tǒng)。下載過的代碼優(yōu)勢還需要在實際應(yīng)用軟件中進行進一步調(diào)試,調(diào)試確定無誤后一個完整的嵌入式程序就可運行了。
6.調(diào)試
嵌入式培訓(xùn)系統(tǒng)的調(diào)試分為軟件調(diào)試和硬件調(diào)試2種:軟件調(diào)試時通過軟件調(diào)試器嵌入式系統(tǒng)軟件;硬件調(diào)試時通過仿真調(diào)試器完成調(diào)試過程。由于嵌入式系統(tǒng)特殊的開發(fā)環(huán)境,不可避免的是,調(diào)試時必然需要目標平臺和調(diào)試器兩方面的支持。
通常作為調(diào)試軟件部分的調(diào)試器是被集成在安裝在目標機上嵌入式軟件開發(fā)集成環(huán)境中的,例如Embest IDE中的Debhgger。軟件調(diào)試工具一般具有ISS功能,即完成代碼在無硬件調(diào)試環(huán)境下的模擬調(diào)試。而由于真正的硬件運行環(huán)境與軟禁模擬環(huán)境有較大的差異,ISS只能用于開發(fā)編程練習(xí)或者軟件的初步調(diào)試。
使用硬件調(diào)試器,可獲得比軟件功能強大得多的調(diào)試性能。硬件調(diào)試器的原理一般是通過仿真硬件和真正執(zhí)行過程,讓開發(fā)者在調(diào)試過程中可時刻獲得執(zhí)行情況。硬件調(diào)試器主要有ICE和ICD兩種。前者主要完成仿真模擬的功能,后者使用硬件上的在線調(diào)試任務(wù)。
這次我們詳細講了嵌入式開發(fā)五大階段了,想了解更多,就來pick粵嵌嵌入式培訓(xùn)。