




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第5章DSP軟件程序設(shè)計基礎(chǔ)
5.1DSP軟件開發(fā)的一般過程
5.2DSP程序的編譯和鏈接原理5.3DSP應(yīng)用程序的構(gòu)成5.4DSP軟件調(diào)試環(huán)境簡介5.5DSP程序設(shè)計和調(diào)試實例
5.1DSP軟件開發(fā)的一般過程一個基于DSP技術(shù)的應(yīng)用系統(tǒng)的開發(fā)過程總體上可以分為硬件平臺開發(fā)和軟件程序設(shè)計兩個環(huán)節(jié)。與一般計算機(jī)應(yīng)用系統(tǒng)的開發(fā)一樣,系統(tǒng)硬件和軟件是彼此關(guān)聯(lián)、密不可分的,硬件開發(fā)過程和軟件開發(fā)過程是相互關(guān)聯(lián)的。在硬件開發(fā)中要考慮系統(tǒng)功能和軟件的運(yùn)行要求,在軟件設(shè)計中也要考慮系統(tǒng)硬件平臺條件,因此不能孤立地考慮軟件開發(fā)問題。圖5-1所示為基于DSP技術(shù)的應(yīng)用系統(tǒng)開發(fā)的一般過程。
圖5-1基于DSP技術(shù)的應(yīng)用系統(tǒng)開發(fā)的一般過程
軟件系統(tǒng)設(shè)計的第一步是對系統(tǒng)實現(xiàn)的功能和要求進(jìn)行全面的分析,根據(jù)系統(tǒng)功能和要求,結(jié)合硬件平臺的性能和功能,確定軟件方案。以各種圖表的形式給出軟件的方案,包括軟件的功能模塊構(gòu)成、組織關(guān)系及各模塊之間的調(diào)用關(guān)系。
第二步是根據(jù)各功能模塊的功能和性能要求選擇各模塊實現(xiàn)的算法。算法的選擇是模塊功能設(shè)計的關(guān)鍵環(huán)節(jié),不同算法的實現(xiàn)性能和效率有著根本的不同,算法的選擇直接從根本上制約了程序的性能。初步選擇了算法之后,還需要對算法進(jìn)行仿真,以確定算法的執(zhí)行結(jié)果是否正確,并對算法的執(zhí)行時間進(jìn)行估計,以確定能否達(dá)到系統(tǒng)的實時性要求。完成各功能模塊的算法仿真后,即可進(jìn)行各模塊的程序編寫。
第三步是根據(jù)確定的算法編寫程序。圖5-2給出了DSP系統(tǒng)程序編寫和調(diào)試的一般過程。程序編寫首先要選擇適當(dāng)?shù)木幊陶Z言。2000系列DSP和5000系列DSP的程序設(shè)計可以采用匯編語言,也可以采用C語言,還支持兩種語言的混合編程。一般來講,利用匯編語言編寫程序可以對系統(tǒng)硬件資源進(jìn)行更好的控制和安排,這樣容易實現(xiàn)更高的程序執(zhí)行效率;而利用C語言編寫程序,可以實現(xiàn)更短的軟件開發(fā)周期,程序也具有很好的移植性。因此一般的產(chǎn)品開發(fā)中選擇C語言編程,這樣可以有效地縮短開發(fā)周期,但對于需要反復(fù)循環(huán)運(yùn)行的核心算法則采用匯編語言編程,以獲得更高的程序性能。
圖5-2DSP系統(tǒng)程序編寫和調(diào)試的一般過程
由兩種語言編寫源程序的編譯過程略有不同,C語言編寫的源程序首先需要經(jīng)過C編譯器編譯為匯編程序,后面的編譯流程和匯編語言的處理過程相同。匯編源程序需要分別經(jīng)過匯編器和鏈接器進(jìn)行匯編和鏈接,生成目標(biāo)文件與可執(zhí)行文件,鏈接器生成的可執(zhí)行文件就可以加載到DSP系統(tǒng)中執(zhí)行了。具體的匯編和鏈接過程將會在5.2節(jié)中進(jìn)行較為詳細(xì)的介紹。
第四步是在軟件環(huán)境下對程序進(jìn)行調(diào)試。該步驟中首先利用相應(yīng)的調(diào)試軟件和仿真器在PC機(jī)上對程序進(jìn)行調(diào)試,主要完成對程序中的語法錯誤和計算錯誤進(jìn)行調(diào)試;然后將程序加載到硬件開發(fā)板中對程序進(jìn)行調(diào)試,主要完成對程序執(zhí)行的實時性問題的調(diào)試。
第五步是將經(jīng)過調(diào)試的程序加載到目標(biāo)板上進(jìn)行軟/硬件的聯(lián)合調(diào)試。第四步已經(jīng)解決了程序中的軟件問題,本步調(diào)試主要解決軟/硬件之間的協(xié)調(diào)問題。
5.2DSP程序的編譯和鏈接原理
5.2.1公共目標(biāo)文件格式和段的概念公共目標(biāo)文件格式(COFF)是DSP系統(tǒng)中采用的一種文件格式,其程序組織的最小單位叫做段,段就是最終占據(jù)存儲器映象中一段連續(xù)地址空間的一組代碼或數(shù)據(jù)。公共目標(biāo)文件格式的每一段都是相對獨立的。公共目標(biāo)文件一般包括以下3個默認(rèn)段。
(1).textsection:文本段或代碼段,由程序代碼和文本組成。
(2).datasection:數(shù)據(jù)段,包括初始化的數(shù)據(jù)。
(3).bsssection:保留空間段,為未初始化變量保留空間。
根據(jù)段的作用不同,段可被分為初始化段(Initializedsection)和未初始化段(Uninitializedsection)兩種。
(1)Initializedsection:初始化段,用于存放數(shù)據(jù)和代碼。
(2)Uninitializedsection:未初始化段,主要任務(wù)是在存儲器中為未初始化的數(shù)據(jù)(主要指變量)保存空間。
從這個意義上講,文本段和數(shù)據(jù)段屬于初始化段,而保留空間段則屬于未初始化段。
除此以外,匯編器和鏈接器還允許用戶自己定義段,用戶可以自己命名這些段,它們都可以和
.text、.data、.bss段一樣被使用。自定義段也分為初始化段和未初始化段兩種基本類型。
匯編器在匯編過程中創(chuàng)建這些段,并根據(jù)程序中的偽指令將段組織成如圖5-3所示的目標(biāo)文件。
鏈接器的功能之一就是把段重新定位在目標(biāo)存儲器上,這一功能稱為重定位。一般的DSP系統(tǒng)包括多種類型的存儲器,使用段可以幫助用戶有效地使用目標(biāo)存儲器。段都是相對獨立的,系統(tǒng)允許用戶對段的起始位置進(jìn)行任意的重定位,這樣用戶可以將任何段放入到目標(biāo)存儲器中的任何位置,這也是公共目標(biāo)文件格式(COFF)中應(yīng)用段作為程序組織單位的重要意義。
圖5-3公共目標(biāo)文件格式及其在存儲空間中的定位
5.2.2匯編器對段的處理
匯編語言的源程序利用匯編偽指令告訴匯編器如何將程序中的各部分組織為不同的段,匯編器支持以下功能的偽指令。
.text:文本段。
.data:數(shù)據(jù)段。
.bss:保留空間段。
.sect:用戶自定義的初始化段。
.usect:用戶自定義未初始化段。
.asect:絕對地址自定義段。
1.未初始化段
未初始化段的作用是在存儲器中保留一定數(shù)量的空間,它們經(jīng)常定位到RAM中。這些段在目標(biāo)文件中沒有實際的內(nèi)容,僅僅能保留空間,程序在運(yùn)行時可以使用這些空間去創(chuàng)建和儲存變量。
系統(tǒng)默認(rèn)的建立未初始化段使用的是
.bss偽指令,.bss偽指令在
.bss段中保留空間,當(dāng)調(diào)用
.bss偽指令時,匯編器就會在特定的命名段中保留更多的空間。
.bss偽指令的語法結(jié)構(gòu)為
.bsssymbol,sizeinwords[,[blockingflag][,alignmentflag]]
其中:
symbol:地址符號,指向此次被.bss和.usect指令調(diào)用所保留的首字。這個符號與保留空間所使用的變量名相對應(yīng),其他段可以引用該符號,也可將它聲明為全局變量。
sizeinwords:空間大小,應(yīng)為一個絕對表達(dá)式,用以表示該保留空間的大小(以字為單位)。
blockingflag:塊標(biāo)志,這是一個可選參數(shù),當(dāng)該參數(shù)為一個大于0的值時,匯編器會將sizeinwords所指定的空間大小連續(xù)存放,只要指定的保留空間大小不超過一個數(shù)據(jù)頁的長度,分配的空間就不會跨過頁的邊界。
alignmentflag:對齊標(biāo)志,這是一個可選參數(shù),當(dāng)該參數(shù)為一個大于0的值時,匯編器會在定位該段時將其他地址對齊到長字的邊界上。
2.初始化段
初始化段包括可執(zhí)行代碼或已初始化的數(shù)據(jù)。初始化段在聲明時已經(jīng)確定內(nèi)容并存儲在目標(biāo)文件中,在程序裝載入DSP時就存儲于相應(yīng)的存儲器中。每一個初始化段都可以單獨地重定位并引用其他段內(nèi)定義的符號,鏈接器將自動識別這些段間的引用。
DSP系統(tǒng)中有兩個默認(rèn)的初始化段偽指令:.text和.data,它們分別將源程序中的指令或數(shù)據(jù)匯編進(jìn)文本段和數(shù)據(jù)段。
當(dāng)匯編器遇到這些偽指令時,停止將指令或數(shù)據(jù)當(dāng)前段匯編到原來的段,而將當(dāng)前段改為偽指令對應(yīng)的段,并繼續(xù)將后續(xù)的指令或數(shù)據(jù)匯編到新的段中,直至再遇到另外一個初始化段偽指令。
段是通過累加的過程來建立的。例如,當(dāng)匯編器第一次遇到
.data偽指令時,.data段為空,在.data偽指令之后的指令和數(shù)據(jù)將被匯編進(jìn).data段中,直至再遇到另外一個初始化段偽指令(如.text偽指令)。如果匯編器在遇到其他偽指令并將當(dāng)前段轉(zhuǎn)為其他段進(jìn)行匯編后再次遇到.data段,則當(dāng)前段又轉(zhuǎn)為.data段,并且.data段中已經(jīng)有部分內(nèi)容,此時匯編器繼續(xù)將再次遇見的.data偽指令后的指令或數(shù)據(jù)匯編進(jìn).data段。這樣當(dāng)整個匯編源程序匯編完成后,就可以形成單個的可被連續(xù)存放的.data段。
3.自定義段
自定義段(namedsections)是由用戶自己定義的段,它的使用方法與系統(tǒng)默認(rèn)的
.text、
.data和.bss段完全相同。自定義段允許用戶自己定義段,以實現(xiàn)對匯編源程序中的部分代碼或數(shù)據(jù)進(jìn)行單獨存儲或進(jìn)行其他操作。例如,重復(fù)地使用.text偽指令會將匯編源程序中不同地方的代碼匯編到一個單一的.text段中,在程序鏈接時就會被連續(xù)地存放在一起。若用戶因為某種原因希望將一部分代碼不與.text段一起存放,而單獨地存放在存儲器中,則用戶就可以自己定義一個自定義段并將相應(yīng)的代碼分配到該段中,這樣就可以在鏈接時對該段進(jìn)行獨立的操作。同理,用戶也可以定義類似于.data和.bss段的自定義段。
這樣,自定義段也被分為初始化的自定義段和未初始化的自定義段,分別用.sect和.usect來定義。.sect指令用于定義初始化段,經(jīng)過定義初始化段,用戶就可以指定匯編器將相應(yīng)的代碼或數(shù)據(jù)匯編于其中,其用法類似于系統(tǒng)默認(rèn)的.text和.data偽指令;偽指令.usect指令在用戶定義的未初始化命名段中保留空間,其用法類似于系統(tǒng)默認(rèn)的.bss偽指令。具體語法如下所示:
.sect"sectionname"
symbol.usect"sectionname",sizeinwords[,[blockingflag][,alignmentflag]]其中:
sectionname:段名,在用戶自定義保留空間段時段指定的名字。
symbol:地址符號,指向此次被.bss和.usect指令調(diào)用所保留的首字。這個符號與保留空間所使用的變量名相對應(yīng),其他段可以引用該符號,也可將它聲明為全局變量。
sizeinwords:空間大小,應(yīng)為一個絕對表達(dá)式,用以表示該保留空間的大小(以字為單位)。
blockingflag:塊標(biāo)志,這是一個可選參數(shù),當(dāng)該參數(shù)為一個大于0的值時,匯編器會將sizeinwords所指定的空間大小連續(xù)存放,只要指定的保留空間大小不超過一個數(shù)據(jù)頁的長度,分配的空間就不會跨過頁的邊界。
aligmentflag:對齊標(biāo)志,這是一個可選參數(shù),當(dāng)該參數(shù)為一個大于0的值時,匯編器會在定位該段時將其地址對齊到長字的邊界上。
另外,DSP匯編系統(tǒng)中還有一個用于初始化段定義的偽指令,即.asect指令,但它的應(yīng)用已經(jīng)越來越少了。
4.段程序計數(shù)器
匯編器為每個段都配置了一個獨立的程序計數(shù)器,稱為段程序計數(shù)器,簡稱為SPC。段中的SPC表示每行代碼或者數(shù)據(jù)匯編后在相應(yīng)段內(nèi)的地址。在每個段匯編開始時,匯編器將每個段的SPC都設(shè)置為0,當(dāng)匯編器把代碼或數(shù)據(jù)匯編進(jìn)某個段時,它就將該段的SPC增加相應(yīng)的值。如果將數(shù)據(jù)或代碼匯編到一個SPC不等于0的段(即當(dāng)前段內(nèi)已經(jīng)有數(shù)據(jù)或地址),則匯編器會記住該段SPC原來的值并在此基礎(chǔ)上繼續(xù)把SPC增加相應(yīng)的值。在匯編時,匯編器將每個段的首地址均設(shè)為0,而每個段的SPC只記錄指令或數(shù)據(jù)在段內(nèi)的相對地址(即偏移地址)。在完成匯編進(jìn)入鏈接階段時,鏈接器按照用戶指定的存儲方案為每個段給定在存儲空間中的首地址。當(dāng)首地址確定后,由每條指令或數(shù)據(jù)的SPC值(段內(nèi)地址)和每個段在存儲空間中的首地址就可以惟一地確定每一條指令或數(shù)據(jù)的物理地址。
5.段偽指令的應(yīng)用實例
下面通過一個簡單的匯編語言編寫的源程序說明段偽指令在匯編建立公共目標(biāo)文件格式時的作用。該實例通過在不用段之間的來回交換,利用段偽指令逐步建立各目標(biāo)段。用戶可以使用段偽指令匯編定義一個新段并將代碼或數(shù)據(jù)匯編于其中,或者繼續(xù)匯編代碼或數(shù)據(jù)到已包含內(nèi)容的段中。以下為該實例的程序清單,在程序清單中,第一列為源程序的行號,第二列為段程序計數(shù)器(SPC)的值,第三列為目標(biāo)代碼,第四列為程序源代碼。
在上述匯編語言程序中,我們利用段偽指令共創(chuàng)建了5個段。
.text:包含了10個16位字的目標(biāo)代碼。
.data:包含了7個16位字的目標(biāo)代碼。
vectors:是在程序中利用.sect定義的初始化的自定義段,其中包含了2個16位字初始化的目標(biāo)代碼。
.bss:為.bss段保留了10個16位字的存儲器空間。
newvars:為在程序中利用.usect定義的未初始化的自定義段,它保留了8個16位字的存儲器空間。
圖5-4所示為實例中匯編器創(chuàng)建的5個段,其中3個為初始化段,2個為未初始化段。
圖5-4實例中匯編器創(chuàng)建的5個段
5.2.3鏈接器對段的處理
鏈接器是DSP程序編譯過程中的重要工具,它與段相關(guān)的功能主要有兩個:段的鏈接和段的定位。段的鏈接是指鏈接器要把匯編器生成的公共目標(biāo)文件(.OBJ文件)中的段進(jìn)行鏈接以生成可執(zhí)行文件,鏈接器輸出的可執(zhí)行文件的擴(kuò)展名為.OUT。當(dāng)匯編器生成的目標(biāo)文件有多個時,鏈接器也需要把它們中相同的段進(jìn)行鏈接。段的定位是指鏈接器需要根據(jù)用戶的要求為各輸出段在存儲空間中選擇存儲地址,即為.OUT文件中的每個段確定段首地址,當(dāng)每個段的首地址確定后,段內(nèi)各代碼(即符號的地址)也就隨即確定了。
在實現(xiàn)段的定位時,用戶需要告訴鏈接器各段在系統(tǒng)地址空間中定位的方案,這需要用到兩個鏈接器的段偽指令:MEMORY和SECTION,它們也是編寫鏈接命令文件的主要指令,其功能如下所述。
(1)MEMORY:存儲器偽指令。該指令用來定義目標(biāo)系統(tǒng)的存儲器空間,利用它可以將存儲器空間分為多個區(qū)域,并指定各區(qū)域的起始位置和區(qū)域長度。
(2)SECTION:段偽指令。該指令告訴鏈接器如何將輸入段組合成輸出段,以及如何在存儲器空間中定位輸出段(即由用戶指定輸出段的存儲地址)。
在DSP程序系統(tǒng)中,用戶可以通過鏈接命令文件(.cmd)來指定以上信息。
圖5-5給出了一個鏈接器對匯編器輸出的目標(biāo)文件的處理過程。在圖5-5中,匯編器有兩個輸出目標(biāo)文件,分別為file1和file2。這兩個文件分別包含了系統(tǒng)默認(rèn)的
.text、.data和
.bss段,此外還包含了用戶自定義段。鏈接器對這兩個目標(biāo)文件分別進(jìn)行段的鏈接和段的定位兩個方面的處理。在段的鏈接方面,鏈接器分別將兩個輸入目標(biāo)文件的同名段鏈接在一起,組成新的段,并以此形成可執(zhí)行文件。如圖5-5所示,鏈接器將file1的.text段和file2的.text段組合形成一個新的.text段。鏈接器對兩個文件的.data段和.bss段也進(jìn)行了同樣的處理,最后對自定義段進(jìn)行類似處理后放在上述段的后面。在段的定位方面,鏈接器按照用戶指定的存儲空間分配方案對鏈接后的各段進(jìn)行定位,即確定各段的段首地址。用戶可通過鏈接命令文件(.cmd)用MEMORY和SECTION偽指令來指導(dǎo)鏈接器進(jìn)行存儲地址空間的劃分和段的定位。
圖5-5鏈接器對目標(biāo)文件的處理過程
5.2.4程序的定位和加載
1.程序的定位
1)鏈接器對程序的定位
在程序鏈接之前,程序中各段只有段程序計數(shù)器(SPC)確定的段內(nèi)地址,段首均沒有定位。鏈接器在處理每一個段時均假設(shè)段首地址為0,鏈接器通過以下操作來重新定位段(即確定段的首地址):
(1)將各段在存儲器空間中進(jìn)行分配,為各段確定段首地址;
(2)將符號變量調(diào)整到對應(yīng)的新的地址;
(3)將程序中的引用調(diào)整到對應(yīng)的新的地址。
2)程序運(yùn)行時的定位
在DSP的應(yīng)用系統(tǒng)中經(jīng)常會遇到這樣的應(yīng)用要求,即需要將代碼加載到存儲器的某個地址區(qū)域,而在另外一個地址區(qū)域運(yùn)行。例如,在以ROM為程序存儲器的系統(tǒng)中,程序在加載時被定位在ROM所分配的地址空間中,但為了縮短程序的取指時間,獲得更高的程序運(yùn)行效率,在運(yùn)行時將程序定位到DARAM所分配的地址空間中。
鏈接器提供了實現(xiàn)這種應(yīng)用要求的簡單方法。用戶可以通過SECTIONS偽指令來為相應(yīng)的段指定兩個段首地址,其中一個為程序加載時使用的段首地址,另外一個為程序運(yùn)行時的段首地址。這樣在不同的階段程序處于不同的存儲空間,從而方便地滿足了程序的存儲安全和運(yùn)行的高效率要求。
2.程序的加載
鏈接器產(chǎn)生可執(zhí)行的COFF程序模塊??蓤?zhí)行的目標(biāo)文件和作為鏈接器輸入的目標(biāo)文件具有同樣的COFF格式,只是在可執(zhí)行目標(biāo)文件中對段進(jìn)行了組合并在目標(biāo)存儲器中進(jìn)行了重定位。
為了運(yùn)行程序,可執(zhí)行目標(biāo)模塊中的代碼和數(shù)據(jù)必須傳送或加載到目標(biāo)系統(tǒng)存儲器中。有幾種方法可以用于加載程序,用戶可以根據(jù)實際條件和系統(tǒng)要求來選擇具體的加載方法。下面給出了兩種常用的方法:
(1)DSP系列的調(diào)試工具包括軟件模擬器、XDS仿真器以及集成化的開發(fā)系統(tǒng)CCS,它們都具有內(nèi)置的加載器。這些工具都有調(diào)用加載器的LOAD指令,加載器讀取可執(zhí)行文件并將程序復(fù)制到目標(biāo)系統(tǒng)的存儲器中以完成程序的加載過程。
(2)使用Hex轉(zhuǎn)換工具,例如使用dephex可將可執(zhí)行的公共目標(biāo)文件模塊轉(zhuǎn)換成其他幾種目標(biāo)格式文件。然后,用戶可以利用EPROM編程器把轉(zhuǎn)換的文件燒寫進(jìn)EPROM或Flash中。
5.2.5程序文件中的符號
COFF文件中包含一個符號表,用于存儲程序中的符號信息。鏈接器在對程序進(jìn)行重新定位時要使用該符號表,調(diào)用程序時也要用到該符號表。
我們把在一個模塊中被定義而在另一個模塊中被引用的符號稱為外部符號。用戶可以通過使用.def、.ref或.global偽指令來聲明某個符號為外部符號。
(1).def偽指令:在當(dāng)前模塊中定義而在另一個模塊中被引用的符號。
(2).ref偽指令:在當(dāng)前模塊中引用而在另一個模塊中定義的符號。
(3).global偽指令:在當(dāng)前模塊中定義而在另一個模塊中被引用或在當(dāng)前模塊中引用而在另一個模塊中定義的符號。
下面的例子說明了這些偽指令的應(yīng)用。
x: ADD #56h,A ;Definex
B y ;Referencey
.def x ;DEFofx
.ref y ;REFofy
對x的.def定義說明x是在本模塊中定義而在其他模塊中引用的外部符號,對y的.ref定義說明y是未在本模塊中定義而在另一個模塊中定義的符號。
匯編器把x和y都放在目標(biāo)文件的符號表中,當(dāng)該文件和其他文件鏈接時,x的入口定義了其他文件不能識別的符號x,y的入口使鏈接器搜索其他文件的符號表,以找到y(tǒng)的定義。
鏈接器必須把所有的符號引用和相應(yīng)的符號定義一一匹配。如果鏈接器不能找到某個符號的定義,那么它將提示有關(guān)未定義符號的出錯信息,在這種情況下鏈接器將不能生成可執(zhí)行的目標(biāo)模塊。
5.3DSP應(yīng)用程序的構(gòu)成
5.3.1CCS中DSP應(yīng)用程序的構(gòu)成在CCS集成化開發(fā)環(huán)境中,DSP的應(yīng)用程序是以項目(Project)為單位進(jìn)行管理的,在CCS中對程序的編譯、鏈接等操作一般也是以項目為單位進(jìn)行的。我們把一個DSP應(yīng)用系統(tǒng)(或一個功能模塊)的相關(guān)文件放在一個項目中進(jìn)行管理,并最終生成一個可執(zhí)行文件加載到目標(biāo)系統(tǒng)中去執(zhí)行。
在CCS中,一個項目主要由四種文件來構(gòu)成,分別為源程序、頭文件、庫文件和鏈接命令文件。其中,源程序包括由匯編語言或C語言編寫的源程序和由匯編語言編寫的中斷向量文件,這部分文件是DSP程序系統(tǒng)的核心,體現(xiàn)了系統(tǒng)的主要功能和任務(wù);頭文件是源程序編譯過程中的說明文件,主要完成源程序中一些符號常量和數(shù)據(jù)結(jié)構(gòu)的定義,包括源程序中要用到的函數(shù)及DSP的主要寄存器的定義;庫文件是源程序編譯過程中的支持文件,TI公司針對不同的DSP產(chǎn)品系列提供了不同的庫文件供用戶調(diào)用;鏈接命令文件是源程序鏈接過程中要用到的文件,該文件通知鏈接器目標(biāo)系統(tǒng)地址空間的分配方案和鏈接后各段的定位方案。
以上文件中庫文件一般是由TI公司提供的,用戶可以直接調(diào)用,其他文件一般需要用戶根據(jù)系統(tǒng)要求自己編寫。這些文件的核心是源程序,用戶應(yīng)在對系統(tǒng)功能、系統(tǒng)要求及硬件平臺條件進(jìn)行充分分析的基礎(chǔ)上選擇匯編語言或C語言進(jìn)行編寫。若要編寫匯編語言的源程序,則用戶除需要對DSP的指令集有全面的了解外,還需要充分掌握DSP的硬件結(jié)構(gòu)和原理,包括DSP的程序控制原理。這些內(nèi)容本書前面的章節(jié)已經(jīng)進(jìn)行了較為詳細(xì)的介紹,具體指令集中每條指令的語法和用法,讀者可參考TI公司的相關(guān)說明書。
5.3.2鏈接命令文件的編寫
1.存儲器偽指令MEMORY
為了實現(xiàn)鏈接后各段在存儲空間中的定位,充分利用系統(tǒng)中的存儲器資源,需要對存儲空間進(jìn)行配置。MEMORY偽指令用來定義目標(biāo)系統(tǒng)的存儲器空間,利用它可以將存儲器空間分為多個區(qū)域,并指定各區(qū)域的起始位置和區(qū)域長度。
MEMORY偽指令在命令文件中的書寫方式為:以大寫的MEMORY開始,然后用大括號給出關(guān)于存儲空間分配的說明。該指令將所有使能的存儲空間分為一系列存儲區(qū)域,每個區(qū)域給出起始地址和長度,這樣就確定了存儲空間的分配方案。
MEMORY偽指令的一般語法如下:
MEMORY
{
PAGE0:name1[(attr)]:origin=constant,length=constant;
…
PAGEn:namen[(attr)]:origin=constant,length=constant;
}其中:
PAGE:存儲空間的頁的劃分,每一個PAGE頁代表一個完全獨立的地址空間。頁號n最大可以達(dá)到255,但應(yīng)用中將整個存儲空間分為兩頁:PAGE0為程序存儲器頁,PAGE1為數(shù)據(jù)存儲器頁。每個PAGE頁上可以劃分多個存儲區(qū)域。
name:劃分的存儲器頁的命名。這個名字只用來標(biāo)記每個存儲空間區(qū)域,本身并沒有特殊的含義,
原則上用戶可以為定義的存儲區(qū)域指定任意的滿足命名規(guī)則的名字。不同的PAGE頁上劃分的存儲區(qū)域可以取相同的名字,但在同一PAGE頁上的區(qū)域名不能相同。
attr:存儲區(qū)域?qū)傩詤?shù)。這是一個可選的參數(shù)項,它規(guī)定了MEMORY偽指令定義的每個存儲區(qū)域的讀/寫屬性。其屬性一般分為R、W、X、I共4種。其中,R表示該存儲區(qū)域可讀;W表示該存儲區(qū)域可寫;X表示該存儲區(qū)域可以加載可執(zhí)行的代碼;I表示該存儲區(qū)域可以進(jìn)行初始化。如果用戶在利用MEMORY偽指令時對某個存儲器區(qū)域不指定該參數(shù),則系統(tǒng)默認(rèn)該區(qū)域同時具有上述的4個屬性。
origin:劃分的存儲區(qū)域的起始地址,用origin、org或o表示均可。這個值默認(rèn)用16位的二進(jìn)制常數(shù)來表示。
length:劃分的存儲區(qū)域的長度,用length、len或l表示均可。這個值默認(rèn)用16位的二進(jìn)制常數(shù)來表示。在確定了存儲區(qū)域劃分的起始地址和長度后就可以惟一地確定該區(qū)域的范圍。
以下給出一個MEMORY偽指令的簡單例子:
MEMORY
{
PAGE0:ROM: origin=0h,length=1000h;
PAGE1:B2:origin=60h,length=20h;
B0B1:
origin=200h,length=200h;
}上述MEMORY偽指令的執(zhí)行結(jié)果是:系統(tǒng)的程序存儲空間和數(shù)據(jù)存儲空間實現(xiàn)了如圖5-6所示的劃分。
圖5-6MEMORY偽指令對存儲空間的劃分結(jié)果
2.段偽指令SECTION
在鏈接命令文件中,利用MEMORY偽指令實現(xiàn)對存儲空間的劃分后就可以利用SECTION偽指令來通知鏈接器如何對多個目標(biāo)文件中的段進(jìn)行鏈接,并如何定位鏈接后的各段。
SECTION偽指令在命令文件中的書寫方式為:以大寫的SECTION開始,然后用大括號給出關(guān)于輸出段說明的語句。每一個輸出段的說明都從段名開始,段名后是一行說明段的內(nèi)容和如何給段分配存儲空間的屬性參數(shù)。
SECTION偽指令的一般語法如下:
SECTION
{
name:[property,property,property,...]
name:[property,property,property,...]
name:[property,property,property,...]
}其中,name為需要在SECTION偽指令中進(jìn)行定位的段名,其后是說明段的內(nèi)容和如何給段分配存儲空間的屬性參數(shù)。這些參數(shù)主要包括如下幾個:
Loadallocation:段加載地址。用于指定將該段加載到存儲空間的什么地址,其語法為Load=allocation
或 allocation
或
>allocation其中,allocation是關(guān)于輸出段地址的說明。例如,
.text:load=0x1000 ;將.text輸出段定位為以0x1000為起始地址的存儲區(qū)域
.text:load>ROM ;將.text輸出段定位到名為ROM的存儲區(qū)域
.text:align=0x80 ;將.text輸出段定位到與0x80對齊的存儲區(qū)域
Runallocation:段運(yùn)行地址。用于指定將該段在存儲空間的什么地址開始運(yùn)行,其語法與Loadallocation的語法相同。鏈接器可以為段指定不同的加載地址和運(yùn)行地址。
Inputsections:輸入段。它用來指定由輸入目標(biāo)文件中的哪些段組成當(dāng)前的輸出段。
Sectiontype:段的類型。它是輸出段定義特殊形式的標(biāo)志。
Fillvalue:段的初始化值。在段初始化時為段指定一個初始的填充值。其語法為Fill=value。其中,value為指定的數(shù)值。
下面給出一個SECTION偽指令的簡單例子:
SECTION
{
.text: load=ROM
.const: load=ROMrun=RAM
.bss: load=RAM
vectors: load=0h
{
t1.obj(.intvec1)
t2.obj(.intvec2)
}
.data: align=16
}上例中通過SECTION偽指令定義了5個輸出段,分別如下:
.text段是由輸入的目標(biāo)文件的.text段組合而成的,程序加載和運(yùn)行的地址均被定位在名為ROM的存儲區(qū)域中。
.const段由輸入的目標(biāo)文件的.const段組合而成,該段加載地址定位于名為ROM的存儲區(qū)域中,而運(yùn)行地址定位于名為RAM的存儲區(qū)域中。
.bss段由輸入的目標(biāo)文件的.bss段組合而成,在存儲空間中定位于名為RAM的存儲區(qū)域中。
vectors段由輸入的目標(biāo)文件t1的.intvec1段和目標(biāo)文件t2的.intvec2段組合而成。
.data段由輸入的目標(biāo)文件的.data段組合而成,該鏈接命令文件允許鏈接器將該段定位于存儲空間的任何區(qū)域,但必須對齊16位字的邊界。
圖5-7SECTION偽指令定義的段在存儲空間中的定位
3.鏈接命令文件實例
上述內(nèi)容介紹了鏈接命令文件中兩個重要的偽指令的用法及示例,這兩個偽指令的參數(shù)較多,但在許多實際工程項目中編寫鏈接命令文件時,許多參數(shù)是很少用到的,因而在實際項目應(yīng)用中編寫鏈接命令文件是比較簡單的。
在鏈接命令文件中,除MEMORY和SECTION兩個偽指令外,還可以指定輸入的目標(biāo)文件和輸出的可執(zhí)行文件。輸入文件的文件名在鏈接命令文件的首行直接列出,輸出文件名用-o參數(shù)來引出。
下面給出了一個典型的TMS320LF240xA系列DSP的鏈接命令文件的編寫實例,以供讀者參考使用。
5.3.3中斷向量文件的編寫
2000系列DSP的中斷向量文件的結(jié)構(gòu)與5000系列DSP的中斷向量文件的結(jié)構(gòu)基本相同,但2000系列DSP的中斷系統(tǒng)相對來講比較復(fù)雜,掌握好2000系列DSP的中斷向量文件的編寫,再編寫5000系列的向量文件也就相對比較容易了。因此本節(jié)以2000系列DSP為例介紹中斷向量文件的編寫。
前面章節(jié)在介紹2000系列DSP的中斷系統(tǒng)時已經(jīng)說明,由于TMS320LF240xA系列DSP的中斷系統(tǒng)在硬件上是一種兩級中斷管理結(jié)構(gòu),因此DSP的軟件系統(tǒng)在中斷服務(wù)程序上也相應(yīng)地采用了兩級中斷服務(wù)程序,分別為全局中斷服務(wù)程序(GISR)和專用中斷服務(wù)程序(SISR)。
全局中斷服務(wù)程序(GISR)是針對CPU直接響應(yīng)的6個中斷源的中斷服務(wù)程序(ISR),INT1~I(xiàn)NT6中每個中斷均對應(yīng)一個GISR,因此DSP系統(tǒng)中應(yīng)具有6個GISR。GISR的主要功能有兩點:一是保存CPU狀態(tài)和原程序執(zhí)行的上下文;二是從外設(shè)中斷向量寄存器(PIVR)中讀取與CPU相應(yīng)中斷對應(yīng)的外設(shè)中斷向量(PIV),并由PIV的值確定專用中斷服務(wù)程序(SISR)的入口地址,控制CPU分支到SISR。
專用中斷服務(wù)程序(SISR)是處理外設(shè)中斷的具體程序,一般系統(tǒng)中用到的外設(shè)中斷都具有自己的SISR,根據(jù)外設(shè)中斷所需完成的任務(wù)不同,SISR的具體內(nèi)容也不相同。一般在完成了特定的處理任務(wù)后,SISR應(yīng)通過指令語句將外設(shè)寄存器(PR)中的中斷標(biāo)志位(IF)清0,并將CPU狀態(tài)寄存器ST0的INTM位清0,以解除對所有的可屏蔽中斷的禁止。
為了保持中斷系統(tǒng)的完整性,保證在發(fā)生意外錯誤時系統(tǒng)以可以控制的方式正常運(yùn)行,DSP在中斷系統(tǒng)中引入了假中斷向量。所謂假中斷向量,是指在中斷系統(tǒng)中人為設(shè)置的一種中斷,其目的是當(dāng)中斷系統(tǒng)因為某種錯誤在CPU響應(yīng)中斷后,不能正確獲得中斷向量值時調(diào)用假中斷服務(wù)程序,以使系統(tǒng)退出中斷響應(yīng),恢復(fù)到正常的工作狀態(tài)。具體來說,當(dāng)一個中斷被CPU響應(yīng)后,CPU將從外設(shè)中斷擴(kuò)展(PIE)的外設(shè)中斷向量寄存器(PIVR)中讀取PIV的值,用以確定SISR的入口地址,此時若因某種錯誤使PIE未將中斷的PIV值加載到PIVR中,則CPU讀出的將是假中斷的PIV值,即0000h。用戶可以在假中斷服務(wù)程序中使系統(tǒng)退出本次中斷響應(yīng),以避免系統(tǒng)因錯誤的PIV值而發(fā)生程序執(zhí)行失控。
因此,用戶在編寫中斷系統(tǒng)的程序時,應(yīng)該給出3種文件:中斷向量表定義文件、全局中斷服務(wù)程序(GISR)和專用中斷服務(wù)程序(SISR)。其中,GISR主要用來保存CPU狀態(tài)和原程序執(zhí)行的上下文,確定外設(shè)中斷向量(PIV)及專用中斷服務(wù)程序(SISR)的入口地址,并控制CPU分支到SISR;SISR主要完成外設(shè)中斷的具體處理任務(wù),用戶需根據(jù)外設(shè)和應(yīng)用系統(tǒng)的功能需要來具體確定,除此之外,SISR一般還需完成外設(shè)寄存器(PR)的中斷標(biāo)志位(IF)清0和將CPU狀態(tài)寄存器ST0的INTM位清0等操作。
中斷向量表定義文件采用匯編語言編寫,對于同一DSP平臺其格式和內(nèi)容基本相同,下面給出一個基于TMS320LF240xA系列DSP的應(yīng)用系統(tǒng)中斷向量表定義文件的實例,以供讀者參考使用。
5.3.4TMS320LF240xA系列DSP的頭文件
頭文件是DSP應(yīng)用系統(tǒng)軟件的重要組成部分,它是源程序編譯過程中的說明文件,主要完成源程序中一些符號常量和數(shù)據(jù)結(jié)構(gòu)的定義,包括源程序中要用到的函數(shù)及DSP的主要寄存器的定義。關(guān)于符號常量和數(shù)據(jù)結(jié)構(gòu)的定義可以在源程序中進(jìn)行,但對在多個程序中都要引用的符號,放在頭文件中定義可以方便用戶編程,也便于在程序調(diào)試和運(yùn)行中修改符號定義,因此用戶可以根據(jù)源程序的需要進(jìn)行編寫。在DSP應(yīng)用系統(tǒng)的編程中經(jīng)常要對DSP系統(tǒng)中的寄存器進(jìn)行訪問,若根據(jù)寄存器地址訪問寄存器,則不但會增加編程的工作量,同時也會降低程序的可讀性。因此可以在頭文件中對所選用DSP中的寄存器進(jìn)行定義,這樣不但便于編寫程序,而且也會提高程序的可讀性。當(dāng)然,不同系列DSP的寄存器的定義和地址可能不同,對不同系列DSP的應(yīng)用軟件應(yīng)該給出不同的寄存器定義文件。
下面給出了一個基于TMS320LF240xA系列DSP的寄存器定義頭文件的實例,該文件對LF2407的處理器核心的寄存器、片上外設(shè)的相關(guān)寄存器中常用的存儲空間和數(shù)據(jù)頁均進(jìn)行了定義,用戶還可以根據(jù)實際系統(tǒng)的需要在文件中加入其他常量的定義。以下是該文件的程序清單,供讀者參考使用。
5.4DSP軟件調(diào)試環(huán)境簡介
5.4.1CCS的主要特征
CCS代碼調(diào)制器是一種集成化開發(fā)環(huán)境(IDE),它是一種針對標(biāo)準(zhǔn)TMS320調(diào)試接口的交互式調(diào)試工具,其界面如圖5-8所示。CCS為用戶提供了環(huán)境設(shè)置、源文件編輯、程序調(diào)試、跟蹤和分析等工具,用戶可以在一個軟件環(huán)境下完成編輯、編譯、鏈接、調(diào)試和數(shù)據(jù)分析等工作。CCS還提供了豐富且強(qiáng)有力的調(diào)試手段來提高程序調(diào)試的效率和精度。它采用Windows風(fēng)格界面,操作簡單直觀,極大地方便了DSP程序的設(shè)計與開發(fā)。
圖5-8CCS軟件界面
圖5-9利用CCS開發(fā)應(yīng)用程序的流程
CCS具有調(diào)試器的主要特性,除此之外還有以下特性:
(1)支持多DSP調(diào)試;
(2)斷點工具,包括硬件斷點、數(shù)據(jù)空間讀/寫斷點、條件斷點等;
(3)探針工具(probepoints),可用于算法仿真,數(shù)據(jù)監(jiān)視等;
(4)分析工具(profilepoits),可用于評估代碼執(zhí)行的時間和指令數(shù);
(5)數(shù)據(jù)的圖形顯示工具,可繪制時域/頻域波形、眼圖、星座圖、圖像等,并可自動刷新;
(6)支持RTDX(RealTimeDataeXchange)技術(shù),利用該技術(shù)可在不中斷目標(biāo)系統(tǒng)運(yùn)行的情況下,實現(xiàn)DSP與其他應(yīng)用程序(OLE)的實時數(shù)據(jù)交換;
(7)提供DSP/BIOS工具,利用該工具可增強(qiáng)對代碼的實時分析能力,如分析代碼執(zhí)行的效率、調(diào)度程序執(zhí)行的優(yōu)先級,方便管理或使用系統(tǒng)資源(代碼/數(shù)據(jù)存儲空間、中斷服務(wù)程序的調(diào)用、定時器的使用等),從而降低對開發(fā)人員對硬件資源熟悉程度的要求。
5.4.2CCS的基本操作
1.創(chuàng)建一個新的項目工程
工程項目的信息儲存在一個單一的工程文件(*.pjt)中。創(chuàng)建一個新的項目工程有如下步驟。
(1)打開新建窗口。從工程菜單中選擇New選項,彈出工程創(chuàng)建窗口,界面如圖5-10所示。
圖5-10CCS中建立新項目的界面
(2)輸入工程名。在工程名區(qū)域中輸入工程名字,每個工程必須有惟一的名字。
(3)選擇文件夾。在Location區(qū)域選擇一個文件夾來儲存所創(chuàng)建的工程文件,一般將不同的工程儲存于不同的文件夾中。
(4)選擇工程類型。在工程類型區(qū)域,從下拉菜單選項中選擇工程的類型,可以建立兩種工程類型:可執(zhí)行文件(*.out)或庫文件(*.lib)??蓤?zhí)行文件類型說明將要創(chuàng)建的工程輸出一個可執(zhí)行文件;庫文件類型說明將要創(chuàng)建的工程輸出一個目標(biāo)文件庫。
(5)確定DSP系列。在Target區(qū)域,按照系統(tǒng)所選用的DSP系列來選擇產(chǎn)品系列。
(6)點擊“完成”按鈕。
2.在工程中添加文件
(1)打開添加文件對話框。選擇Project→AddFilestoProject,或在工程窗口中的文件名上點擊右鍵并選擇添加文件選項,彈出添加文件對話框,界面如圖5-11所示。
圖5-11CCS中添加文件對話框的界面
(2)選擇文件。在添加文件對話框的文件類型下拉列表中選擇所添加的文件類型,在放置文件的文件夾中選擇所要添加的文件。
(3)點擊“打開”按鈕來添加選定的文件到工程中。
當(dāng)需要刪除一個文件時,可在ProjectView窗口中相應(yīng)文件上單擊右鍵,并選擇“從工程中刪除”選項。在添加文件時,不必手動添加工程中需要的
.h文件,因為系統(tǒng)在編譯該項目時會自動在項目文件夾中搜索引用的.h文件,并將其添加到項目文件中。
3.由項目建立和運(yùn)行程序
(1)啟動編譯過程。選擇Project→RebuildAll,或者點擊按鈕,啟動匯編和鏈接過程以建立程序。選擇該選項后,CCS將依次啟動匯編和鏈接過程對項目進(jìn)行編譯,這一系列過程的相關(guān)信息會顯示在窗口底部。
(2)生成可執(zhí)行文件。在默認(rèn)情況下,編譯生成的可執(zhí)行文件(.out文件)被存放于調(diào)試文件夾下,要改變它的地址,可從CCS工具欄里選擇另外一個文件夾。
(3)加載文件。選擇File→LoadProgram選
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 集合典型考點闖關(guān)練-2026年高考數(shù)學(xué)復(fù)習(xí)備考(含答案)
- 2020年成人高考高起專英語詞匯辨析訓(xùn)練
- 吉林省松原市寧江區(qū)2024-2025學(xué)年七年級下學(xué)期期中地理試題(含答案)
- 2025至2030年中國個人代理保險行業(yè)市場運(yùn)營現(xiàn)狀及投資規(guī)劃研究建議報告
- 2025至2030年中國地柜行業(yè)市場發(fā)展監(jiān)測及投資戰(zhàn)略咨詢報告
- 承接建筑勞務(wù)服務(wù)合同范本
- 燃?xì)怃摴芊栏N售合同范本
- 售電業(yè)務(wù)居間服務(wù)合同范本
- pos機(jī)推廣合同協(xié)議書范本
- 與保姆簽合同終止協(xié)議書
- 焦慮癥健康宣教課件
- 圓錐角膜科普講座
- 武漢管理咨詢行業(yè)分析
- 科技成果鑒定證書格式模板
- 高效的物業(yè)服務(wù)管理團(tuán)隊
- 冠脈造影術(shù)后護(hù)理查房課件
- 急重癥醫(yī)學(xué)情境模擬案例訓(xùn)練手冊
- 全國大學(xué)生電子設(shè)計競賽-智能小車報告
- 有限空間作業(yè)安全管理協(xié)議
- 農(nóng)藥采購及配送服務(wù)方案
- 營業(yè)線施工安全教育培訓(xùn)內(nèi)容
評論
0/150
提交評論