TMS320C54XDSP混合編程的方法研究
摘要:提出并分析了在考慮程序代碼效率、執行效率和程序的可讀性及可移植性的情況下,對于TMS320C54X系列,采用C語(yǔ)言和匯編語(yǔ)言混合編程的優(yōu)點(diǎn);詳細闡述了混合編程方法的特點(diǎn)、應遵循的規則和詳細接口規范;給出了程序設計實(shí)例。
本文引用地址:http://dyxdggzs.com/article/242267.htm關(guān)鍵詞:數字信號處理(DSP) TMS320C54X 混合編程
數字信號處理技術(shù)是一門(mén)涉及許多學(xué)科的新技術(shù),廣泛應用于軍事、工業(yè)、航空、航天等諸多領(lǐng)域。數字信號處理技術(shù)由于其運行量大和實(shí)現算法復雜,通常采用專(zhuān)用的DSP芯片來(lái)實(shí)現。美國TI公司的TMS320C54X系列芯片是為實(shí)現低功耗和高性能而專(zhuān)門(mén)設計的定點(diǎn)DSP芯片。
TMS320C54X的主要特點(diǎn)包括:高運算速度、優(yōu)化的CPU結構、低功耗方式和智能外設等。
使用專(zhuān)用DSP芯片進(jìn)行設計與開(kāi)發(fā)包括硬件和軟件兩個(gè)方面。通常有以下三種軟件設計方式:
(1)完全用C語(yǔ)言開(kāi)發(fā)。TI公司提供了用于C語(yǔ)言開(kāi)發(fā)的CCS(CODE COMPOSER STUDIO)平臺。該平臺包括了優(yōu)化ANSI C編譯器,從而可以在C源程序級進(jìn)行開(kāi)發(fā)調方式。這種方式大大提高了軟件的開(kāi)發(fā)速度和可讀性,方便了軟件的修改和移植。但是,在某些情況下,C代碼的效率還是無(wú)法與手工編寫(xiě)的匯編代碼的效率相比,如FFT編程。這是因為即使最佳的C編譯器,也無(wú)法在所有的飛速下都能夠最合理地利用DSP芯片所提供的各種資源。此外,用C語(yǔ)言實(shí)現DSP芯片的某些硬件控制也不如匯編程序方便,有些甚至無(wú)法用C語(yǔ)言實(shí)現。
(2)完全有匯編語(yǔ)言開(kāi)發(fā),TI公司提供了用于匯編語(yǔ)言開(kāi)發(fā)的針對TMS320C54X的匯編語(yǔ)言。用戶(hù)可以用它進(jìn)行軟件開(kāi)發(fā)。此種方式可以更為合理地充分利用DSP芯片提供的硬件資源,其代碼效率高,程序執行速度快。但是用DSP芯片的匯編語(yǔ)言編寫(xiě)程序是比較繁雜的。一般來(lái)說(shuō),不同公司的芯片匯編語(yǔ)言是不同的,即使是同一公司的芯片,由于片類(lèi)型的不同(如定點(diǎn)和浮點(diǎn)),芯片的升級換代,其匯編語(yǔ)言也不同。因此,用匯編語(yǔ)言開(kāi)發(fā)基于某種DSP芯片的產(chǎn)品周期較長(cháng),并且軟件的修改和升級較困難,這些都是因為匯編語(yǔ)言的可讀性和可移植性較差所致。
(3)用C語(yǔ)言和匯編語(yǔ)言混合編程開(kāi)發(fā)。為了充分利用DSP芯片的資源,更好地發(fā)揮C語(yǔ)言和匯編語(yǔ)言進(jìn)行軟件開(kāi)發(fā)的各自的優(yōu)點(diǎn),可以將兩者有機結合起來(lái),兼顧兩者的優(yōu)點(diǎn),避免其弊端。因此,在很多情況下,采用混合編程方法能更好地達到設計要求,完成設計功能。但是,采用C語(yǔ)言和匯編語(yǔ)言混合編程必須遵循一些有關(guān)的規則,否則會(huì )遇到一些意想不到的問(wèn)題,給開(kāi)發(fā)設計帶來(lái)許多麻煩。
本文提出了基于DSP(TMS320C54X)的C語(yǔ)言和匯編語(yǔ)言混合編程的程序設計方法,并給出了混合編程應遵循的規則和需要注意的一些問(wèn)題。
1 TMS320C54X的C語(yǔ)言和匯編語(yǔ)言混合編程方法
C語(yǔ)言和匯編語(yǔ)言的混合編程有以下幾種方法:
(1)獨立編寫(xiě)編編程序和C程序,分開(kāi)編譯或匯編形成各自的目標代碼模塊,用鏈接器將C模塊和匯編模塊鏈接起來(lái),這是一種靈活性較大的方法。采用這種方法,C程序可以調用匯編程序,并且可以訪(fǎng)問(wèn)匯編程序中定義的變量。同樣,匯編程序也可以調用C程序或訪(fǎng)問(wèn)C程序中定義的變量。但用戶(hù)必須自己維護各匯編模塊的入口和出口代碼,自己計算傳遞的參數在堆棧中的偏移量,工作量稍大,但能做到對程序的絕對控制。
(2)在C程序中直接內嵌匯編語(yǔ)句。此種方法可以在C程序中實(shí)現C語(yǔ)言無(wú)法實(shí)現的一些硬件控制功能,如修改中斷控制寄存器、中斷標志寄存器等。嵌入匯編語(yǔ)句的方法比較簡(jiǎn)單,只需在匯編語(yǔ)句的兩邊加上括號和雙引號,并且在括號前加上asm標識符即可,即asm(“匯編語(yǔ)句”)。
但是,采用此種方法必須注意以下幾點(diǎn):
①括號中的匯編語(yǔ)句必須以標號、空格、tab、分號開(kāi)頭,這和通常的匯編編程的語(yǔ)法一樣。
②不要破壞C環(huán)境,因為C編譯器并不檢查和分析嵌入的匯編語(yǔ)句。
③插入跳轉語(yǔ)句和標號會(huì )產(chǎn)生不可預測的結果。
④匯編語(yǔ)句不要改變C程序中變量的值。
⑤不要在匯編語(yǔ)句中加入匯編器選項而改變匯編環(huán)境。
(3)將C程序編譯生成相應的匯編程序,手工修改和優(yōu)化C編譯器生成的匯編代碼。采用此種方法可以控制C編程器從而產(chǎn)生個(gè)有交叉列表的匯編程序,而且程序員可能對其中的匯編語(yǔ)句進(jìn)行修改。之后,對匯編程序進(jìn)行匯編可產(chǎn)生目標文件。注意,修改匯編語(yǔ)句時(shí)切勿破壞C環(huán)境。
2 混合編程應遵循的規則和詳細的接口規范
2.1 寄存器規則
在C環(huán)境中,定義了嚴格的寄存器規則。寄存器規則明確了編譯器如何使用寄存器以及在函數調用過(guò)程中如何保護寄存器。調用函數時(shí),被調用函數負責保護某些寄存器,這些寄存器不必由調用者來(lái)保護。如果調用者需要使用沒(méi)有保護的寄存器,則調用者在調用函數前必須予以保護。下面具體說(shuō)明寄存器規則:
(1)輔助寄存器AR1、AR6、AR7由被調用函數保護,即可以在函數執行過(guò)程中修改,但在函數返回時(shí)必須恢復。在TMS320C54X中,編譯器將AR1和AR6用作寄存器變量。其中,AR1被用作第一個(gè)寄存器變量,AR6被有作第二個(gè)寄存器變量,其順序不能改變。
AR0、AR2、AR3、AR4、AR5可以自由使用,即在函數執行過(guò)程中可以修改,而且不必恢復。
(2)堆棧指針SP在函數調用時(shí)必須予以保護,但其是自動(dòng)保護的,即在返回時(shí),壓入椎棧的內容都將被全部彈出。
(3)ARP在函數進(jìn)入和返回時(shí),必須為0,即當前輔助寄存器為AR0。函數執行時(shí)可以是其它值。
(4)在缺省的情況下,編譯器總是認為OVM為0。因此,若在匯編程序中將OVM置為1,則在返回C環(huán)境時(shí),必須將其恢復為0。
(5)其它狀態(tài)位和寄存器在子程序中可以任意使用,不必恢復。
2.2 標識符合名規則
C編譯器將C程序定義的所有標識符前都加一下劃線(xiàn)(-)。因此,必須將在C程序中要引用的匯編變量和匯編模塊子程序的名字前加上下劃線(xiàn)(-)。如果變量?jì)H在匯編模塊中使用,則不加下劃線(xiàn)(-)的變量名可以任意使用,而不會(huì )與C標識符發(fā)生沖突。
2.3 函數調用規則
C編譯器規定了一組嚴格的函數調用規則。除了特殊的運行支持函數外,任何調用C函數或被C函數所調用的函數都必須遵循這些規則,否則就會(huì )破壞C環(huán)境,造成不可預測的結果。
2.3.1 參數傳遞
函數調用前,將參數以逆序壓入運行堆棧,即最右邊的參數最先入棧,然后自右向左將參數依次入棧。但是,對于TMS320C54X,在函數調用時(shí),第一個(gè)參數放入累加器A中進(jìn)行傳遞。若參數是長(cháng)整型和浮點(diǎn)數時(shí),則低位字先壓棧,高位字后壓棧。若參數中有結構形式,則調用函數給結構分配空間,其地址通過(guò)累加器A傳遞給被調用函數。
2.3.2 結果返回
函數調用結束后,將返回值置于累加器A中。整數和指針在累加器A的低16位中返回。浮點(diǎn)數和長(cháng)整型數在累加器A的32位中返回。
2.3.3 函數調用時(shí)需注意的一些問(wèn)題
參數不是由被調用函數彈出椎棧,而是由調用函數彈出。因此調用函數可以傳遞任意數目的參數至函數,而且函數不必知道有多少個(gè)參數傳遞。
在匯編程序中,除了自動(dòng)初始化全局變量外,不要將.cinit段用作其它用途。C程序在boot.asm中的啟動(dòng)程序認為.cinit段中放置的全部是初始化表,因此將其它一些信息放入.cinit段將產(chǎn)生不可預料的結果。
如果要定義在C程序中訪(fǎng)問(wèn)的匯編變量或調用的匯編子程序,則必須在匯編程序中用.global說(shuō)明為外部;同樣,如果要定義在匯編程序中要調用的C函數或訪(fǎng)問(wèn)變量,也必須在C程序中將其以exterm說(shuō)明為外部。
下面給出具體例子。
C程序:
Extern int asmfunc ( ); /*聲明外部的匯編子程序*/
/*注意函數名前不要加下劃線(xiàn)*/
int gvar; /*定義全局變量*/
main( )
{
int I=3;
I=asmfunc(i); /*進(jìn)行函數調用*/
}
匯編程序:
_asmfunc: ;函數名膠一定要有下劃線(xiàn)
ADD *(-gvar),A ;I的值在累加器A中
STL A,*(-gvar) ;返回結果在累加器A中
RETD ;子程序返回
3 C語(yǔ)言和匯編語(yǔ)言混合編程軟件設計要點(diǎn)和具體設計實(shí)例
在智能測試儀表的軟件設計中,要完成對振動(dòng)信號進(jìn)行數據采集,從而進(jìn)行頻譜分析的主要功能。在這個(gè)具體實(shí)例中,主程序要完成系統的實(shí)始化,進(jìn)行用戶(hù)操作界面顯示,并且進(jìn)行鍵值查詢(xún),根據按鍵值決定程序的流程,從而完成儀器設計要求的各項功能。主程序對運行速度和代碼效率要求不高,但要求可讀性強且修改維護容易,因此采和C語(yǔ)言實(shí)現。另外一些子程序如FFT算法,對運行速度要求較高,可用匯編語(yǔ)言實(shí)現。而DSP與PC機的通訊與硬件串口有關(guān),采用匯編語(yǔ)言易于實(shí)現編程,因此也采用匯編語(yǔ)言鈄其做成子程序,而在C語(yǔ)言編寫(xiě)的主程序中調用它。
在實(shí)際的系統軟件設計中,可以根據具體情況來(lái)選擇將某一模塊或某一子程序用C語(yǔ)言或匯編語(yǔ)言來(lái)實(shí)現,從而更充分地發(fā)揮兩者的優(yōu)勢,將DSP技術(shù)更加充分地利用于各種系統設計中。
在此,僅以A/D數據采集為例來(lái)具體說(shuō)明C語(yǔ)言和匯編語(yǔ)言的相互調用問(wèn)題。由于篇幅有限,僅列出與混合編程及相互調用相關(guān)的部分程序以供分析和參考。
C程序:
Extern void ad1247( ); /*定義外部的匯編函數*/
/*函數名前不必加下劃線(xiàn)*/
main( ) /*主程序*/
{
int adlength=2048; /*數據的采樣長(cháng)度*/
int adfreq=40; /*數據采樣頻率*/
.
.
}
匯編程序:
.mmregs
FP .set AR7
.sect.text
.global_ad1247 ;定義匯編子程序,以global說(shuō)明要被外部的C程序調用,函數名前要有劃線(xiàn)
.bss len,1 ;定義局部變量len
.bss freq,1 ;定義局站變量freq,變量名前不必加下劃線(xiàn)
.
.
.
_ad1247 ;程序入口
PSHM AR6 ;保護AR6
PSHM AR7 ;保護AR6
PSHM AR1 ;保護AR1
FRAME #-16 ;為建立的局部幀分配空間函數體
STL A,*(len) ;將置于累加器A的第一個(gè)參數傳給變量len
SSBX CPL ;用SP的直接尋址方式
LD @17,A ;第二個(gè)參數的偏移地址
STL A,*(freq) ;將置于堆棧中的第二個(gè)參數傳給變量freq
.
.
.
FRAME #16 ;釋放局部幀的空間
POPM AR1 ;恢復 AR1
POPM AR7 ;恢復 AR7
POPM AR6 ;恢復 AR6
RET ;返回
其中有關(guān)函數調用中堆棧的使用和分配,詳見(jiàn)圖1.
由以上的例子可以看出,采用C語(yǔ)言和匯編語(yǔ)言混合諧和的方法,可以大大提高編程的效率,使程序設計者可以把精力更多地集中到算法的實(shí)現上,而不必關(guān)心寄存器的使用和安排;在一些要求代碼執行效率高的地方可以用匯編語(yǔ)言來(lái)實(shí)現,從而可以編寫(xiě)出高效的處理程序,將DSP技術(shù)更加充分地利用于各種系統設計中。
評論