精品国产成人一区二区三区-女子十八毛片-欧洲性猛交-无码不卡一区二区三区在线观看-www.四虎在线-伊人网国产-国精产品自偷自偷综合下载-不卡av网站-俄罗斯黄色大片-一本久久知道综合久久-国产精品日韩一区二区-日韩精品色-免费人成网ww555kkk在线-黄色在线观看免费-日韩在线免费-久久久久99人妻一区二区三区-十八禁真人啪啪免费网站

機(jī)電之家資源網(wǎng)
單片機(jī)首頁(yè)|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開(kāi)發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開(kāi)發(fā)
培訓(xùn)信息
贊助商
ARM ADS集成開(kāi)發(fā)環(huán)境的使用
ARM ADS集成開(kāi)發(fā)環(huán)境的使用
 更新時(shí)間:2009-7-31 15:56:42  點(diǎn)擊數(shù):0
【字體: 字體顏色

 

在這一章里,將介紹ARM開(kāi)發(fā)軟件ADS(ARM Developer Suite)。通過(guò)學(xué)習(xí)如何在CodeWarrior IDE集成開(kāi)發(fā)環(huán)境下編寫(xiě),編譯一個(gè)工程的例子,使讀者能夠掌握在ADS軟件平臺(tái)下開(kāi)發(fā)用戶(hù)應(yīng)用程序。本章還描述了如何使用AXD調(diào)試工程,使讀者對(duì)于調(diào)試工程有個(gè)初步的理解,為進(jìn)一步的使用和掌握調(diào)試工具起到拋磚引玉的作用。本章主要內(nèi)容有:- ADS軟件組成介紹- 使用ADS創(chuàng)建工程- 用AXD進(jìn)行代碼調(diào)試

8.1  ADS集成開(kāi)發(fā)環(huán)境組成介紹

ARM ADS全稱(chēng)為ARM Developer Suite。是ARM公司推出的新一代ARM集成開(kāi)發(fā)工具,F(xiàn)在ADS的最新版本是1.2,它取代了早期的ADS1.1和ADS1.0。它除了可以安裝在Windows NT4,Windows 2000,Windows 98和Windows 95操作系統(tǒng)下,還支持Windows XP和Windows Me操作系統(tǒng)。ADS由命令行開(kāi)發(fā)工具,ARM時(shí)實(shí)庫(kù),GUI開(kāi)發(fā)環(huán)境(Code Warrior和AXD),實(shí)用程序和支持軟件組成。 有了這些部件,用戶(hù)就可以為ARM系列的RISC處理器編寫(xiě)和調(diào)試自己的開(kāi)發(fā)應(yīng)用程序了。下面就詳細(xì)介紹一下ADS的各個(gè)組成部分。

8.1.1  命令行開(kāi)發(fā)工具

這些工具完成將源代碼編譯,鏈接成可執(zhí)行代碼的功能。ADS提供下面的命令行開(kāi)發(fā)工具:armccarmcc是ARM C編譯器。這個(gè)編譯器通過(guò)了Plum Hall C Validation Suite為ANSI C的一致性測(cè)試。armcc用于將用ANSI C編寫(xiě)的程序編譯成32位ARM指令代碼。因?yàn)閍rmcc是我們最常用的編譯器,所以對(duì)此作一個(gè)詳細(xì)的介紹。在命令控制臺(tái)環(huán)境下,輸入命令:armcc –help可以查看armcc的語(yǔ)法格式以及最常用的一些操作選項(xiàng)armcc最基本的用法為:   armcc [options] file1 file2 ... filen這里的option是編譯器所需要的選項(xiàng),fiel1,file2…filen是相關(guān)的文件名。    這里簡(jiǎn)單介紹一些最常用的操作選項(xiàng)。-c:表示只進(jìn)行編譯不鏈接文件;  -C:(注意:這是大寫(xiě)的C)禁止預(yù)編譯器將注釋行移走;-D<symbol>:定義預(yù)處理宏,相當(dāng)于在源程序開(kāi)頭使用了宏定義語(yǔ)句#define symbol ,這里symbol默認(rèn)為1;-E:僅僅是對(duì)C源代碼進(jìn)行預(yù)處理就停止;-g<options>:指定是否在生成的目標(biāo)文件中包含調(diào)試信息表;-I<directory>:將directory所指的路徑添加到#include的搜索路徑列表中去; -J<directory>:用directory所指的路徑代替默認(rèn)的對(duì)#include的搜索路徑;-o<file>:指定編譯器最終生成的輸出文件名。-O0:不優(yōu)化;-O1:這是控制代碼優(yōu)化的編譯選項(xiàng),大寫(xiě)字母O后面跟的數(shù)字不同,表示的優(yōu)化級(jí)別就不同,-O1關(guān)閉了影響調(diào)試結(jié)果的優(yōu)化功能;-O2:該優(yōu)化級(jí)別提供了最大的優(yōu)化功能;-S:對(duì)源程序進(jìn)行預(yù)處理和編譯,自動(dòng)生成匯編文件而不是目標(biāo)文件;-U<symbol>:取消預(yù)處理宏名,相當(dāng)于在源文件開(kāi)頭,使用語(yǔ)句#undef symbol;-W<options>:關(guān)閉所有的或被選擇的警告信息;有關(guān)更詳細(xì)的選項(xiàng)說(shuō)明,讀者可查看ADS軟件的在線(xiàn)幫助文件。armcpparmcpp是ARM C++編譯器。它將ISO C++ 或EC++ 編譯成32位ARM指令代碼。tcctcc是Thumb C 編譯器。該編譯器通過(guò)了Plum Hall C Validation Suite為ANSI 一致性的測(cè)試。tcc將ANSI C源代碼編譯成16位的Thumb指令代碼。tcpptcpp是Thumb C++ 編譯器。 它將ISO C++ 和EC++ 源碼編譯成16位Thumb指令代碼。armasmarmasm是ARM和Thumb的匯編器. 它對(duì)用ARM 匯編語(yǔ)言和Thumb 匯編語(yǔ)言寫(xiě)的源代碼進(jìn)行匯編。armlinkarmlink是ARM連接器。該命令既可以將編譯得到的一個(gè)或多個(gè)目標(biāo)文件和相關(guān)的一個(gè)或多個(gè)庫(kù)文件進(jìn)行鏈接,生成一個(gè)可執(zhí)行文件,也可以將多個(gè)目標(biāo)文件部分鏈接成一個(gè)目標(biāo)文件,以供進(jìn)一步的鏈接。ARM鏈接器生成的是ELF格式的可執(zhí)行映像文件。armsdarmsd是ARM 和Thumb的符號(hào)調(diào)試器。它能夠進(jìn)行源碼級(jí)的程序調(diào)試。用戶(hù)可以在用C或匯編語(yǔ)言寫(xiě)的代碼中進(jìn)行單步調(diào)試,設(shè)置斷點(diǎn),查看變量值和內(nèi)存單元的內(nèi)容。
8.1.1.1  armcc用法詳解
下面為讀者介紹上述的4種ARM C和C++編譯器的命令通用語(yǔ)法。compiler [PCS-options] [source-language] [search-paths] [preprocessor-options] [output-format] [target-options] [debug-options] [code-generation-options] [warning-options] [additional-checks] [error-options] [source]用戶(hù)可以通過(guò)命令行操作選項(xiàng)控制編譯器的執(zhí)行。所有的選項(xiàng)都是以符號(hào)”-”開(kāi)始,有些選項(xiàng)后面還跟有參數(shù)。在大多數(shù)情況下,ARM C和 C++編譯器允許在選項(xiàng)和參數(shù)之間存在空格。命令行中各個(gè)選項(xiàng)出現(xiàn)順序可以任意。這里的compiler是指armcc,tcc, armcpp和 tcpp中的一個(gè);PCS-options:指定了要使用的過(guò)程調(diào)用標(biāo)準(zhǔn);source-language:指定了編譯器可以接受的編寫(xiě)源程序的語(yǔ)言種類(lèi)。對(duì)于C編譯器默認(rèn)的語(yǔ)言是ANSI C,對(duì)于C++編譯器默認(rèn)是ISO標(biāo)準(zhǔn)C++;search-paths:該選項(xiàng)指定了對(duì)包含的文件(包括源文件和頭文件)的搜索路徑;preprocessor-options:該選項(xiàng)指定了預(yù)處理器的行為,其中包括預(yù)處理器的輸出和宏定義等特性;output-format:該選項(xiàng)指定了編譯器的輸出格式,可以使用該項(xiàng)生成匯編語(yǔ)言輸出列表文件和目標(biāo)文件;target-options:該選項(xiàng)指定目標(biāo)處理器或ARM體系結(jié)構(gòu);debug-options:該選項(xiàng)指定調(diào)試信息表是否生成,和該調(diào)試信息表生成時(shí)的格式;code-generation-options:該選項(xiàng)指定了例如優(yōu)化,字節(jié)順序和由編譯器產(chǎn)生的數(shù)據(jù)對(duì)齊格式等選項(xiàng);warning-options:該選項(xiàng)決定警告信息是否產(chǎn)生;additional-checks:該選項(xiàng)指定了幾個(gè)能用于源碼的附加檢查,例如檢查數(shù)據(jù)流異常,檢查沒(méi)有使用的聲明等;error-options:該選項(xiàng)可以關(guān)閉指定的可恢復(fù)的錯(cuò)誤,或者將一些指定的錯(cuò)誤降級(jí)為警告;source:該選項(xiàng)提供了包含有C或C++源代碼的一個(gè)或多個(gè)文件名,默認(rèn)的,編譯器在當(dāng)前路徑尋找源文件和創(chuàng)建輸出文件。如果源文件是用匯編語(yǔ)言編寫(xiě)的(也就是說(shuō)該文件的文件名是以.s作為擴(kuò)展名),匯編器將被調(diào)用來(lái)處理這些源文件。如果操作系統(tǒng)對(duì)命令行的長(zhǎng)度有限制,可以使用下面的操作,從文件中讀取另外的命令行選項(xiàng):-via filename該命令打開(kāi)文件名為filename的文件,并從中讀取命令行選項(xiàng)。用戶(hù)可以對(duì)-via進(jìn)行嵌套調(diào)用,亦即,在文件filename中又通過(guò)-via finlename2包含了另外一個(gè)文件。在下面的例子中,從input.txt文件中讀取指定的選項(xiàng),作為armcpp的操作選項(xiàng):armcpp -via input.txt  source.c以上是對(duì)編譯器選項(xiàng)的一個(gè)簡(jiǎn)單概述。它們(包括后面還要介紹的其他一些命令工具)既可以在命令控制臺(tái)環(huán)境下使用,同時(shí)由于它們被嵌入到了ADS的圖形界面中,所以也可以在圖形界面下使用。
 8.1.1.2  armlink用法詳解
在介紹armlink的使用方法之前,先介紹要涉及到的一些術(shù)語(yǔ)。映像文件(image):是指一個(gè)可執(zhí)行文件,在執(zhí)行的時(shí)候被加載到處理器中。一個(gè)映像文件有多個(gè)線(xiàn)程。它是ELF(Executable and linking format)格式的。段(Section):描述映像文件的代碼或數(shù)據(jù)塊。RO:是Read-only的簡(jiǎn)寫(xiě)形式。RW:是Read-write.的簡(jiǎn)寫(xiě)形式。ZI:是Zero-initialized的簡(jiǎn)寫(xiě)形式。輸入段(input section):它包含著代碼,初始化數(shù)據(jù)或描述了在應(yīng)用程序運(yùn)行之前必須要初始化為0的一段內(nèi)存。輸出段(output section):它包含了一系列具有相同的RO,RW或ZI屬性的輸入段。域(Regions):在一個(gè)映像文件中,一個(gè)域包含了1至3個(gè)輸出段。多個(gè)域組織在一起,就構(gòu)成了最終的映像文件。Read Only Position Independent(ROPI):它是指一個(gè)段,在這個(gè)段中代碼和只讀數(shù)據(jù)的地址在運(yùn)行時(shí)候可以改變。Read Write Position Independent(RWPI):它是指一個(gè)段,在該段中的可讀/寫(xiě)的數(shù)據(jù)地址在運(yùn)行期間可以改變。加載時(shí)地址:是指映像文件位于存儲(chǔ)器(在該映像文件沒(méi)有運(yùn)行時(shí))中的地址。運(yùn)行時(shí)地址:是指映像文件在運(yùn)行時(shí)的地址。下面介紹一下armlink命令的語(yǔ)法完整的連接器命令語(yǔ)法如下: armlink [-help] [-vsn] [-partial] [-output file] [-elf] [-reloc][-ro-base address] [-ropi] [-rw-base address] [-rwpi] [-split] [-scatter file][-debug|-nodebug][-remove?RO/RW/ZI/DBG]|-noremove] [-entry location ] [-keep section-id] [-first section-id] [-last section-id] [-libpath pathlist] [-scanlib|-noscanlib] [-locals|-nolocals] [-callgraph] [-info topics] [-map] [-symbols] [-symdefs file] [-edit file] [-xref] [-xreffrom object(section)] [-xrefto object(section)] [-errors file] [-list file] [-verbose][-unmangled |-mangled] [-match crossmangled][-via file] [-strict][-unresolved symbol][-MI|-LI|-BI] [input-file-list]上面各選項(xiàng)的含義分別為: -help這個(gè)選項(xiàng)會(huì)列出在命令行中常用的一些選項(xiàng)操作。-vsn 這個(gè)選項(xiàng)顯示出所用的armlink的版本信息。-partial 用這個(gè)選項(xiàng)創(chuàng)建的是部分鏈接的目標(biāo)文件而不是可執(zhí)行映像文件。-output file這個(gè)選項(xiàng)指定了輸出文件名,該文件可能是部分鏈接的目標(biāo)文件,也可能是可執(zhí)行映像文件。如果輸出文件名沒(méi)有特別指定的話(huà),armlink將使用下面的默認(rèn):如果輸出是一個(gè)可執(zhí)行映像文件,則生成的輸出文件名為_(kāi)_image.axf;如果輸出是一個(gè)部分鏈接的目標(biāo)文件,在生成的文件名為_(kāi)_object.o;如果沒(méi)有指定輸出文件的路徑信息,則輸出文件就在當(dāng)前目錄下生成。如果指定了路徑信息,則所指定的路徑成為輸出文件的當(dāng)前路徑。-elf這個(gè)選項(xiàng)生成ELF格式的映像文件,這也是armlink所支持的唯一的一種輸出格式,這是默認(rèn)選項(xiàng)。-reloc這個(gè)選項(xiàng)生成可重定址的映像。一個(gè)可重定址的映像具有動(dòng)態(tài)的段,這個(gè)段中包含可重定址信息,利用這些信息可以在鏈接后,進(jìn)行映像文件的重新定址;-reloc,-rw-base 一起使用,但是如果沒(méi)有-split選項(xiàng),鏈接時(shí)會(huì)產(chǎn)生錯(cuò)誤。 -ro-base address這個(gè)選項(xiàng)將包含有RO(Read-Only屬性)輸出段的加載地址和運(yùn)行地址設(shè)置為address,該地址必須是字對(duì)齊的,如果沒(méi)有指定這個(gè)選項(xiàng),則默認(rèn)的RO基地址值為0x8000。-ropi這個(gè)選項(xiàng)使得包含有RO輸出段的加載域和運(yùn)行域是位置無(wú)關(guān)的。如果該選項(xiàng)沒(méi)有使用,則相應(yīng)的域被標(biāo)記為絕對(duì)的。通常每一個(gè)只讀屬性的輸入段必須是只讀位置無(wú)關(guān)的。如果使用了這個(gè)選項(xiàng),armlink將會(huì)進(jìn)行以下操作:檢查各段之間的重定址是否有效;確保任何由armlink自身生成的代碼是只讀位置無(wú)關(guān)的。這里希望讀者注意的是,ARM工具直到armlink完成了對(duì)輸入段的處理后,才能夠決定最終的生成映像是否為只讀位置無(wú)關(guān)的。這就意味著 ,即使為編譯器和匯編器指定了ROPI選項(xiàng),armlink也可能會(huì)產(chǎn)生ROPI錯(cuò)誤信息。-rw-base address這個(gè)選項(xiàng)設(shè)置包含RW(Read/Write屬性)輸出段的域的運(yùn)行時(shí)地址,該地址必須是字對(duì)齊的。如果這個(gè)選項(xiàng)和-split選項(xiàng)一起使用,將設(shè)置包含RW輸出段的域的加載和運(yùn)行時(shí)地址都設(shè)置在address處。-rwpi這個(gè)選項(xiàng)使得包含有RW和ZI(Zero Initialization,初始化為0)屬性的輸出段的加載和運(yùn)行時(shí)域?yàn)槲恢脽o(wú)關(guān)的。如果該選項(xiàng)沒(méi)有使用,相應(yīng)域標(biāo)記為絕對(duì)的。這個(gè)選項(xiàng)要求-rw-base選項(xiàng)后有值,如果-rw-base沒(méi)有指定的話(huà),默認(rèn)其值為0,即相當(dāng)于-rw-base 0。通常每一個(gè)可寫(xiě)的輸入段必須是可讀/ 可寫(xiě)的位置無(wú)關(guān)的。如果使用了該選項(xiàng),armlink會(huì)進(jìn)行以下的操作:檢查可讀/可寫(xiě)屬性的運(yùn)行域的輸入段是否設(shè)置了位置無(wú)關(guān)屬性;檢查在各段之間的重定址是否有效;生成基于靜態(tài)寄存器sb的條目,這些在RO和RW域被拷貝和初始化的時(shí)候會(huì)用到。編譯器并不會(huì)強(qiáng)制可寫(xiě)的數(shù)據(jù)一定要為位置無(wú)關(guān)的,這就是說(shuō),即使在為編譯器和匯編器指定了RWPI選項(xiàng),armlink也可能生成數(shù)據(jù)不是RWPI的信息。-split這個(gè)選項(xiàng)將包含RO和RW屬性的輸出段的加載域,分割成2個(gè)加載域。一個(gè)是包含RO輸出段的加載域,默認(rèn)的加載地址為0x8000,但是可以用-ro-base選項(xiàng)設(shè)置其他的地址值,另一個(gè)加載域包含RO屬性的輸出段,由-rw-base選項(xiàng)指定加載地址,如果沒(méi)有使用-rw-base選項(xiàng)的話(huà),默認(rèn)使用的是-rw-base 0。-scatter file這個(gè)選項(xiàng)使用在file中包含的分組和定位信息來(lái)創(chuàng)建映像內(nèi)存映射。注意,如果使用了該選項(xiàng)的話(huà),必須要重新實(shí)現(xiàn)堆棧初始化函數(shù)__user_initial_stackheap()。-debug這個(gè)選項(xiàng)使輸出文件包含調(diào)試信息,調(diào)試信息包括,調(diào)試輸入段,符號(hào)和字符串表。這是默認(rèn)的選項(xiàng)。-nodebug這個(gè)選項(xiàng)使得在輸出文件中不包含調(diào)試信息。生成的映像文件短小,但是不能進(jìn)行源碼級(jí)的調(diào)試。armlink對(duì)在輸入的目標(biāo)文件和庫(kù)函數(shù)中發(fā)現(xiàn)的任何調(diào)試輸入段都不予處理,當(dāng)加載映像文件到調(diào)試器中的時(shí)候,也不包含符號(hào)和字符串信息表。這個(gè)選項(xiàng)僅僅是對(duì)裝載到調(diào)試器的映像文件的大小有影響,但是對(duì)要下載到目標(biāo)板上的二進(jìn)制代碼的大小沒(méi)有任何影響。如果用armlink進(jìn)行部分鏈接生成目標(biāo)文件而不是映像文件,則雖然在生成的目標(biāo)文件中不含有調(diào)試輸入段,但是會(huì)包含符號(hào)和字符串信息表。這里特別請(qǐng)讀者注意的是:如果要在鏈接完成后使用fromELF工具的話(huà),不可使用-nodebug選項(xiàng),這是因?yàn)槿绻傻挠诚裎募胁话{(diào)試信息的話(huà),則有下面的影響:fromELF不能將映像文件轉(zhuǎn)換成其他格式的文件;fromELF不能生成有意義的反匯編列表。-remove (RO/RW/ZI/DBG)使用這個(gè)選項(xiàng)會(huì)將在輸入段未使用的段從映像文件中刪除。如果輸入段中含有映像文件入口點(diǎn)或者該輸入段被一個(gè)使用的段所引用,則這樣的輸入段會(huì)當(dāng)作已使用的段。在使用這個(gè)選項(xiàng)時(shí)候要注意,不要?jiǎng)h除異常處理函數(shù)。使用-keep選項(xiàng)來(lái)標(biāo)識(shí)異常處理函數(shù),或用ENTRY偽指令標(biāo)明是入口點(diǎn)。為了更精確的控制刪除未使用的段,可以使用段屬性限制符?梢允褂靡韵碌亩螌傩韵拗品篟O刪除所有未使用的RO屬性的段;RW刪除所有未使用的RW屬性的段;ZI刪除所有未使用的ZI屬性的段;DBG刪除所有未使用的DEBUG屬性的段。這些限制符出現(xiàn)的順序是任意的,但是它們必須要有”( )”括住,多個(gè)限制符之間要用符號(hào)”/”進(jìn)行間隔。ADS軟件中默認(rèn)選項(xiàng)是-remove (RO/RW/ZI/DBG)。如果沒(méi)有指定段屬性限制符,則所有未使用的段都會(huì)被刪除。因?yàn)?remove就等價(jià)于-remove(RO/RW/ZI/DBG)選項(xiàng)。-noremove這個(gè)選項(xiàng)保留映像文件中所有未被使用的段。-entry location這個(gè)選項(xiàng)指定映像文件中唯一的初始化入口點(diǎn)。一個(gè)映像文件可以包含多個(gè)入口點(diǎn),使用這個(gè)命令定義的初始化入口點(diǎn)是存放在可執(zhí)行文件的頭部,以供加載程序加載時(shí)使用。當(dāng)一個(gè)映像文件被裝載時(shí),ARM調(diào)試器使用這個(gè)入口點(diǎn)地址來(lái)初始化PC指針。初始化入口點(diǎn)必須滿(mǎn)足下面的條件:映像文件的入口點(diǎn)必須位于運(yùn)行域內(nèi);運(yùn)行域必須是非覆蓋的,并且必須是固定域(就是說(shuō),加載域和運(yùn)行域的地址相同)。在這里可以用以下的參數(shù)代替location參數(shù):1.  入口點(diǎn)地址:這是一個(gè)數(shù)值,例如-entry 0x0;2.  符號(hào):該選項(xiàng)指定映像文件的入口點(diǎn)為該符號(hào)所代表的地址處,比如:-entry int_handler表示程序入口點(diǎn)在符號(hào)int_handler所在處。如果該符號(hào)有多處定義存在,armlink將產(chǎn)生出錯(cuò)信息。offset+object(section):該選項(xiàng)指定在某個(gè)目標(biāo)文件的段的內(nèi)部的某個(gè)偏移量處為映像文件的入口地址,例如:-entry 8+startup(startupseg)如果偏移量值為0,可以簡(jiǎn)寫(xiě)成object(section),如果輸入段只有一個(gè),則可以簡(jiǎn)化為object。-keep section-id使用該選項(xiàng),可以指定保留一個(gè)輸入段,這樣的話(huà),即使該輸入段沒(méi)有在映像文件中使用,也不會(huì)被刪除。參數(shù)section-id取下面一些格式:1.  symbol該選項(xiàng)指定定義symbol的輸入段不會(huì)在刪除未使用的段時(shí)被刪除。如果映像文件中有多處symbol定義存在,則所有包含symbol定義的輸入段都不會(huì)被刪除。例如:-keep int_handler則所有定義int_handler的符號(hào)的段都會(huì)保留,而不被刪除。    為了保留所有含有以_handler結(jié)尾的符號(hào)的段,可以使用如下的選項(xiàng):-keep *_handler2.  object(section)這個(gè)選項(xiàng)指定了在刪除未使用段時(shí),保留目標(biāo)文件中的section段。輸入段和目標(biāo)名是不區(qū)分大小寫(xiě)的,例如,為了在目標(biāo)文件vectors.o中保留vect段,使用:-keep vectors.o(vect)為了保留vectors.o中的所有以vec開(kāi)頭的段名,可以使用選項(xiàng):-keep vectors.o(vec*)3.  object這個(gè)選項(xiàng)指定在刪除未使用段時(shí),保留該目標(biāo)文件唯一的輸入段。目標(biāo)名是不區(qū)分大小寫(xiě)的,如果使用這個(gè)選項(xiàng)的時(shí)候,目標(biāo)文件中所含的輸入段不止一個(gè)的話(huà),armlink會(huì)給出出錯(cuò)信息。比如,為了保留每一個(gè)以dsp開(kāi)頭的只含有唯一輸入段的目標(biāo)文件,可以使用如下的選項(xiàng):-keep dsp*.o-first section-id這個(gè)選項(xiàng)將被選擇的輸入段放在運(yùn)行域的開(kāi)始。通過(guò)該選項(xiàng),將包含復(fù)位和中斷向量地址的段放置在映像文件的開(kāi)始,可以用下面的參數(shù)代替section-id:1.symbol選擇定義symbol的段。禁止指定在多處定義的symbol,因?yàn)槎鄠(gè)段不能同時(shí)放在映像文件的開(kāi)始。2.object(section)從目標(biāo)文件中選擇段放在映像文件的開(kāi)始位置。在目標(biāo)文件和括號(hào)之間不允許存在空格,例如-first init.o(init)3.object選擇只有一個(gè)輸入段的目標(biāo)文件。如果這個(gè)目標(biāo)文件包含多個(gè)輸入段,armlink會(huì)產(chǎn)生錯(cuò)誤信息。用這個(gè)選項(xiàng)的例子如下:-first init.o這里希望讀者注意的是:使用-first不能改變?cè)谟蛑邪凑誖O段放在開(kāi)始,接著放置RW段,最后放置ZI段的基本屬性排放順序。如果一個(gè)域含有RO段,則RW或ZI段就不能放在映像文件的開(kāi)頭。類(lèi)似地,如果一個(gè)域有RO或RW段,則ZI段就不能放在文件開(kāi)頭。兩個(gè)不同的段不能放在同一個(gè)運(yùn)行時(shí)域的開(kāi)頭,所以使用該選項(xiàng)的時(shí)候只允許將一個(gè)段放在映像文件的開(kāi)頭。-last section-id這個(gè)選項(xiàng)將所選擇的輸入段放在運(yùn)行域的最后。例如,用這個(gè)選項(xiàng)能夠強(qiáng)制性的將包含校驗(yàn)和的輸入段放置在RW段的最后。使用下面的參數(shù)可以替換section-id。1.  symbol選擇定義symbol的段放置在運(yùn)行域的最后。不能指定一個(gè)有多處定義的symbol。使用該參數(shù)的例子如下:-last checksum2.  object(section)從目標(biāo)文件中選擇section段。在目標(biāo)文件和后面的括號(hào)間不能有空格,用該參數(shù)的例子為:-last checksum.o(check)3.       object選擇只有一個(gè)輸入段的目標(biāo),如果該目標(biāo)文件中有多個(gè)輸入段,armlink會(huì)給出出錯(cuò)信息。和-first選項(xiàng)一樣,需要讀者注意的是;使用-last選項(xiàng)不能改變?cè)谟蛑袑O段放在開(kāi)始,接著放置RW段,最后放置ZI段的輸出段基本的排放順序。如果一個(gè)域含有ZI段,則RW段不能放在最后,如果一個(gè)域含有RW或ZI段,則RO段不能放在最后。在同一個(gè)運(yùn)行域中,兩個(gè)不同的段不能同時(shí)放在域的最后位置。-libpath pathlist這個(gè)選項(xiàng)為ARM標(biāo)準(zhǔn)的C和C++庫(kù)指定了搜索路徑列表。注意,這個(gè)選項(xiàng)不會(huì)影響對(duì)用戶(hù)庫(kù)的搜索路徑。這個(gè)選項(xiàng)覆蓋了環(huán)境變量ARMLIB所指定的路徑。參數(shù)pathlist是一個(gè)以逗號(hào)分開(kāi)的多個(gè)路徑列表,即為path1, path2,... pathn,這個(gè)路徑列表只是用來(lái)搜索要用到的ARM庫(kù)函數(shù)。默認(rèn)的,對(duì)于包含ARM庫(kù)函數(shù)的默認(rèn)路徑是由環(huán)境變量ARMLIB所指定的。-scanlib 這個(gè)選項(xiàng)啟動(dòng)對(duì)默認(rèn)庫(kù)(標(biāo)準(zhǔn)ARM C和C++庫(kù))的掃描以解析引用的符號(hào)。這個(gè)選項(xiàng)是默認(rèn)的設(shè)置。-noscanlib 該選項(xiàng)禁止在鏈接時(shí)候掃描默認(rèn)的庫(kù)。-locals這個(gè)選項(xiàng)指導(dǎo)鏈接器在生成一個(gè)可執(zhí)行映像文件的時(shí)候,將本地符號(hào)添加到輸出符號(hào)信息表中。該選項(xiàng)是默認(rèn)設(shè)置。-nolocals這個(gè)選項(xiàng)指導(dǎo)鏈接器在生成一個(gè)可執(zhí)行映像文件的時(shí)候,不要將本地符號(hào)添加到輸出符號(hào)信息表中。如果想減小輸出符號(hào)表的大小,可以使用該選項(xiàng)。-callgraph該選項(xiàng)創(chuàng)建一個(gè)HTML格式的靜態(tài)函數(shù)調(diào)用圖。這個(gè)調(diào)用圖給出了映像文件中所有函數(shù)的定義和引用信息。對(duì)于每一個(gè)函數(shù)它列出了:1.  函數(shù)編譯時(shí)候的處理器狀態(tài)(ARM狀態(tài)還是Thumb狀態(tài));2.       調(diào)用func函數(shù)的集合;3.       被func調(diào)用的函數(shù)的集合;4.       在映像文件中使用的func尋址的次數(shù)。此外,調(diào)用圖還標(biāo)識(shí)了下面的函數(shù):1.       被interworking veneers所調(diào)用的函數(shù);2.       在映像文件外部定義的函數(shù);3.       允許未被定義的函數(shù)(以weak方式的引用);靜態(tài)調(diào)用圖還提供了堆棧使用信息,它顯示出了:1.       每個(gè)函數(shù)所使用的堆棧大;2.       在全部的函數(shù)調(diào)用中,所用到的最大堆棧大小。-info topics這個(gè)選項(xiàng)打印出關(guān)于指定種類(lèi)的信息,這里的參數(shù)topics是指用逗號(hào)間隔的類(lèi)型標(biāo)識(shí)符列表。類(lèi)型標(biāo)識(shí)符列表可以是下面所列出的任意一個(gè):1.  sizes為在映像文件中的每一個(gè)輸入對(duì)象和庫(kù)成員列出了代碼和數(shù)據(jù)(這里的數(shù)據(jù)包括,RO數(shù)據(jù),RW數(shù)據(jù),ZI 數(shù)據(jù)和Debug 數(shù)據(jù))的大小;2.  totals為輸入對(duì)象文件和庫(kù),列出代碼和數(shù)據(jù)(這里的數(shù)據(jù)包括,RO數(shù)據(jù),RW數(shù)據(jù),ZI 數(shù)據(jù)和Debug 數(shù)據(jù)) 總的大小;3.       veneers給出由armlink生成的veneers的詳細(xì)信息;4.       unused列出由于使用-remove選項(xiàng)而從映像文件中被刪除的所有未使用段。注意:在信息類(lèi)型標(biāo)識(shí)符列表之間不能存在空格,比如可以輸入-info sizes,totals 但是不能是-info sizes, totals(即在逗號(hào)和totals之間有空格是不允許的)-map這個(gè)選項(xiàng)創(chuàng)建映像文件的信息圖。映像文件信息圖包括映像文件中的每個(gè)加載域,運(yùn)行域和輸入段的大小和地址,這里的輸入段還包括調(diào)試信息和鏈接器產(chǎn)生的輸入段。-symbols這個(gè)選項(xiàng)列出了鏈接的時(shí)候使用的每一個(gè)局部和全局符號(hào)。該符號(hào)還包括鏈接生成的符號(hào)。-symdefs file這個(gè)選項(xiàng)創(chuàng)建一個(gè)包含來(lái)自輸出映像文件的全局符號(hào)定義的符號(hào)定義文件。默認(rèn)的,所有的全局符號(hào)都寫(xiě)入到符號(hào)定義文件中。如果文件file已經(jīng)存在,鏈接器將限制生成在已存在的symdefs文件中已列出的符號(hào)。如果文件file沒(méi)有指明路徑信息,鏈接器將在輸出映像文件的路徑搜索文件。如果文件沒(méi)有找到,就會(huì)在該目錄下面創(chuàng)建文件。在鏈接另一個(gè)映像文件的時(shí)候,可以將符號(hào)定義文件作為鏈接的輸入文件。-edit file這個(gè)選項(xiàng)指定一個(gè)steering 類(lèi)型的文件,該文件包含用于修改輸出文件中的符號(hào)信息表的命令?梢栽趕teering文件中指定具有以下功能的命令:隱藏全局符號(hào)。使用該選項(xiàng)可以在目標(biāo)文件中隱藏指定的全局符號(hào)。重命名全局符號(hào)。使用這個(gè)選項(xiàng)可以解決符號(hào)命名沖突的現(xiàn)象。-xref該選項(xiàng)列出了在輸入段間的所有交叉引用。-xreffrom object(section)這個(gè)選項(xiàng)列出了從目標(biāo)文件中的輸入段對(duì)其他輸入段的交叉引用。如果想知道某個(gè)指定的輸入段中的引用情況,就可以使用該選項(xiàng)。-xrefto object(section)該選項(xiàng)列出了從其他輸入段到目標(biāo)文件輸入段的引用。-errors file     使用該選項(xiàng)會(huì)將診斷信息從標(biāo)準(zhǔn)輸出流重定向到文件file中。-list file該選項(xiàng)將-info,-map,-symbols,-xref,-xreffrom和 –xrefto這幾個(gè)選項(xiàng)的輸出重新定向到文件file中。如果文件file沒(méi)有指定路徑信息,就會(huì)在輸出路徑創(chuàng)建該文件,該路徑是輸出映像文件所在的路徑。-verbose這個(gè)選項(xiàng)將有關(guān)鏈接操作的細(xì)節(jié)打印出來(lái),包括所包括的目標(biāo)文件和要用到的庫(kù)。-unmangled該選項(xiàng)指定鏈接器在由xref,-xreffrom,-xrefto,和-symbols所生成的診斷信息中顯示出unmangled C++符號(hào)名。如果使用了這個(gè)選項(xiàng),鏈接器將unmangle C++符號(hào)名以源碼的形式顯示出來(lái)。這個(gè)選項(xiàng)是默認(rèn)的。-mangled這個(gè)選項(xiàng)指定鏈接器顯示由-xref,-xreffrom,-xrefto,和-symbols所產(chǎn)生的診斷信息中的mangled C++符號(hào)名。如果使用了該選項(xiàng),鏈接器就不會(huì)unmangle C++符號(hào)名了。符號(hào)名是按照它們?cè)谀繕?biāo)符號(hào)表中顯示的格式顯示的。-via file該選項(xiàng)表示從文件file中讀取輸入文件名列表和鏈接器選項(xiàng)。在armlink命令行可以輸入多個(gè)-via選項(xiàng),當(dāng)然,-via選項(xiàng)也能夠不含在一個(gè)via文件中。-strict這個(gè)選項(xiàng)告訴鏈接器報(bào)告可能導(dǎo)致錯(cuò)誤而不是警告的條件。-unresolved symbol這個(gè)選項(xiàng)將未被解析的符號(hào)指向全局符號(hào)symbol。Symbol必須是已定義的全局符號(hào),否則,symbol會(huì)當(dāng)作一個(gè)未解析的符號(hào),鏈接將以失敗告終。這個(gè)選項(xiàng)在自上而下的開(kāi)發(fā)中尤為有用,在這種情況下,通過(guò)將無(wú)法指向相應(yīng)函數(shù)的引用指向一個(gè)偽函數(shù)的方法,可以測(cè)試一個(gè)部分實(shí)現(xiàn)的系統(tǒng)。該選項(xiàng)不會(huì)顯示任何警告信息。input-file-list這是一個(gè)以空格作為間隔符的目標(biāo)或庫(kù)的列表。有一類(lèi)特殊的目標(biāo)文件,即symdef文件,也可以包含在文件列表中,為生成的映像文件提供全局的symbol值。在輸入文件列表中有兩種使用庫(kù)的方法。1.  指定要從庫(kù)中提取并作為目標(biāo)文件添加到映像文件中的特定的成員。2.  指定某庫(kù)文件,鏈接器根據(jù)需要從其中提取成員。armlink按照以下的順序處理輸入文件列表:1.  無(wú)條件的添加目標(biāo)文件2.  使用匹配模式從庫(kù)中選擇成員加載到映像文件中去。例如使用下面的命令:armlink main.o mylib(stdio.o) mylib(a*.o). 將會(huì)無(wú)條件的把mylib庫(kù)中所有的以字母a開(kāi)頭的目標(biāo)文件和stdio.o在鏈接的時(shí)候鏈接到生成的映像文件中去。3.  添加為解析尚未解析的引用的庫(kù)到庫(kù)文件列表。

 8.1.2  ARM運(yùn)行時(shí)庫(kù)

本小節(jié)為讀者介紹一下ARM C/C++庫(kù)方面的相關(guān)內(nèi)容。
8.1.2.1  運(yùn)行時(shí)庫(kù)類(lèi)型和建立選項(xiàng)
ADS提供以下的運(yùn)行時(shí)庫(kù)來(lái)支持被編譯的C和C++代碼:ANSI C庫(kù)函數(shù):這個(gè)C函數(shù)庫(kù)是由以下幾部分組成:1.  在ISO C標(biāo)準(zhǔn)中定義的函數(shù);2.  在semihosted環(huán)境下(semihosting是針對(duì)ARM目標(biāo)機(jī)的一種機(jī)制,它能夠根據(jù)應(yīng)用程序代碼的輸入/輸出請(qǐng)求,與運(yùn)行有調(diào)試功能的主機(jī)通訊。這種技術(shù)允許主機(jī)為通常沒(méi)有輸入和輸出功能的目標(biāo)硬件提供主機(jī)資源)用來(lái)實(shí)現(xiàn)C庫(kù)函數(shù)的與目標(biāo)相關(guān)的函數(shù);3.  被C和C++編譯器所調(diào)用的支持函數(shù)。ARM C 庫(kù)提供了額外的一些部件支持C++,并為不同的結(jié)構(gòu)體系和處理器編譯代碼。 C++庫(kù)函數(shù):C++庫(kù)函數(shù)包含由ISO C++庫(kù)標(biāo)準(zhǔn)定義的函數(shù)。C++庫(kù)依賴(lài)于相應(yīng)的C庫(kù)實(shí)現(xiàn)與特定目標(biāo)相關(guān)的部分,在C++庫(kù)的內(nèi)部本身是不包含與目標(biāo)相關(guān)的部分。這個(gè)庫(kù)是由以下幾部分組成的:1.  版本為2.01.01的Rogue Wave Standard C++庫(kù);2.  C++編譯器使用的支持函數(shù);3.  Rogue Wave庫(kù)所不支持的其他的C++函數(shù)。正如上面所說(shuō),ANSI C庫(kù)使用標(biāo)準(zhǔn)的ARM semihosted 環(huán)境提供例如,文件輸入/輸出的功能。Semihosting是由已定義的軟件中斷(Software Interrupt)操作來(lái)實(shí)現(xiàn)的。在大多數(shù)的情況下,semihosting SWI是被庫(kù)函數(shù)內(nèi)部的代碼所觸發(fā),用于調(diào)試的代理程序處理SWI異常。調(diào)試代理程序?yàn)橹鳈C(jī)提供所需要的通信。Semihosted被ARMulator ,Angel和Multi-ICE所支持。用戶(hù)可以使用在ADS軟件中的ARM開(kāi)發(fā)工具去開(kāi)發(fā)用戶(hù)應(yīng)用程序,然后在ARMulator或在一個(gè)開(kāi)發(fā)板上運(yùn)行和調(diào)試該程序。用戶(hù)可以把C庫(kù)中的與目標(biāo)相關(guān)的函數(shù)作為自己應(yīng)用程序中的一部分,重新進(jìn)行代碼的實(shí)現(xiàn)。這就為用戶(hù)帶來(lái)了極大的方便,用戶(hù)可以根據(jù)自己的執(zhí)行環(huán)境,適當(dāng)?shù)牟眉鬋庫(kù)函數(shù)。除此之外,用戶(hù)還可以針對(duì)自己的應(yīng)用程序的要求,對(duì)與目標(biāo)無(wú)關(guān)的庫(kù)函數(shù)進(jìn)行適當(dāng)?shù)牟眉。在C庫(kù)中有很多函數(shù)是獨(dú)立于其他函數(shù)的,并且與目標(biāo)硬件沒(méi)有任何依賴(lài)關(guān)系。對(duì)于這類(lèi)函數(shù),用戶(hù)可以很容易地從匯編代碼中使用它們。在建立自己的用戶(hù)應(yīng)用程序的時(shí)候,用戶(hù)必須指定一些最基本的操作選項(xiàng)。例如:字節(jié)順序,是大端模式(big endian:字?jǐn)?shù)據(jù)的高字節(jié)存放在低地址,低字節(jié)存放在高地址),還是小端模式(little endian:字?jǐn)?shù)據(jù)的高字節(jié)存放在高地址,低字節(jié)存放在低地址);浮點(diǎn)支持:可能是FPA,VFP,軟件浮點(diǎn)處理或不支持浮點(diǎn)運(yùn)算;堆棧限制:是否檢查堆棧溢出;位置無(wú)關(guān)(PID):數(shù)據(jù)是從與位置無(wú)關(guān)的代碼還是從與位置相關(guān)的代碼中讀/寫(xiě),代碼是位置無(wú)關(guān)的只讀代碼還是位置相關(guān)的的只讀代碼。當(dāng)用戶(hù)對(duì)匯編程序,C程序或C++程序進(jìn)行鏈接的時(shí)候,鏈接器會(huì)根據(jù)在建立時(shí)所指定的選項(xiàng),選擇適當(dāng)?shù)腃或C++運(yùn)行時(shí)庫(kù)的類(lèi)型。選項(xiàng)各種不同組合都有一個(gè)相應(yīng)的ANSI C庫(kù)類(lèi)型。
8.1.2.2  庫(kù)路徑結(jié)構(gòu)
庫(kù)路徑是在ADS軟件安裝路徑的lib目錄下的兩個(gè)子目錄。假設(shè),ADS軟件安裝在e:\arm\adsv1_2目錄,則在e:\arm\adsv1_2\lib目錄下的兩個(gè)子目錄armlib和cpplib是ARM的庫(kù)所在的路徑。armlib這個(gè)子目錄包含了ARM C 庫(kù),浮點(diǎn)代數(shù)運(yùn)算庫(kù),數(shù)學(xué)庫(kù)等各類(lèi)庫(kù)函數(shù)。與這些庫(kù)相應(yīng)的頭文件在e:\arm\adsv1_2\include目錄中。cpplib這個(gè)子目錄包含了Rogue Wave C++庫(kù)和C++支持函數(shù)庫(kù)。Rogue Wave C++庫(kù)和C++支持函數(shù)庫(kù)合在一起被稱(chēng)為ARM C++庫(kù)。與這些庫(kù)相應(yīng)的頭文件安裝在e:\arm\adsv1_2\include目錄下。環(huán)境變量ARMLIB必須被設(shè)置成指向庫(kù)路徑。另外一種指定ARM C和ARM C++庫(kù)路徑的方法是,在鏈接的時(shí)候使用操作選項(xiàng)-libpath directory(directory代表庫(kù)所在的路徑),來(lái)指明要裝載的庫(kù)的路徑。無(wú)需對(duì)armlib和cpplib這兩個(gè)庫(kù)路徑分開(kāi)指明,鏈接器會(huì)自動(dòng)從用戶(hù)所指明的庫(kù)路徑中找出這兩個(gè)子目錄。這里需要讓讀者特別注意的以下幾點(diǎn):1.         ARM C庫(kù)函數(shù)是以二進(jìn)制格式提供的;2.         ARM 庫(kù)函數(shù)禁止修改。如果讀者想對(duì)庫(kù)函數(shù)創(chuàng)建新的實(shí)現(xiàn)的話(huà),可以把這個(gè)新的函數(shù)編譯成目標(biāo)文件,然后在鏈接的時(shí)候把它包含進(jìn)來(lái)。這樣在鏈接的時(shí)候,使用的是新的函數(shù)實(shí)現(xiàn)而不是原來(lái)的庫(kù)函數(shù)。3.         通常情況下,為了創(chuàng)建依賴(lài)于目標(biāo)的應(yīng)用程序,在ANSI C庫(kù)中只有很少的幾個(gè)函數(shù)需要實(shí)現(xiàn)重建。4.         Rogue Wave Standard C++函數(shù)庫(kù)的源代碼不是免費(fèi)發(fā)布的,可以從Rogue Wave Software Inc.,或ARM公司通過(guò)支付許可證費(fèi)用來(lái)獲得源文件。

8.1.3  GUI開(kāi)發(fā)環(huán)境(Code Warrior和AXD)

8.1.3.1 CodeWarrior集成開(kāi)發(fā)環(huán)境
CodeWarrior for ARM是一套完整的集成開(kāi)發(fā)工具,充分發(fā)揮了ARM RISC 的優(yōu)勢(shì), 使產(chǎn)品開(kāi)發(fā)人員能夠很好的應(yīng)用尖端的片上系統(tǒng)技術(shù). 該工具是專(zhuān)為基于ARM RISC的處理器而設(shè)計(jì)的, 它可加速并簡(jiǎn)化嵌入式開(kāi)發(fā)過(guò)程中的每一個(gè)環(huán)節(jié),使得開(kāi)發(fā)人員只需通過(guò)一個(gè)集成軟件開(kāi)發(fā)環(huán)境就能研制出ARM產(chǎn)品,在整個(gè)開(kāi)發(fā)周期中,開(kāi)發(fā)人員無(wú)需離開(kāi)CodeWarrior開(kāi)發(fā)環(huán)境, 因此節(jié)省了在操做工具上花的時(shí)間,使得開(kāi)發(fā)人員有更多的精力投入到代碼編寫(xiě)上來(lái),CodeWarrior集成開(kāi)發(fā)環(huán)境(IDE)為管理和開(kāi)發(fā)項(xiàng)目提供了簡(jiǎn)單多樣化的圖形用戶(hù)界面。用戶(hù)可以使用ADS的CodeWarrior IDE為ARM和Thumb處理器開(kāi)發(fā)用C,C++,或ARM匯編語(yǔ)言的程序代碼。通過(guò)提供下面的功能,CodeWarrior IDE縮短了用戶(hù)開(kāi)發(fā)項(xiàng)目代碼的周期。1.       全面的項(xiàng)目管理功能;2.       子函數(shù)的代碼導(dǎo)航功能,使得用戶(hù)迅速找到程序中的子函數(shù)?梢栽贑odeWarrior IDE為ARM配置在8.1.1中介紹的各種命令工具,實(shí)現(xiàn)對(duì)工程代碼的編譯,匯編和鏈接。在CodeWarrior IDE中所涉及到的target有兩種不同的語(yǔ)義。目標(biāo)系統(tǒng)(Target system)是特指代碼要運(yùn)行的環(huán)境,是基于ARM的硬件。比如,要為ARM開(kāi)發(fā)板上編寫(xiě)要運(yùn)行在它上面的程序,這個(gè)開(kāi)發(fā)板就是目標(biāo)系統(tǒng)。生成目標(biāo)(Build target)是指用于生成特定的目標(biāo)文件的選項(xiàng)設(shè)置(包括匯編選項(xiàng),編譯選項(xiàng),鏈接選項(xiàng)以及鏈接后的處理選項(xiàng))和所用的文件的集合。CodeWarrior IDE 能夠讓用戶(hù)將源代碼文件,庫(kù)文件還有其他相關(guān)的文件以及配置設(shè)置等放在一個(gè)工程中。每個(gè)工程可以創(chuàng)建和管理生成目標(biāo)設(shè)置的多個(gè)配置。例如,要編譯一個(gè)包含調(diào)試信息的生成目標(biāo)和一個(gè)基于ARM7TDMI的硬件優(yōu)化生成目標(biāo),生成目標(biāo)可以在同一個(gè)工程中共享文件,同時(shí)使用各自的設(shè)置。CodeWarrior IDE為用戶(hù)提供下面的功能:源代碼編輯器,它集成在CodeWarrior IDE的瀏覽器中,能夠根據(jù)語(yǔ)法格式,使用不同的顏色顯示代碼;源代碼瀏覽器,它保存了在源碼中定義的所有符號(hào),能夠使用戶(hù)在源碼中快速方便的跳轉(zhuǎn);查找和替換功能,用戶(hù)可以在多個(gè)文件中,利用字符串通配符,進(jìn)行字符串的搜索和替換;文件比較功能,可以使用戶(hù)比較路徑中的不同文本文件的內(nèi)容。ADS的CodeWarrior IDE是基于Metrowerks CodeWarrior IDE 4.2版本的。它經(jīng)過(guò)適當(dāng)?shù)牟眉粢灾С諥DS工具鏈。針對(duì)ARM的配置面板為用戶(hù)提供了在CodeWarrior IDE集成環(huán)境下配置各種ARM開(kāi)發(fā)工具的能力,這樣用戶(hù)可以不用在命令控制臺(tái)下就能夠使用在8.1.1和將在8.1.4中介紹的各種命令。以ARM為目標(biāo)平臺(tái)的工程創(chuàng)建向?qū),可以使用?hù)以此為基礎(chǔ),快速創(chuàng)建ARM和Thumb工程。盡管大多數(shù)的ARM工具鏈已經(jīng)集成在CodeWarrior IDE,但是仍有許多功能在該集成環(huán)境中沒(méi)有實(shí)現(xiàn),這些功能大多數(shù)是和調(diào)試相關(guān)的,因?yàn)锳RM的調(diào)試器沒(méi)有集成到CodeWarrior IDE中。由于ARM調(diào)試器(AXD)沒(méi)有集成在CodeWarrior IDE中,這就意味著,用戶(hù)不能在CodeWarrior IDE中進(jìn)行斷點(diǎn)調(diào)試和查看變量。對(duì)于熟悉CodeWarrior IDE的用戶(hù)會(huì)發(fā)現(xiàn),有許多的功能已經(jīng)從CodeWarrior IDE For ARM中移走,比如快速應(yīng)用程序開(kāi)發(fā)模板等。在CodeWarrior IDE For ARM中有很多的菜單或子菜單是不能使用的。下面介紹一下這些不能使用的選項(xiàng)。1.        View菜單下不能使用的菜單選項(xiàng)有:Processes,Expressions,Global Variable,Breakpoints,Registers。2.  Project菜單不能使用的菜單選項(xiàng):Precompile子菜單。因?yàn)锳RM編譯器不支持預(yù)編譯的頭文件。3.  Debug菜單該菜單中沒(méi)有一個(gè)子菜單是可以使用的。4.  Browser菜單中不能使用的菜單選項(xiàng):New Property,New Method和New Event Set。5.  Help menu中不能用于ADS的菜單選項(xiàng)有:CodeWarrior Help,Index,Search和Online Manuals。有關(guān)CodeWarrior IDE中一些常用菜單的使用,將在后面的舉例中具體說(shuō)明的,在此,不在贅述。
8.1.3.2  ADS調(diào)試器
調(diào)試器本身是一個(gè)軟件,用戶(hù)通過(guò)這個(gè)軟件使用debug agent可以對(duì)包含有調(diào)試信息的,正在運(yùn)行的可執(zhí)行代碼進(jìn)行比如變量的查看,斷點(diǎn)的控制等調(diào)試操作。ADS中包含有3個(gè)調(diào)試器:AXD(ARM eXtended Debugger):ARM擴(kuò)展調(diào)試器;armsd(ARM Symbolic Debugger):ARM符號(hào)調(diào)試器;與老版本兼容的Windows或Unix下的ARM調(diào)試工具,ADW/ADU(Application Debugger Windows/Unix)。下面對(duì)在調(diào)試映像文件中所涉及到的一些術(shù)語(yǔ)做一個(gè)簡(jiǎn)單的介紹。Debug target在軟件開(kāi)發(fā)的最初階段,可能還沒(méi)有具體的硬件設(shè)備。如果要測(cè)試所開(kāi)發(fā)的軟件是否達(dá)到了預(yù)期的效果,這可以由軟件仿真來(lái)完成。即使調(diào)試器和要測(cè)試的軟件運(yùn)行在同一臺(tái)PC上,也可以把目標(biāo)當(dāng)作一個(gè)獨(dú)立的硬件來(lái)看待。當(dāng)然,也可以搭建一個(gè)PCB板,這個(gè)板上可以包含一個(gè)或多個(gè)處理器,在這個(gè)板上可以運(yùn)行和調(diào)試應(yīng)用軟件。只有當(dāng)通過(guò)硬件或者是軟件仿真所得到的結(jié)果達(dá)到了預(yù)期的效果,才算是完成了應(yīng)用程序的編寫(xiě)工作。調(diào)試器能夠發(fā)送以下指令:1.       裝載映像文件到目標(biāo)內(nèi)存;2.       啟動(dòng)或停止程序的執(zhí)行;3.       顯示內(nèi)存,寄存器或變量的值;4.  允許用戶(hù)改變存儲(chǔ)的變量值。Debug agentDebug agent執(zhí)行調(diào)試器發(fā)出的命令動(dòng)作,比如:設(shè)置斷點(diǎn),從存儲(chǔ)器中讀數(shù)據(jù),把數(shù)據(jù)寫(xiě)到存儲(chǔ)器等。Debug agent既不是被調(diào)試的程序,也不是調(diào)試器。在ARM體系中,它有這幾種方式:Multi-ICE(Multi-processor in-circuit emulator),ARMulator和Angel。其中Multi-ICE是一個(gè)獨(dú)立的產(chǎn)品,是ARM公司自己的JTAG在線(xiàn)仿真器,不是由ADS提供的。AXD可以在Windows 和UNIX下,進(jìn)行程序的調(diào)試。它為用C,C++,和匯編語(yǔ)言編寫(xiě)的源代碼提供了一個(gè)全面的Windows 和UNIX 環(huán)境。在后面的章節(jié)中,會(huì)結(jié)合具體實(shí)例為讀者介紹如何使用AXD調(diào)試器。

8.1.4       實(shí)用程序

ADS提供以下的實(shí)用工具來(lái)配合前面介紹的命令行開(kāi)發(fā)工具的使用fromELF這是ARM映像文件轉(zhuǎn)換工具。該命令將ELF格式的文件作為輸入文件,將該格式轉(zhuǎn)換為各種輸出格式的文件,包括plain binary(BIN格式映像文件), Motorola 32-bit S-record format(Motorola 32位S格式映像文件), Intel Hex 32 format(Intel 32位格式映像文件),和 Verilog-like hex format(Verilog 16進(jìn)制文件)。FromELF命令也能夠?yàn)檩斎胗诚裎募a(chǎn)生文本信息,例如代碼和數(shù)據(jù)長(zhǎng)度。armarARM庫(kù)函數(shù)生成器將一系列ELF格式的目標(biāo)文件以庫(kù)函數(shù)的形式集合在一起,用戶(hù)可以把一個(gè)庫(kù)傳遞給一個(gè)鏈接器以代替幾個(gè)ELF文件。Flash downloader用于把二進(jìn)制映像文件下載到ARM開(kāi)發(fā)板上的Flash存儲(chǔ)器的工具

8.1.5  支持的軟件

ADS為用戶(hù)提供下面的軟件,使用戶(hù)可以在軟件仿真的環(huán)境下或者在基于ARM的硬件環(huán)境調(diào)試用戶(hù)應(yīng)用程序。ARMulator這是一個(gè)ARM指令集仿真器,集成在ARM的調(diào)試器AXD中,它提供對(duì)ARM處理器的指令集的仿真,為ARM和Thumb提供精確的模擬。用戶(hù)可以在硬件尚未做好的情況下,開(kāi)發(fā)程序代碼。

8.2  使用ADS創(chuàng)建工程

本節(jié)通過(guò)一個(gè)具體實(shí)例,為讀者介紹如何使用該集成開(kāi)發(fā)環(huán)境,利用CodeWarrior提供的建立工程的模板建立自己的工程,并學(xué)會(huì)如何進(jìn)行編譯鏈接,生成包含調(diào)試信息的映像文件和可以直接燒寫(xiě)的Flash中的.bin格式的二進(jìn)制可執(zhí)行文件。

8.2.1  建立一個(gè)工程

工程將所有的源碼文件組織在一起,并能夠決定最終生成文件存放的路徑,輸出的格式等。在CodeWarrior中新建一個(gè)工程的方法有兩種,可以在工具欄中單擊“New”按鈕,也可以在“File”菜單中選擇“New…”菜單。這樣就會(huì)打開(kāi)一個(gè)如圖8.1所示的對(duì)話(huà)框。圖8.1  新建工程對(duì)話(huà)框在這個(gè)對(duì)話(huà)框中為用戶(hù)提供了7種可選擇的工程類(lèi)型。ARM Executabl Image:用于由ARM指令的代碼生成一個(gè)ELF格式的可執(zhí)行映像文件;ARM Object Library:用于由ARM指令的代碼生成一個(gè)armar格式的目標(biāo)文件庫(kù);Empty Project:用于創(chuàng)建一個(gè)不包含任何庫(kù)或源文件的工程;Makefile Importer Wizard:用于將Visual C的nmake或GNU make文件轉(zhuǎn)入到CodeWarrior IDE 工程文件;Thumb ARM Executable Image:用于由ARM指令和Thumb指令的混和代碼生成一個(gè)可執(zhí)行的ELF格式的映像文件;Thumb Executable image:用于由Thumb指令創(chuàng)建一個(gè)可執(zhí)行的ELF格式的映像文件;Thumb Object Library:用于由Thumb指令的代碼生成一個(gè)armar格式的目標(biāo)文件庫(kù)。在這里選擇ARM Executable Image,在“Project name:”中輸入工程文件名,本例為“l(fā)edcircle”,點(diǎn)擊“Location:”文本框的“Set…”按鈕,瀏覽選擇想要將該工程保存的路徑,將這些設(shè)置好后,點(diǎn)擊“確定”,即可建立一個(gè)新的名為ledcircle的工程。這個(gè)時(shí)候會(huì)出現(xiàn)ledcircle.mcp的窗口,如圖8.2所示,有三個(gè)標(biāo)簽頁(yè),分別為files,link order,target默認(rèn)的是顯示第一個(gè)標(biāo)簽頁(yè)files。通過(guò)在該標(biāo)簽頁(yè)點(diǎn)擊鼠標(biāo)右鍵,選中“Add Files…”可以把要用到的源程序添加到工程中。圖8.2  新建工程打開(kāi)窗口對(duì)于本例,由于所有的源文件都還沒(méi)有建立,所以首先需要新建源文件。在“File”菜單中選擇“New”,在打開(kāi)的如圖8.1所示的對(duì)話(huà)框中,選擇標(biāo)簽頁(yè)File,在File name中輸入要?jiǎng)?chuàng)建的文件名,輸入“Init.s”,點(diǎn)擊“確定”關(guān)閉窗口。在打開(kāi)的文件編輯框中輸入下面的匯編代碼:;**************************************************************;Chinese Academy of Sciences, Institute of Automation;File Name:    Init.s;Description:  ;Author:       JuGuang.Li;Date:         ;**************************************************************  IMPORT      Main  AREA    Init,CODE,READONLY  ENTRY  LDR R0, =0x3FF0000        LDR R1, =0xE7FFFF80 ;配置SYSCFG,片內(nèi)4K Cache,4K SRAM  STR     R1, [R0]          LDR SP, =0x3FE1000  ;SP指向4K SRAM的尾地址,堆棧向下生成  BL      Main  B       .  END在這段代碼中,偽操作IMPORT告訴編譯器符號(hào)Main不是在該文件中定義的,而是在其他源文件中定義的符號(hào),但是本源文件中可能要用到該符號(hào)。接下來(lái)用偽指令A(yù)REA定義段名為Init的段為只讀的代碼段,偽指令ENTRY指出了程序的入口點(diǎn)。下面就是用匯編指令實(shí)現(xiàn)了配置SYSCFG特殊功能寄存器,將S3C4510B片內(nèi)的8K一體化的SRAM配置為4K Cache,4K SRAM,并將用戶(hù)堆棧設(shè)置在片內(nèi)的SRAM中。4K SRAM的地址為0x3FE,0000~(0x3FE,1000-1),由于S3C4510B的堆棧由高地址向低地址生成,將SP初始化為0x3FE,1000。完成上述操作后,程序跳轉(zhuǎn)到Main函數(shù)執(zhí)行。保存Init.s匯編程序。用同樣的方法,再建立一個(gè)名為main.c的C源代碼文件。具體代碼內(nèi)容如下://*****************************************************************//Chinese Academy of Sciences, Institute of Automation//File Name:   main.c//Description: //Author:      JuGuang.Li//Date:        //***************************************************************#define  IOPMOD    (*(volatile unsigned *)0x03FF5000) //IO port mode register#define  IOPDATA  (*(volatile unsigned *)0x03FF5008) //IO port data registervoid Delay(unsigned int);int Main(){unsigned long  LED;IOPMOD=0xFFFFFFFF;   //將IO口置為輸出模式IOPDATA=0x01;for(;;){      LED=IOPDATA;      LED=(LED<<1);      IOPDATA=LED;      Delay(10);      if(!(IOPDATA&0x0F))          IOPDATA=0x01;}return(0);    }void Delay(unsigned int x){unsigned int i,j,k;for(i=0;i<=x;i++)            for(j=0;j<0xff;j++)                for(k=0;k<0xff;k++);} 該段代碼首先將I/O模式寄存器設(shè)置為輸出模式,為I/O數(shù)據(jù)寄存器賦初值為0x1,通過(guò)將I/O數(shù)據(jù)寄存器的數(shù)值進(jìn)行周期性的左移,實(shí)現(xiàn)使接在P0~P3口的LED顯示器輪流被點(diǎn)亮的功能。(注意這里的if語(yǔ)句,是為了保證當(dāng)I/O數(shù)據(jù)寄存器中的數(shù)在移位過(guò)程中,第4位為數(shù)字“1”時(shí),使數(shù)字1通過(guò)和0xFF相與,又重新回到I/O數(shù)據(jù)寄存器的第0位,從而保證了數(shù)字1一直在I/O數(shù)據(jù)寄存器的低四位之間移位。)在這里還有一個(gè)細(xì)節(jié),希望讀者注意。在建立好一個(gè)工程時(shí),默認(rèn)的target是DebugRel,還有另外兩個(gè)可用的target,分別為Realse和Debug,這三個(gè)target的含義分別為:DebugRel:使用該目標(biāo),在生成目標(biāo)的時(shí)候,會(huì)為每一個(gè)源文件生成調(diào)試信息;Debug:使用該目標(biāo)為每一個(gè)源文件生成最完全的調(diào)試信息;Release:使用該目標(biāo)不會(huì)生成任何調(diào)試信息。在本例中,使用默認(rèn)的DebugRel目標(biāo)。現(xiàn)在已經(jīng)新建了兩個(gè)源文件,要把這兩個(gè)源文件添加到工程中去。為工程添加源碼常用的方法有兩種,既可以使用入圖8.2所示方法,也可以在“Project”菜單項(xiàng)中,選擇“Add Files…”,這兩種方法都會(huì)打開(kāi)文件瀏覽框,用戶(hù)可以把已經(jīng)存在的文件添加到工程中來(lái)。當(dāng)選中要添加的文件時(shí),會(huì)出現(xiàn)一個(gè)對(duì)話(huà)框,如圖8.3所示,詢(xún)問(wèn)用戶(hù)把文件添加到何類(lèi)目標(biāo)中,在這里,我們選擇DebugRel目標(biāo)。把剛才創(chuàng)建的兩個(gè)文件添加到工程中來(lái)。圖8.3  選擇添加文件到指定目標(biāo)到目前為止,一個(gè)完整的工程已經(jīng)建立。下面該對(duì)工程進(jìn)行編譯和鏈接工作。

8.2.2  編譯和鏈接工程

在進(jìn)行編譯和鏈接前,首先講述一下如何進(jìn)行生成目標(biāo)的配置。點(diǎn)擊Edit菜單,選擇“DebugRel Settings…”(注意,這個(gè)選項(xiàng)會(huì)因用戶(hù)選擇的不同目標(biāo)而有所不同),出現(xiàn)如圖8.2所示的對(duì)話(huà)框。這個(gè)對(duì)話(huà)框中的設(shè)置很多,在這里指介紹一些最為常用的設(shè)置選項(xiàng),讀者若對(duì)其他未涉及到的選項(xiàng)感興趣,可以查看相應(yīng)的幫助文件。1.       target設(shè)置選項(xiàng)Target Name文本框顯示了當(dāng)前的目標(biāo)設(shè)置。Linker選項(xiàng)供用戶(hù)選擇要使用的鏈接器。在這里默認(rèn)選擇的是ARM Linker,使用該鏈接器,將使用armlink鏈接編譯器和匯編器生成的工程中的文件相應(yīng)的目標(biāo)文件。 圖8.4  DebugRel設(shè)置對(duì)話(huà)框這個(gè)設(shè)置中還有兩個(gè)可選項(xiàng),None不是不用任何鏈接器,如果使用它,則工程中的所有文件都不會(huì)被編譯器或匯編器處理。ARM Librarian表示將編譯或匯編得到的目標(biāo)文件轉(zhuǎn)換為ARM庫(kù)文件。對(duì)于本例,使用默認(rèn)的鏈接器ARM Linker。Pre-linker:目前CodeWarrior IDE不支持該選項(xiàng)。Post-Linker:選擇在鏈接完成后,還要對(duì)輸出文件進(jìn)行的操作。因?yàn)樵诒纠,希望生成一個(gè)可以燒寫(xiě)到Flash中去的二進(jìn)制代碼,所以在這里選擇ARM fromELF,表示在鏈接生成映像文件后,再調(diào)用FromELF命令將含有調(diào)試信息的ELF格式的映像文件轉(zhuǎn)換成其他格式的文件。2.       Language Settings因?yàn)楸纠邪袇R編源代碼,所以要用到匯編器。首先看ARM匯編器。這個(gè)匯編器實(shí)際就說(shuō)在8.1節(jié)中談到的armasm,默認(rèn)的ARM體系結(jié)構(gòu)是ARM7TDMI,正好符合目標(biāo)板S3C4510B,無(wú)需改動(dòng)。字節(jié)順序默認(rèn)就是小端模式。其他設(shè)置,就用默認(rèn)值即可。還有一個(gè)需要注意的就是ARM C編譯器,它實(shí)際就是調(diào)用的命令行工具armcc。使用默認(rèn)的設(shè)置就可以了。細(xì)心的讀者可能會(huì)注意到,在設(shè)置框的右下腳,當(dāng)對(duì)某項(xiàng)設(shè)置進(jìn)行了修改,該行中的某個(gè)選項(xiàng)就會(huì)發(fā)生相應(yīng)的改動(dòng),如圖8.5所示。實(shí)際上,這行文字就顯示的是在8.1中介紹的相應(yīng)的編譯或鏈接選項(xiàng),由于有了CodeWarrior,開(kāi)發(fā)人員可以不用再去查看繁多的命令行選項(xiàng),只要在界面中選中或撤消某個(gè)選項(xiàng),軟件就會(huì)自動(dòng)生成相應(yīng)的代碼,為不習(xí)慣在DOS下鍵入命令行的用戶(hù)提供了極大的方便。3.       Linker設(shè)置鼠標(biāo)選中ARM Linker,出現(xiàn)如圖8.6所示對(duì)話(huà)框。這里詳細(xì)介紹該對(duì)話(huà)框的主要的標(biāo)簽頁(yè)選項(xiàng),因?yàn)檫@些選項(xiàng)對(duì)最終生成的文件有著直接的影響。在標(biāo)簽頁(yè)Output中,Linktype中提供了三種鏈接方式。Partial方式表示鏈接器只進(jìn)行部分鏈接,經(jīng)過(guò)部分鏈接生成的目標(biāo)文件,可以作為以后進(jìn)一步鏈接時(shí)的輸入文件。Simple方式是默認(rèn)的鏈接方式,也是最為頻繁使用的鏈接方式,它鏈接生成簡(jiǎn)單的ELF格式的目標(biāo)文件,使用的是鏈接器選項(xiàng)中指定的地址映射方式。Scattered方式使得鏈接器要根據(jù)scatter格式文件中指定的地址映射,生成復(fù)雜的ELF格式的映像文件。這個(gè)選項(xiàng)一般情況圖8.5  命令行工具選項(xiàng)設(shè)置圖8.6  鏈接器設(shè)置下,使用不太多。因?yàn)槲覀兯e的例子比較簡(jiǎn)單,選擇Simple方式就可以了。在選中Simple方式后,就會(huì)出現(xiàn)Simple image。RO Base:這個(gè)文本框設(shè)置包含有RO段的加載域和運(yùn)行域?yàn)橥粋(gè)地址。默認(rèn)是0x8000。這里用戶(hù)要根據(jù)自己硬件的實(shí)際SDRAM的地址空間來(lái)修改這個(gè)地址,保證在這里填寫(xiě)的地址,是程序運(yùn)行時(shí),SDRAM地址空間所能覆蓋的地址。針對(duì)本書(shū)所介紹的目標(biāo)板,就可以使用這個(gè)默認(rèn)地址值。RW Base:這個(gè)文本框設(shè)置了包含RW和ZI輸出段的運(yùn)行域地址。如果選中split選項(xiàng),鏈接器生成的映像文件將包含兩個(gè)加載域和兩個(gè)運(yùn)行域,此時(shí),在RW Base中所輸入的地址為包含RW和ZI輸出段的域設(shè)置了加載域和運(yùn)行域地址Ropi:選中這個(gè)設(shè)置將告訴鏈接器使包含有RO輸出段的運(yùn)行域位置無(wú)關(guān)。使用這個(gè)選項(xiàng),鏈接器將保證下面的操作:檢查各段之間的重定址是否有效;確保任何由armlink自身生成的代碼是只讀位置無(wú)關(guān)的。Rwpi:選中該選項(xiàng)將會(huì)告訴鏈接器使包含RW和ZI輸出段的運(yùn)行域位置無(wú)關(guān)。如果這個(gè)選項(xiàng)沒(méi)有被選中,域就標(biāo)識(shí)為絕對(duì)。每一個(gè)可寫(xiě)的輸入段必須是讀寫(xiě)位置無(wú)關(guān)的。如果這個(gè)選項(xiàng)被選中,鏈接器將進(jìn)行下面的操作,檢查可讀/可寫(xiě)屬性的運(yùn)行域的輸入段是否設(shè)置了位置無(wú)關(guān)屬性;檢查在各段之間的重地址是否有效;在Region$$Table和ZISection$$Table中添加基于靜態(tài)存儲(chǔ)器sb的選項(xiàng)。該選項(xiàng)要求RW Base有值,如果沒(méi)有給它指定數(shù)值的話(huà),默認(rèn)為0值。Split Image:選擇這個(gè)選項(xiàng)把包含RO和RW的輸出段的加載域分成2個(gè)加載域:一個(gè)是包含RO輸出段的域,一個(gè)是包含RW輸出段的域。這個(gè)選項(xiàng)要求RW Base有值,如果沒(méi)有給RW Base選項(xiàng)設(shè)置,則默認(rèn)是-RW Base 0。Relocatable:選擇這個(gè)選項(xiàng)保留了映像文件的重定址偏移量。這些偏移量為程序加載器提供了有用信息。在Options選項(xiàng)中,需要讀者引起注意的是Image entry point文本框。它指定映像文件的初始入口點(diǎn)地址值,當(dāng)映像文件被加載程序加載時(shí),加載程序會(huì)跳轉(zhuǎn)到該地址處執(zhí)行。如果需要,用戶(hù)可以在這個(gè)文本框中輸入下面格式的入口點(diǎn):入口點(diǎn)地址:這是一個(gè)數(shù)值,例如-entry 0x0符號(hào):該選項(xiàng)指定映像文件的入口點(diǎn)為該符號(hào)所代表的地址處,比如:-entry int_handler如果該符號(hào)有多處定義存在,armlink將產(chǎn)生出錯(cuò)信息。offset+object(section):該選項(xiàng)指定在某個(gè)目標(biāo)文件的段的內(nèi)部的某個(gè)偏移量處為映像文件的入口地址,例如:-entry 8+startup(startupseg)在此處指定的入口點(diǎn)用于設(shè)置ELF映像文件的入口地址。需要引起注意的是,這里不可以用符號(hào)main作為入口點(diǎn)地址符號(hào),否則將會(huì)出現(xiàn)類(lèi)似“Image dose not have an entry point(Not specified or not set due to multiple choice)”的錯(cuò)誤信息。關(guān)于ARM Linker的設(shè)置還有很多,對(duì)于想進(jìn)一步深入了解的讀者,可以查看幫助文件,都有很詳細(xì)的介紹。在Linker下還有一個(gè)ARM fromELF,如圖8.7所示:fromELF就是在8.1節(jié)中介紹的一個(gè)實(shí)用工具,它實(shí)現(xiàn)將鏈接器,編譯器或匯編器的輸出代碼進(jìn)行格式轉(zhuǎn)換的功能。例如,將ELF格式的可執(zhí)行映像文件轉(zhuǎn)換成可以燒寫(xiě)到ROM的二進(jìn)制格式文件;對(duì)輸出文件進(jìn)行反匯編,從而提取出有關(guān)目標(biāo)文件的大小,符號(hào)和字符串表以及重定址等信息。只有在Target設(shè)置中選擇了Post-linker,才可以使用該選項(xiàng)。在Output format下拉框中,為用戶(hù)提供了多種可以轉(zhuǎn)換的目標(biāo)格式,本例選擇Plain binary,這是一個(gè)二進(jìn)制格式的可執(zhí)行文件,可以被燒些的目標(biāo)板的Flash中。在Output file name文本域輸入期望生成的輸出文件存放的路徑,或通過(guò)點(diǎn)擊Choose...按鈕從文件對(duì)話(huà)框中選擇輸出文件。如果在這個(gè)文本域不輸入路徑名,則生成的二進(jìn)制文件存放在工程所在的目錄下。進(jìn)行好這些相關(guān)的設(shè)置后,以后在對(duì)工程進(jìn)行make的時(shí)候,CodeWarrior IDE 就會(huì)在鏈接完成后調(diào)用fromELF 來(lái)處理生成的映像文件。對(duì)于本例的工程而言,到此,就完成了make之前的設(shè)置工作了。圖8.7  ARM fromELF可選項(xiàng)點(diǎn)擊CodeWarrior IDE的菜單Project下的make菜單,就可以對(duì)工程進(jìn)行編譯和鏈接了。整個(gè)編譯鏈接過(guò)程如圖8.8所示:圖8.8  編譯和鏈接過(guò)程在工程ledcircle所在的目錄下,會(huì)生成一個(gè)名為:工程名_data目錄,在本例中就是ledcircle_data目錄,在這個(gè)目錄下不同類(lèi)別的目標(biāo)對(duì)應(yīng)不同的目錄。在本例中由于我們使用的是DebugRe目標(biāo),所以生成的最終文件都應(yīng)該在該目錄下。進(jìn)入到DebugRel目錄中去,讀者會(huì)看到make后生成的映像文件和二進(jìn)制文件,映像文件用于調(diào)試,二進(jìn)制文件可以燒寫(xiě)到S3C4510B的Flash中運(yùn)行。

8.2.3  使用命令行工具編譯應(yīng)用程序

如果用戶(hù)開(kāi)發(fā)的工程比較簡(jiǎn)單,或者只是想用到ADS提供的各種工具,但是并不想在CodeWarrior IDE中進(jìn)行開(kāi)發(fā)。在這種情況下,再為讀者介紹一種不在CodeWarrior IDE集成開(kāi)發(fā)環(huán)境下,開(kāi)發(fā)用戶(hù)應(yīng)用程序的方法,當(dāng)然前提是用戶(hù)必須安裝了ADS軟件,因?yàn)樵诰幾g鏈接的過(guò)程中要用到ADS提供的各種命令工具。這種方法對(duì)于開(kāi)發(fā)包含較少源代碼的工程是比較實(shí)用的。首先用戶(hù)可以用任何編輯軟件(比如UltraEdit)編寫(xiě)8.2.1中所提到的兩個(gè)源文件Init.s和main.c。接下了,可以利用在第7章中介紹的makefile的知識(shí),編寫(xiě)自己的makefile文件。對(duì)于本例,編寫(xiě)的makefile文件(假設(shè)該makefile文件保存為ads_mk.mk)如下:PAT = e:/arm/adsv1_2/binCC  = $(PAT)/armccLD      = $(PAT)/armlinkOBJTOOL = $(PAT)/fromelf RM  = $(PAT)/rm -fAS  = $(PAT)/armasm -keep -gASFILE  = e:/arm_xyexp/Init.sCFLAGS  = -g -O1  -Wa -DNO_UNDERSCORES=1  MODEL   = mainSRC     = $(MODEL).cOBJS    = $(MODEL).oall:    $(MODEL).axf  $(MODEL).bin  clean    %.axf:$(OBJS) Init.o     @echo "### Linking ..."    $(LD)  $(OBJS) Init.o -ro-base 0x8000  -entry Main -first Init.o  -o $@ -libpath e:/arm/adsv1_2/lib%.bin: %.axf        $(OBJTOOL) -c -bin -output $@ $<    $(OBJTOOL) -c -s -o $(<:.axf=.lst) $<    %.%.c     @echo "### Compiling $<"        $(CC) $(CFLAGS)  -c $< -o $@ clean:    $(RM) Init.o $(OBJS)由于ADS在安裝的時(shí)候沒(méi)有提供make命令,可以將在第7章中用到的make命令直接拷貝到ADS安裝路徑的bin目錄下,比如ADS安裝在目錄e:\arm\adsv1_2下, 可以將make命令拷貝到e:\arm\adsv1_2\bin目錄下,在command console下的編譯過(guò)程如圖8.9所示:圖8.9  在command console下編譯過(guò)程  經(jīng)過(guò)上述編譯鏈接,以及鏈接后的操作,在e:\arm_xyexp\ledcircle目錄下會(huì)生成兩個(gè)新的文件,main.axf和main.bin。用這種方式生成的文件與在CodeWarrior IDE界面通過(guò)各個(gè)選項(xiàng)的設(shè)置,生成的文件是一樣的。在所舉的例子中,都生成了包含有調(diào)試信息的可執(zhí)行映像文件,即以.axf結(jié)尾的文件。下面一節(jié)將介紹用如何用AXD對(duì)程序進(jìn)行源碼級(jí)的調(diào)試。

8.3  用AXD進(jìn)行代碼調(diào)試

AXD(ARM eXtended Debugger)是ADS軟件中獨(dú)立于CodeWarrior IDE的圖形軟件,打開(kāi)AXD軟件,默認(rèn)是打開(kāi)的目標(biāo)是ARMulator。這個(gè)也是調(diào)試的時(shí)候最常用的一種調(diào)試工具,本節(jié)主要是結(jié)合ARMulator介紹在AXD中進(jìn)行代碼調(diào)試的方法和過(guò)程,使讀者對(duì)AXD的調(diào)試有初步的了解。要使用AXD必須首先要生成包含有調(diào)試信息的程序,在8.2節(jié)中,已經(jīng)生成的ledcircle.axf或main.axf就是含有調(diào)試信息的可執(zhí)行ELF格式的映像文件。1.       在AXD中打開(kāi)調(diào)試文件在菜單File中選擇“Load image…”選項(xiàng),打開(kāi)Load Image對(duì)話(huà)框,找到要裝載的.axf映像文件,點(diǎn)擊“打開(kāi)”按鈕,就把映像文件裝載到目標(biāo)內(nèi)存中了。在所打開(kāi)的映像文件中會(huì)有一個(gè)藍(lán)色的箭頭指示當(dāng)前執(zhí)行的位置。對(duì)于本例,打開(kāi)映像文件后,如圖8.10所示:圖8.10  在axd下打開(kāi)映像文件在菜單Execute中選擇“Go”,將全速運(yùn)行代碼。要想進(jìn)行單步的代碼調(diào)試,在Execute菜單中選擇“Step”選項(xiàng),或用F10即可以單步執(zhí)行代碼,窗口中藍(lán)色箭頭會(huì)發(fā)生相應(yīng)的移動(dòng)。有時(shí)候,用戶(hù)可能希望程序在執(zhí)行到某處時(shí),查看一些所關(guān)心的變量值,此時(shí)可以通過(guò)斷點(diǎn)設(shè)置達(dá)到此要求。將光標(biāo)移動(dòng)到要進(jìn)行斷點(diǎn)設(shè)置的代碼處,在Execute菜單中,選擇“Toggle Breakpoint”或按F9,就會(huì)在光標(biāo)所在位置出現(xiàn)一個(gè)實(shí)心圓點(diǎn),表明該處為斷點(diǎn)。還可以在AXD中查看寄存器值,變量值,某個(gè)內(nèi)存單元的數(shù)值等等。下面就結(jié)合本章中的例子,介紹在AXD中調(diào)試過(guò)程。2.  查看存儲(chǔ)器內(nèi)容在程序運(yùn)行前,可以先查看兩個(gè)宏變量IOPMOD和IOPDATA的當(dāng)前值。方法是:從Processor Views菜單中選擇“Memory”選項(xiàng),如圖8.11所示。圖8.11  查看存儲(chǔ)器內(nèi)容在Memory Start address選擇框中,用戶(hù)可以根據(jù)要查看的存儲(chǔ)器的地址輸入起始地址,在下面的表格中會(huì)列出連續(xù)的64個(gè)地址。因?yàn)镮/O模式控制寄存器和I/O數(shù)據(jù)控制寄存器都是32位的控制寄存器,所以從0x3ff5000開(kāi)始的連續(xù)四個(gè)地址空間存放的是I/O模式控制寄存器的值,從圖8.11可以讀出該控制寄存器的值開(kāi)始為0xE7FF0010,I/O數(shù)據(jù)控制寄存器的內(nèi)容是從地址0x3FF5008開(kāi)始的連續(xù)四個(gè)地址空間存放的內(nèi)容。從圖8.11中可以看出IODATA中的初始值為0x E7FF0010,注意因?yàn)橛玫氖切《四J剑宰x數(shù)據(jù)的時(shí)候注意高地址中存放的是高字節(jié),低地址存放的是低字節(jié),F(xiàn)在對(duì)程序進(jìn)行單步調(diào)試,當(dāng)程序運(yùn)行到for循環(huán)處時(shí),可以再一次查看這兩個(gè)寄存器中的內(nèi)容,此時(shí)存儲(chǔ)器的內(nèi)容如圖8.12所示:圖8.12  單步運(yùn)行后的存儲(chǔ)器內(nèi)容從圖中可以看出運(yùn)行完兩個(gè)賦值語(yǔ)句后,兩個(gè)寄存器的內(nèi)容的確發(fā)生了變化,在地址0x3FF5000作為起始地址的連續(xù)四個(gè)存儲(chǔ)單元中,可以讀出I/O模式控制寄存器的內(nèi)容為0xFFFFFFFF,在地址0x3FF5008開(kāi)始的連續(xù)的四個(gè)存儲(chǔ)單元中,可以讀出I/O數(shù)據(jù)控制寄存器的內(nèi)容為0x00000001。3.  設(shè)置斷點(diǎn)可以在for循環(huán)體的“Delay(10);”語(yǔ)句處設(shè)置斷點(diǎn),將光標(biāo)定位在該語(yǔ)句處,使用快捷鍵F9在此處設(shè)置斷點(diǎn),按F5鍵,程序?qū)⑦\(yùn)行到斷點(diǎn)處,如果讀者想查看子函數(shù)Delay是如何運(yùn)行的,可以在Execute菜單中選擇“Step In”選項(xiàng),或按下F8鍵,進(jìn)入到子函數(shù)內(nèi)部進(jìn)行單步程序的調(diào)試。如圖8.13所示。4.  查看變量值在Delay函數(shù)的內(nèi)部,如果用戶(hù)希望查看某個(gè)變量的值,比如查看變量i的值,可以在Processor Views菜單中選擇“Watch”,會(huì)出現(xiàn)如圖8.14所示的watch窗口,然后用鼠標(biāo)選中變量i,點(diǎn)擊鼠標(biāo)郵件,在快捷菜單中選中“Add to watch”,如圖8.14所示,這樣變量i默認(rèn)是添加到watch窗口的Tab1中。程序運(yùn)行過(guò)程中,用戶(hù)可以看到變量i的值在不斷的圖8.13  設(shè)置斷點(diǎn)圖8.14  查看變量圖8.15  改變變量的格式變化。默認(rèn)顯示變量數(shù)值是以十六進(jìn)制格式顯示的,如果用戶(hù)對(duì)這種顯示格式不習(xí)慣的話(huà),可以通過(guò)在watch窗口點(diǎn)擊鼠標(biāo)右鍵,在彈出的快捷菜單中選擇“Format”選項(xiàng),如圖8.15所示,用戶(hù)可以選擇所查看的變量顯示數(shù)據(jù)的格式。如果用戶(hù)想從Delay函數(shù)中跳出到主函數(shù)中去,最簡(jiǎn)單的方法就是將光標(biāo)定位到你想跳轉(zhuǎn)到的主函數(shù)處,在Execute菜單中選擇“Run to Cursor”選項(xiàng),則程序會(huì)從Delay函數(shù)中跳轉(zhuǎn)到光標(biāo)所在位置。

8.4  本章小結(jié)

本章主要介紹了ADS軟件。首先介紹了ADS軟件的基本組成部分,接著重點(diǎn)地介紹了最常用的2個(gè)命令工具armcc和armlink的使用語(yǔ)法和各個(gè)操作選項(xiàng)。然后結(jié)合一個(gè)具體的應(yīng)用實(shí)例,介紹如何在CodeWarrior IDE環(huán)境下建立自己的新工程,編譯和鏈接工程生成可以調(diào)試的映像文件和二進(jìn)制文件的過(guò)程,同時(shí)補(bǔ)充了一種不在CodeWarrior IDE集成開(kāi)發(fā)環(huán)境下,利用第7章介紹的有關(guān)make的知識(shí),利用ADS提供的編譯和鏈接等命令工具編寫(xiě)自己的makefile文件,來(lái)開(kāi)發(fā)和編譯程序的方法。最后介紹了如何使用ADS的調(diào)試軟件AXD調(diào)試應(yīng)用程序。 
  • 上一篇: 嵌入式Linux下彩色LCD驅(qū)動(dòng)的設(shè)計(jì)與實(shí)現(xiàn)
  • 下一篇: 基于SoC的AC97技術(shù)硬件設(shè)計(jì)
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁(yè)  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話(huà):0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國(guó)行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營(yíng)許可證:浙B2-20080178-1
    楚雄市| 台北市| 文水县| 福清市| 岳阳市| 利津县| 两当县| 浠水县| 抚远县| 邢台市| 胶州市| 舒兰市| 中江县| 裕民县| 泉州市| 蓬溪县| 巫山县| 浦城县| 辽阳市| 元江| 宣城市| 晋江市| 南郑县| 高邮市| 长岛县| 和顺县| 通许县| 屯门区| 阿拉善盟| 绿春县| 海门市| 奈曼旗| 汉川市| 紫金县| 老河口市| 海丰县| 岳池县| 余庆县| 年辖:市辖区| 武威市| 且末县|