第4章C55x處理器的軟件設計_第1頁
第4章C55x處理器的軟件設計_第2頁
第4章C55x處理器的軟件設計_第3頁
第4章C55x處理器的軟件設計_第4頁
第4章C55x處理器的軟件設計_第5頁
已閱讀5頁,還剩108頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

2023年2月4日TMS320C55xDSP原理及應用1第4章C55x處理器的軟件設計

內(nèi)容提要

C55x系列處理器應用靈活、處理能力強大,為開發(fā)、使用提供了一個很好的硬件平臺,要使這個平臺更好的發(fā)揮作用,高效、方便的軟件設計是不可或缺的。

程序的主體框架和對實時性要求不高的部分采用C/C++語言,而算法實現(xiàn)采用匯編語言,這樣能夠充分發(fā)揮二者的優(yōu)點,解決易讀性和效率之間的矛盾。同時也改善了軟件的移植性,在軟件移植時不用改變程序的主體框架,只要為處理器提供相應的算法即可。

本章主要介紹了C55x處理器的程序基本結(jié)構(gòu),C語言編程以及優(yōu)化,C語言與匯編語言的混合編程,通用目標文件格式,最后對C55x處理器的數(shù)字信號處理庫和圖像、視頻處理庫進行了介紹。2023年2月4日TMS320C55xDSP原理及應用2第4章C55x處理器的軟件設計4.1C55x處理器程序基本結(jié)構(gòu)4.2C語言程序開發(fā)及優(yōu)化4.3C語言與匯編語言的混合編程4.4通用目標文件格式4.5C55x處理器的數(shù)字信號處理庫和圖像、視頻處理庫2023年2月4日TMS320C55xDSP原理及應用3第4章C55x處理器的軟件設計

C55x處理器軟件開發(fā)流程C/C++源文件C編譯器匯編源代碼COFF目標文件匯編器鏈接器可執(zhí)行COFF文件宏源文件歸檔器宏調(diào)用庫歸檔器目標文件庫運行支持庫建立運行支持庫2023年2月4日TMS320C55xDSP原理及應用4第4章C55x處理器的軟件設計

●匯編器:是把匯編源代碼轉(zhuǎn)換成機器語言。

●匯編器:是把匯編源代碼轉(zhuǎn)換成機器語言。

●鏈接器:則將多個目標文件結(jié)合成一個可執(zhí)行文件。

●歸檔器:可以把一組文件歸檔為一個庫,供用戶使用。

如果用戶只用匯編語言編寫程序,則將跳過C編譯器而直接通過匯編器生成目標文件。2023年2月4日TMS320C55xDSP原理及應用5第4章C55x處理器的軟件設計

4.1C55x處理器程序基本結(jié)構(gòu)

根據(jù)任務調(diào)度的方式不同,C55x處理器程序大體可以分為兩類

:(1)

由程序自己完成任務調(diào)度

程序運行效率高,對硬件中斷響應快,程序運行穩(wěn)定,適合于任務較為單一,實時性較強的應用;(2)由嵌入式操作系統(tǒng)完成任務調(diào)度

但如果要利用處理器同時完成多個任務,應用嵌入式操作系統(tǒng)是十分有必要的,這是因為嵌入式操作系統(tǒng)可以將應用分解為多個任務,簡化了應用系統(tǒng)軟件設計,更為重要的是良好的多任務設計有助于提高系統(tǒng)的穩(wěn)定性和可靠性。2023年2月4日TMS320C55xDSP原理及應用6第4章C55x處理器的軟件設計

4.1.1自我調(diào)度程序的基本結(jié)構(gòu)雖然嵌入式操作系統(tǒng)已經(jīng)發(fā)展得較為成熟,但通過程序自身完成任務調(diào)度仍然保持著旺盛的生命力,這是因為這種方式適合于DSP這種需要對大量實時數(shù)據(jù)完成順序處理的應用。下面給出自我調(diào)度程序的基本結(jié)構(gòu)。2023年2月4日TMS320C55xDSP原理及應用7

中斷服務程序1;//定時器到時 中斷服務程序2;//讀取A/D轉(zhuǎn)換 中斷服務程序3;//讀取通訊數(shù)據(jù) ……

中斷服務程序m;//讀取按鍵碼 Main() { DSP_INT(){……}; //DSP初始化

For(;;) //主循環(huán)

{ if(條件1) {處理模塊1;} //條件滿足運行處理模塊1 …… if(條件n) {處理模塊n;} //條件滿足運行處理模塊n } }

自我調(diào)度程序通常由中斷程序部分、初始化部分和主循環(huán)部分組成

中斷服務程序一般僅讀取數(shù)據(jù)和改變條件,由主循環(huán)中的程序處理,這種處理必須要輪流進行,因此此程序僅適于實時性要求不高的場合。2023年2月4日TMS320C55xDSP原理及應用8第4章C55x處理器的軟件設計

初始化部分通常完成DSP軟、硬件的初始化設置,啟動系統(tǒng)硬件,使能DSP中斷等工作。

主循環(huán)部分是程序的主體,將由它完成數(shù)據(jù)輸入、處理和輸出等工作。主循環(huán)由條件判斷和處理模塊組成,當滿足條件時運行處理模塊,不滿足條件則自動跳到下一個判斷條件。中斷服務程序通過設置判斷標志來影響主循環(huán)部分的運行。但對于要求立即處理的程序,要放在中斷服務程序中。4.1.1自我調(diào)度程序的基本結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應用9第4章C55x處理器的軟件設計

為了滿足實時運行的要求,自我調(diào)度程序的主循環(huán)部分必須將處理時延限制在最大可接受時延內(nèi),具體來說就是運行主循環(huán)的所有分支的時間總和必須小于最大可接受時延,如果不能滿足這一條件,則在最壞情況下,會造成處理數(shù)據(jù)的不連續(xù),而無法實現(xiàn)數(shù)據(jù)的實時處理。

當所編寫的程序沒有滿足上述條件時,則需要對處理流程進行修改,或修改處理算法以滿足條件。

4.1.1

自我調(diào)度程序的基本結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應用10第4章C55x處理器的軟件設計

處理模塊很多場合是要多步驟完成的(比如控制一個機械動作、按鍵過程、通訊過程),一般要用switch結(jié)構(gòu):4.1.1

自我調(diào)度程序的基本結(jié)構(gòu)

中斷服務程序j:

獲取數(shù)據(jù)和狀態(tài); switch(step){//即時處理模塊 case0:處理程序0;step++;break;

case1:處理程序1; if(a)step++;if(b)step=6;if(c)step--; break; …… casen:處理程序n;} 執(zhí)行處理結(jié)果;

中斷返回;2023年2月4日TMS320C55xDSP原理及應用11第4章C55x處理器的軟件設計

優(yōu)點:這種結(jié)構(gòu)可以適用于大多數(shù)場合,容易掌握,不必使用操作系統(tǒng),實時性也好。缺點:必須用switch之類的程序結(jié)構(gòu)找到要執(zhí)行的程序段,編程繁瑣。在有多個實時多步處理任務且有時任務之間還有協(xié)調(diào)和同步的要求時,編程難度大。4.1.1

自我調(diào)度程序的基本結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應用12第4章C55x處理器的軟件設計

任務程序j: //處理模塊:

處理程序0;休息t0;//如果是可剝奪任務,也可不要此休息(也叫掛起)語句。

m1:處理程序1;等待信號量s1; 處理程序2;休息t2;

if(條件1)gotom1;

elseif(條件2)gotom6; 處理程序3;等待信號量s2;……m6:處理程序6;等待信號量s3;……處理程序n;休息t8;返回任務起點;2023年2月4日TMS320C55xDSP原理及應用13第4章C55x處理器的軟件設計

在數(shù)字信號處理器中運行的操作系統(tǒng)必須滿足系統(tǒng)實時性要求,而操作系統(tǒng)的實時方式可以分成兩種——硬實時方式和軟實時方式。

軟實時系統(tǒng)由軟件來進行任務的切換,而硬實時系統(tǒng)則按照固定時鐘節(jié)拍切換任務。軟實時系統(tǒng)使各個任務盡快運行,而不要求限定某個任務在多長時間內(nèi)完成;硬實時系統(tǒng)中各任務不僅要執(zhí)行無誤,而且要準時。

4.1.2

應用嵌入式操作系統(tǒng)

嵌入式實時操作系統(tǒng)的作用就是合理調(diào)度、分配任務的運行,使各個任務正確、及時地執(zhí)行。

2023年2月4日TMS320C55xDSP原理及應用14第4章C55x處理器的軟件設計

嵌入式操作系統(tǒng)的核心是操作系統(tǒng)內(nèi)核,在多任務系統(tǒng)中,內(nèi)核負責管理各個任務,為每個任務分配CPU時間,負責任務間的通信和任務切換。根據(jù)其重要程度的不同系統(tǒng)中每個任務被賦予一定的優(yōu)先級,內(nèi)核將根據(jù)任務的優(yōu)先級進行任務調(diào)度。基于優(yōu)先級的內(nèi)核可以分成不可剝奪型和可剝奪型兩種類型。

4.1.2

應用嵌入式操作系統(tǒng)

2023年2月4日TMS320C55xDSP原理及應用15第4章C55x處理器的軟件設計

1.

不可剝奪型內(nèi)核

不可剝奪型內(nèi)核要求每個任務主動放棄CPU使用權(quán),這種任務的調(diào)度方法也可以叫做合作型多任務,每個任務相互合作,共享一個CPU。

不可剝奪型內(nèi)核中的異步事件由中斷服務來處理,中斷服務可以使一個高優(yōu)先級的任務由掛起態(tài)變?yōu)榫途w態(tài);但在中斷服務之后,CPU的使用權(quán)還給原來被中斷的任務,直到該任務主動放棄CPU的使用權(quán),一個高優(yōu)先級的任務才能進入運行態(tài)。4.1.2

應用嵌入式操作系統(tǒng)

2023年2月4日TMS320C55xDSP原理及應用16第4章C55x處理器的軟件設計

這種內(nèi)核的優(yōu)點是響應中斷快,采用不可剝奪型內(nèi)核允許任務使用不可重入函數(shù),每個任務調(diào)用不可重入型函數(shù)不必擔心其他任務可能使用該函數(shù)而造成數(shù)據(jù)破壞。使用不可剝奪型內(nèi)核時,任務的響應時間取決于最長任務的執(zhí)行時間。使用該內(nèi)核很少需要使用信號量保護共享數(shù)據(jù),這是因為正在運行的任務不必擔心其他任務搶占CPU;但如果任務使用共享設備時,還應使用互斥型信號量。

4.1.2

應用嵌入式操作系統(tǒng)

1.

不可剝奪型內(nèi)核

2023年2月4日TMS320C55xDSP原理及應用17第4章C55x處理器的軟件設計

不可剝奪型內(nèi)核的缺點是響應時間具有不確定性,無法確定最高優(yōu)先級的任務何時能夠獲得CPU的使用權(quán)。

2.可剝奪型內(nèi)核

可剝奪型內(nèi)核運行時,一旦具有最高優(yōu)先級的任務就緒,就總能得到CPU的使用權(quán)。當有一個具有更高優(yōu)先權(quán)的任務進入就緒態(tài)時,當前運行的任務將被掛起,更高級的任務立刻得到CPU的使用權(quán)。1.

不可剝奪型內(nèi)核

4.1.2

應用嵌入式操作系統(tǒng)

2023年2月4日TMS320C55xDSP原理及應用18第4章C55x處理器的軟件設計

如果是中斷服務子程序使一個高優(yōu)先級的任務進入就緒狀態(tài),中斷完成后,被中斷的任務被掛起,開始運行更高級的任務。使用可剝奪型內(nèi)核可以隨時執(zhí)行最高級任務,這使得任務的響應時間得以最優(yōu)化。使用可剝奪內(nèi)核要求應用程序不應直接使用不可重入函數(shù),如果要使用則應滿足互斥條件。

4.1.2

應用嵌入式操作系統(tǒng)

2.可剝奪型內(nèi)核

2023年2月4日TMS320C55xDSP原理及應用19第4章C55x處理器的軟件設計

4.1.2

應用嵌入式操作系統(tǒng)

內(nèi)核的主要工作是完成任務的調(diào)度,任務也可稱作線程,是一個簡單的程序,該程序認為CPU完全屬于自己。使用操作系統(tǒng)要求程序員把所要完成的工作分解為多個任務,每個任務都是應用的一部分。任務都被賦予一定的優(yōu)先級,并擁有自己的一套CPU寄存器和獨立的堆??臻g,每個任務堆??臻g大小也可不同,在創(chuàng)建任務時指定。2023年2月4日TMS320C55xDSP原理及應用20第4章C55x處理器的軟件設計

4.1.2

應用嵌入式操作系統(tǒng)

任務是一個無限循環(huán),它必須處于下列5個狀態(tài)之一:

休眠狀態(tài)是任務駐留在內(nèi)存之中,但并沒有被系統(tǒng)內(nèi)核所調(diào)用;

就緒狀態(tài)是任務已經(jīng)準備好,但由于該任務的優(yōu)先級比正在運行的任務的優(yōu)先級低,還暫時不能運行;

運行狀態(tài)是任務擁有CPU的使用權(quán),正在運行;掛起狀態(tài)是任務正在等待某一個事件的發(fā)生以結(jié)束目前的等待(如等待外設的I/O操作、等待共享資源、等待定時或超時信息等事件);發(fā)生中斷時,CPU進入中斷服務程序,而暫時不能運行當前的任務,任務就進入了被中斷態(tài)。

2023年2月4日TMS320C55xDSP原理及應用21第4章C55x處理器的軟件設計4.1.2

應用嵌入式操作系統(tǒng)

操作系統(tǒng)需要在多個任務之間轉(zhuǎn)換和調(diào)度,這是因為CPU在某一時刻只能為一個任務提供服務,CPU必須為一系列任務輪流服務。多任務運行可以使CPU的利用率達到最高,并使應用程序模塊化,使用多任務可以使程序更容易設計和維護。

當任務從當前任務切換到另一個任務時,必須保存正在執(zhí)行的任務的當前狀態(tài)。所謂“任務的當前狀態(tài)”即CPU寄存器中的所有內(nèi)容;這些內(nèi)容被保存在任務自己的堆棧中,以備任務下次執(zhí)行時恢復當前狀態(tài)。在保存完當前任務后,要把下一個任務的當前狀態(tài)裝入CPU寄存器,并開始下一個任務的運行,這一過程叫做“任務切換”。2023年2月4日TMS320C55xDSP原理及應用22第4章C55x處理器的軟件設計

4.1.2

應用嵌入式操作系統(tǒng)每個任務都有其優(yōu)先級,任務越重要,被賦予的優(yōu)先級應越高。如果程序執(zhí)行過程中任務的優(yōu)先級不變,則稱為靜態(tài)優(yōu)先級;反之則稱為動態(tài)優(yōu)先級。

所謂“任務管理”就是在內(nèi)核的控制下任務在五種狀態(tài)之間切換。下面是一個常用實時操作系統(tǒng)

μC/OS-II的任務狀態(tài)轉(zhuǎn)換圖。2023年2月4日TMS320C55xDSP原理及應用23第4章C55x處理器的軟件設計

OSIntExit()OSTaskDel()OSTaskDel()掛起狀態(tài)休眠狀態(tài)就緒狀態(tài)運行狀態(tài)被中斷狀態(tài)OSTaskCreate()OSTaskCreateExt()OSFlagPost()OSMboxPost()OSMboxPost()OSMutexPost()OSQPost()OSQPostFront()OSSemPost()OSTaskResume()OSTimeDlyResume()OSTimeTick()OSStart()OSIntExt()OS_TASK_SW()CPU使用權(quán)被剝奪OSTaskDel()OSFlagPend()OSMboxPend()OSMutexPend()OSQPend()OSSemPend()OSTaskSuspend()OSTimeDly()OSTimeDlyHMSM()中斷2023年2月4日TMS320C55xDSP原理及應用24第4章C55x處理器的軟件設計

4.1.2

應用嵌入式操作系統(tǒng)

不同任務之間有可能會使用共同的資源,當它們同時使用共享資源時有可能發(fā)生錯誤,嵌入式操作系統(tǒng)提供了信號量這一約定機制,通過該機制可以控制共享資源的使用權(quán),或標志某一事件的發(fā)生,也常用于兩個任務之間的同步,或任務和中斷之間的同步。等待某信號量:OSSemPend(指向該信號量的指針);調(diào)用此函數(shù)的任務會使自己掛起,直到得到該信號量(另一任務或中斷發(fā)送該信號量)或掛起超時。發(fā)送某信號量:OSSemPost(指向該信號量的指針);2023年2月4日TMS320C55xDSP原理及應用25第4章C55x處理器的軟件設計

4.1.2

應用嵌入式操作系統(tǒng)

信號量可以看作一把鑰匙。當任務要運行時首先要取得這把鑰匙。如果信號量已經(jīng)被其他任務占用,那么該任務只好掛起并等待信號量被當前使用者釋放。

2023年2月4日TMS320C55xDSP原理及應用26第4章C55x處理器的軟件設計

4.1.2

應用嵌入式操作系統(tǒng)

任務要使用信號量,首先要對信號量進行初始化。

如果任務要得到信號量,首先要執(zhí)行“等待”操作。

如果該信號量有效(信號量的值大于0),則該信號量值減1,任務得以繼續(xù)執(zhí)行。

如果信號量的值為0,等待信號量的任務就被列入等待信號量任務表。

2023年2月4日TMS320C55xDSP原理及應用27第4章C55x處理器的軟件設計

如果等待時間超過某一設定值,該信號量還無效,那么等待信號量的任務自動進入就緒狀態(tài)并準備運行,并向系統(tǒng)報一個“超時錯誤”信息。4.1.2

應用嵌入式操作系統(tǒng)

2023年2月4日TMS320C55xDSP原理及應用28第4章C55x處理器的軟件設計

實際上,等待該信號量的任務可能有多個。在嵌入式操作系統(tǒng)中通常依照優(yōu)先級來決定由哪個任務取得信號量。

任務還可以釋放信號量。

如果有任務等待該信號量,那么就會有一個任務進入就緒狀態(tài),信號量的值不增加。

如果這時沒有任務等待信號量,則信號量的值加1。4.1.2

應用嵌入式操作系統(tǒng)

2023年2月4日TMS320C55xDSP原理及應用29第4章C55x處理器的軟件設計4.1.2

應用嵌入式操作系統(tǒng)

兩個任務之間可以利用信號量來取得同步,這種同步可以分成兩類——單向同步和雙向同步。所謂“單向同步”是指任務用一個信號量觸發(fā)另一個任務。單向同步2023年2月4日TMS320C55xDSP原理及應用30第4章C55x處理器的軟件設計

當兩個任務需要相互同步對方,這時就要用到雙向同步。

兩個任務的雙向同步4.1.2

應用嵌入式操作系統(tǒng)

2023年2月4日TMS320C55xDSP原理及應用31第4章C55x處理器的軟件設計4.1.2

應用嵌入式操作系統(tǒng)

任務之間的通信可以通過兩個途徑:全局變量或消息。

使用全局變量必須保證任務或中斷服務子程序在使用該變量時沒有其他的任務或中斷服務子程序訪問該變量。另外,如果任務沒有其他機制通知其變量已經(jīng)被修改了,任務就只能周期性地查詢該變量的值。要避免這種情況,可以考慮使用消息郵箱或消息隊列。2023年2月4日TMS320C55xDSP原理及應用32第4章C55x處理器的軟件設計

4.1.2

應用嵌入式操作系統(tǒng)

消息郵箱是一個任務或一個中斷程序通過一個指針型變量把一個消息(指針)放到郵箱之中,而一個或多個任務通過內(nèi)核服務可以接收到這個消息。

內(nèi)核可以提供下列郵箱服務:

初始化郵箱內(nèi)的消息;

將消息放入郵箱;

等待消息進入郵箱;

從郵箱中取得消息。2023年2月4日TMS320C55xDSP原理及應用33第4章C55x處理器的軟件設計

消息隊列則是任務或中斷程序把一個消息指針放到消息隊列之中,而一個或多個任務通過內(nèi)核服務從消息隊列中接收消息。

內(nèi)核提供消息隊列服務如下:

消息隊列初始化,即將消息隊列清空;

將一個消息放到消息隊列之中;

等待消息到來;

得到消息。4.1.2

應用嵌入式操作系統(tǒng)

2023年2月4日TMS320C55xDSP原理及應用34第4章C55x處理器的軟件設計

TMS320C55x處理器為C語言開發(fā)提供了一系列工具,包括:優(yōu)化C/C++編譯器、鏈接器和歸檔器。

并支持混合編程。

C語言的優(yōu)點在于程序可讀性強。4.2C語言程序開發(fā)及優(yōu)化2023年2月4日TMS320C55xDSP原理及應用35第4章C55x處理器的軟件設計

4.2.1C語言中的數(shù)據(jù)類型

C55x支持下列數(shù)據(jù)類型包括字符、定點數(shù)、浮點數(shù)、指針等。4.2C語言程序開發(fā)及優(yōu)化類型長度內(nèi)容最小值最大值signedchar(有符號字符)16位ASCII碼-3276832767char,unsignedchar(無符號字符)16位ASCII碼065535short,signedshort(短整型)16位二進制補碼-3276832767unsignedshort(無符號短整型)16位二進制數(shù)0655352023年2月4日TMS320C55xDSP原理及應用36第4章C55x處理器的軟件設計

char,unsignedcharpointers(數(shù)據(jù)指針)小存儲器模式16位0xFFFF類型長度內(nèi)容最小值最大值int,signedint(整型)16位二進制補碼3276832767unsignedint(無符號整型)16位二進制數(shù)065535long,signedlong(長整型)32位二進制補碼21474836482147483647unsignedlong(無符號長整型)32位二進制數(shù)04249967295longlong(40位長整型)40位二進制補碼549755813888549755813887unsignedlonglong(40位無符號長整型)40位二進制數(shù)01099511627775emum(枚舉型)16位二進制補碼3276832767float(浮點型)32位32位浮點數(shù)1.175494e383.40282346e+382023年2月4日TMS320C55xDSP原理及應用37第4章C55x處理器的軟件設計類型長度內(nèi)容最小值最大值double(雙精度浮點數(shù))32位32位浮點數(shù)1.175494e383.40282346e+38longdouble(長雙精度浮點數(shù))32位32位浮點數(shù)1.175494e383.40282346e+38大存儲器模式23位二進制數(shù)00x7FFFFFpointers(程序指針)24位二進制數(shù)00xFFFFFF

指針分為程序指針和數(shù)據(jù)指針兩種,其區(qū)別在于程序指針尋址是按字節(jié)尋址,而數(shù)據(jù)指針以字為單位進行尋址。2023年2月4日TMS320C55xDSP原理及應用38第4章C55x處理器的軟件設計

C55x處理器包含數(shù)據(jù)空間和I/O空間,為了在C/C++中對I/O空間進行尋址,編譯器給出了關(guān)鍵字ioport,以支持I/O尋址模式。

ioport關(guān)鍵字可以用在數(shù)組、結(jié)構(gòu)、聯(lián)合以及枚舉類型當中。

當用在數(shù)組中時,ioport可以作為數(shù)組中的元素;在結(jié)構(gòu)中使用ioport,只能是指向ioport數(shù)據(jù)的指針而不能直接作為結(jié)構(gòu)的成員。

4.2C語言程序開發(fā)及優(yōu)化4.2.2對I/O空間進行尋址

2023年2月4日TMS320C55xDSP原理及應用39第4章C55x處理器的軟件設計

ioport類型只能用來聲明全局或靜態(tài)變量,如果在本地變量中使用ioport類型,則變量必須用指針聲明。接下來給出指針聲明ioport類型的例子:voidfoo(void){ioportinti;/*無效的聲明*/ioportint*j;/*有效聲明*/}應當注意聲明ioport類型的指針只有16位,這是因為I/O空間是16位尋址,而不受大/小存儲器模式的限制。4.2.2

對I/O空間進行尋址

2023年2月4日TMS320C55xDSP原理及應用40第4章C55x處理器的軟件設計

在printf()中不能直接引用ioport指針,如果要引用,則必須進行強制類型轉(zhuǎn)換“void*”,具體例子如下:ioportint*p;printf(“%p\n”,(void*)p);

4.2.2

對I/O空間進行尋址

2023年2月4日TMS320C55xDSP原理及應用41第4章C55x處理器的軟件設計

這段代碼的編譯結(jié)果如下:

_foo:MOV#_i,port(#_ioport_pointer) ;存儲i在I/O空間的地址MOVport(#_ioport_pointer),AR3;載入i的地址MOV*AR3,AR1 ;將i的內(nèi)容存放到AR1中MOVAR1,*abs16(#_j) ;將i的內(nèi)容保存到jreturn給出在本地變量中使用ioport類型的例子:

int*ioportioport_pointer;/*ioport指針*/inti;intj;voidfoo(void){ioport_pointer=&i;j=*ioport_pointer;}2023年2月4日TMS320C55xDSP原理及應用42第4章C55x處理器的軟件設計

下來給出一個指向I/O空間數(shù)據(jù)指針的例子:

/*指向ioport數(shù)據(jù):*/ioportint*ptr_to_ioport;ioportinti;voidfoo(void){intj;i=10;ptr_to_ioport=&i;j=*ptr_to_ioport;}上面代碼編譯結(jié)果如下:

_foo:MOV#_i,*abs16(#_ptr_to_ioport) ;存儲_i的地址MOV*abs16(#_ptr_to_ioport),AR3AADD#–1,SPMOV#10,port(#_i) ;向_i中存入10MOV*AR3,AR1MOVAR1,*SP(#0)AADD#1,SPreturn2023年2月4日TMS320C55xDSP原理及應用43第4章C55x處理器的軟件設計上面代碼編譯結(jié)果如下:

_foo:MOV#10,port(#_i) ;將10存在_i中MOV#_i,port(#_iop_ptr_to_ioport);存儲_i的地址MOVport(#_iop_ptr_to_ioport),AR3 ;載入_i的地址MOV*AR3,AR1 ;載入_iMOVAR1,port(#_j);將10存到_j中return下面的例子是利用ioport指針指向I/O空間的數(shù)據(jù):

/*指向ioport數(shù)據(jù)的ioport指針:*/ioportint*ioportiop_ptr_to_ioport;ioportinti;ioportintj;voidfoo(void){i=10;iop_ptr_to_ioport=&i;j=*iop_ptr_to_ioport;}2023年2月4日TMS320C55xDSP原理及應用44第4章C55x處理器的軟件設計

4.2.3interrupt關(guān)鍵字中斷操作需要使用特定的寄存器保存規(guī)則,并具有特殊的返回順序。

C55x編譯器使用了關(guān)鍵字“interrupt”定義中斷函數(shù)。

當C/C++代碼被中斷時,中斷程序必須保存所有與程序有關(guān)的寄存器。

當使用“interrupt”關(guān)鍵字定義函數(shù)時,中斷函數(shù)必須返回空并且沒有參數(shù)傳遞。

2023年2月4日TMS320C55xDSP原理及應用45第4章C55x處理器的軟件設計

4.2.3interrupt關(guān)鍵字

中斷函數(shù)可以定義本地變量并且使用堆棧。接下來給出定義中斷函數(shù)的例子:

interruptvoidint_handler(){unsignedintflags;...}

c_int00是C/C++程序的入口點,這個函數(shù)名被系統(tǒng)復位中斷保留,該中斷服務程序用來初始化系統(tǒng)并調(diào)用main函數(shù)。2023年2月4日TMS320C55xDSP原理及應用46第4章C55x處理器的軟件設計

onchip關(guān)鍵字的作用是告訴編譯器由該關(guān)鍵字定義的指針所指向的數(shù)據(jù)可以作為一個雙乘法指令中的操作數(shù)。

如果onchip關(guān)鍵字向函數(shù)傳遞數(shù)據(jù),或者最終所引用的數(shù)據(jù)是用onchip定義的,則該數(shù)據(jù)必須在片上內(nèi)存。如果該數(shù)據(jù)在片外,則當通過BB數(shù)據(jù)總線訪問該數(shù)據(jù)時將產(chǎn)生一個總線錯誤。下面給出用onchip定義數(shù)組和指針的例子。

onchipintx[100]; /*arraydeclaration*/onchipint*p; /*pointerdeclaration*/

4.2.4onchip關(guān)鍵字2023年2月4日TMS320C55xDSP原理及應用47第4章C55x處理器的軟件設計

4.2.5C語言的優(yōu)化(略)如果將未經(jīng)優(yōu)化的C語言程序直接運行會發(fā)現(xiàn)運行效率較低,并且產(chǎn)生的代碼較大,而通過優(yōu)化可以較好地解決這些問題。優(yōu)化的作用是對循環(huán)進行化簡,重新組織表達式和聲明,將變量直接分配到寄存器中。

通過優(yōu)化可以提高程序運行效率,縮小程序編碼數(shù)量。2023年2月4日TMS320C55xDSP原理及應用48第4章C55x處理器的軟件設計

4.2.5C語言的優(yōu)化C/C++編譯器提供了不同的優(yōu)化選擇,通過修改cl55命令行中的-on選擇就可以方便地選擇不同的優(yōu)化等級,n代表優(yōu)化等級,包括0、1、2和3。下面給出不同優(yōu)化等級的功能。

(1)

O0

簡化控制流圖

把變量分配到寄存器

分析循環(huán)的各種情況,只保留一個退出循環(huán)的分支刪除未用的代碼簡化表達式和聲明把用inline聲明的函數(shù)變?yōu)檎{(diào)用關(guān)系2023年2月4日TMS320C55xDSP原理及應用49第4章C55x處理器的軟件設計

4.2.5C語言的優(yōu)化

(2)

O1

除了

O0的各種優(yōu)化功能外,還有如下功能:

在分配變量時,將數(shù)值直接賦給變量而不是給出變量的索引值

去掉沒有用的分配變量和表達式

去掉本地通用表達式2023年2月4日TMS320C55xDSP原理及應用50第4章C55x處理器的軟件設計

(3)

O2

除了

O1的各種優(yōu)化功能外,還有如下功能:

完成循環(huán)優(yōu)化

去掉全局通用的子表達式去掉全局沒有用的分配變量和表達式

完成循環(huán)的化解

當只用-o選項時優(yōu)化器自動進行-O2優(yōu)化4.2.5C語言的優(yōu)化2023年2月4日TMS320C55xDSP原理及應用51第4章C55x處理器的軟件設計

(4)O3除了

O2的各種優(yōu)化功能外,還有如下功能:

去掉未調(diào)用的函數(shù)

簡化返回值未使用的函數(shù)將小函數(shù)進行內(nèi)嵌調(diào)用

對被調(diào)用的函數(shù)聲明進行重新排序,以便被優(yōu)化的調(diào)用方能夠找到該函數(shù)完成文件級優(yōu)化4.2.5C語言的優(yōu)化2023年2月4日TMS320C55xDSP原理及應用52第4章C55x處理器的軟件設計4.2.5C語言的優(yōu)化優(yōu)化器分析數(shù)據(jù)流時將盡量減少對內(nèi)存的訪問,如果這個數(shù)據(jù)必須從內(nèi)存中得到,則該數(shù)據(jù)必須用volatile關(guān)鍵字定義,這樣可以使編譯器不對該變量進行優(yōu)化。例如聲明一個指針unsignedint*ctrl;

當在循環(huán)中有如下語句時

while(*ctrl!=0xFF);

優(yōu)化器將只在進入循環(huán)的初始化中進行一次內(nèi)存讀,而在循環(huán)當中不在更新該變量的內(nèi)容,如果該變量被中斷或其他程序改變,由于循環(huán)中的ctrl的值沒有更新,將會使程序不能按照正確的方式執(zhí)行,這里應當用如下方法聲明ctrl:volatileunsignedint*ctrl;特別當該變量在中斷函數(shù)中被賦值,而該變量在主函數(shù)的循環(huán)中被用到時,必須用volatile聲明該變量。

2023年2月4日TMS320C55xDSP原理及應用53第4章C55x處理器的軟件設計

4.3.1

在C語言中直接嵌套匯編語句C55x的C/C++編譯器允許使用者在C語言代碼中直接嵌套匯編語句,嵌套匯編語句的語法十分簡單,只需在嵌入的匯編語句前面加上asm標示符,左右加上一個雙引號和一個小括號即可。

asm("匯編語句")

4.3C語言與匯編語言的混合編程2023年2月4日TMS320C55xDSP原理及應用54第4章C55x處理器的軟件設計

4.3.1

在C語言中直接嵌套匯編語句采用直接嵌套匯編語句的方法比較適合完成對硬件進行操作、設置狀態(tài)寄存器、開關(guān)中斷等工作,這樣做往往要比用C語言實現(xiàn)效率更高。

用C語言打開中斷的代碼:

IRQ_globalEnable(); //全局開中斷2023年2月4日TMS320C55xDSP原理及應用55第4章C55x處理器的軟件設計

下面給出該代碼編譯后的結(jié)果:

0115A6IRQ_globalEnable:0115A63C3BMOV#3,AR30115A8DF6105MOVuns(*AR3),AC00115AB76080040BFXTR#2048,AC0,T00115AF20NOP0115B046B2BCLRST1_INTM0115B24804RET

可以看到采用C語言打開全局中斷共用了6條語句,考慮到調(diào)用子函數(shù)的開銷,完成該功能一共要花費10個左右的指令周期,而采用嵌套匯編語句的方法則只用一條指令即可:

asm("BCLRST1_INTM")

2023年2月4日TMS320C55xDSP原理及應用56第4章C55x處理器的軟件設計

4.3.1在C語言中直接嵌套匯編語句采用直接嵌套的方法要十分小心,這是因為C語言編譯器并不檢查和分析所嵌入的匯編語句,而嵌入的語句很可能改變C語言的運行環(huán)境。

例如嵌入跳轉(zhuǎn)指令或者標號將會引起不可預測的后果。如果采用嵌套匯編語句,在編譯程序時不應采用優(yōu)化功能,采用優(yōu)化功能可能會調(diào)整匯編語句周圍代碼的排列順序,有可能改變程序的運行結(jié)果。

2023年2月4日TMS320C55xDSP原理及應用57第4章C55x處理器的軟件設計

如果采用該方法實現(xiàn)較復雜的功能,會造成程序的可讀性較差,并影響程序的可移植性,因此在采用匯編語言實現(xiàn)較復雜的功能時,更可行的方法是獨立編寫C語言程序和匯編程序,C語言通過函數(shù)調(diào)用匯編子程序,這樣既可以提高程序的運行效率,又保證了程序的可移植性,這要做的優(yōu)點還有程序的結(jié)構(gòu)性較好,并不影響C語言編譯器的優(yōu)化功能。

2023年2月4日TMS320C55xDSP原理及應用58第4章C55x處理器的軟件設計

要很好地使用C語言與匯編的混合編程技術(shù),必須對C語言調(diào)用子函數(shù)的規(guī)則詳細掌握,這些規(guī)則包括C/C++中寄存器的使用、函數(shù)的結(jié)構(gòu)及調(diào)用規(guī)則等,只有這樣才能正確完成C語言對匯編模塊的調(diào)用。4.3.2C語言調(diào)用匯編模塊的接口2023年2月4日TMS320C55xDSP原理及應用59第4章C55x處理器的軟件設計

4.3.2C語言調(diào)用匯編模塊的接口1.C/C++中的寄存器規(guī)則

這些規(guī)則決定編譯器在C語言環(huán)境下如何使用寄存器和如何在調(diào)用函數(shù)時傳遞參數(shù)。

在函數(shù)調(diào)用時把函數(shù)調(diào)用方叫做父函數(shù),被調(diào)用方叫做子函數(shù)。

規(guī)則規(guī)定在函數(shù)調(diào)用時所用到的寄存器需要預先保存,保存工作部分由父函數(shù)完成,父函數(shù)沒有保存的而又被子函數(shù)用到的寄存器由子函數(shù)保存。

2023年2月4日TMS320C55xDSP原理及應用60第4章C55x處理器的軟件設計

寄存器保存方保存方AC0,AC1,AC2,AC3父函數(shù)16位、32位或40位數(shù)據(jù),或24位代碼指針(X)AR0~(X)AR4(X)AR5~(X)AR7父函數(shù)子函數(shù)16位或23位指針,獲16位數(shù)據(jù)T0、T1T2、T3父函數(shù)子函數(shù)16位數(shù)據(jù)RPTCCSRBRC0、BRC1BRS1RSA0、RSA1REA0、REA1父函數(shù)父函數(shù)父函數(shù)父函數(shù)父函數(shù)父函數(shù)寄存器保存方保存方SPSSPPCRETACFCT子函數(shù)子函數(shù)2023年2月4日TMS320C55xDSP原理及應用61第4章C55x處理器的軟件設計

2.函數(shù)調(diào)用規(guī)則

父函數(shù)在調(diào)用子函數(shù)時首先要將所要傳遞的參數(shù)放入寄存器或堆棧:

如果一個函數(shù)的變量用一個省略號聲明(標志參數(shù)的數(shù)量是變化的),則剩余的參數(shù)跟著最后一個被聲明的參數(shù)被傳到堆棧,而堆棧的地址將作為訪問其他未聲明參數(shù)的索引。2023年2月4日TMS320C55xDSP原理及應用62第4章C55x處理器的軟件設計

2.函數(shù)調(diào)用規(guī)則⑵

編譯器通常先對所要傳遞的參數(shù)歸類,之后按照所歸類別將參數(shù)放到寄存器中,參數(shù)可以分成三類:

●數(shù)據(jù)指針(int*,long*,等)●16位數(shù)據(jù)(char,short,int)●32位數(shù)據(jù)(long,float,double,以及函數(shù)指針)如果參數(shù)是指向數(shù)據(jù)類型的指針,則該參數(shù)就是數(shù)據(jù)指針;如果一個參數(shù)能夠放入一個16位寄存器,則被看成一個16位數(shù)據(jù);否則該參數(shù)被看成一個32位數(shù)據(jù)。

2023年2月4日TMS320C55xDSP原理及應用63第4章C55x處理器的軟件設計

2.函數(shù)調(diào)用規(guī)則⑶一個32位(兩個字)或小于32位的結(jié)構(gòu)被當作一個32位數(shù)據(jù)通過寄存器傳送。⑷如果結(jié)構(gòu)的長度大于2個字,則通過索引傳送,即編譯器把該結(jié)構(gòu)的地址作為一個數(shù)據(jù)指針傳送。2023年2月4日TMS320C55xDSP原理及應用64第4章C55x處理器的軟件設計

2.函數(shù)調(diào)用規(guī)則⑹參數(shù)在函數(shù)聲明中的排列位置是與其所分配的寄存器有直接關(guān)系的,它們按照表中所列順序排列。參數(shù)類型

寄存器分配順序?qū)臄?shù)據(jù)類型16位或32位數(shù)據(jù)指針16位數(shù)據(jù)32位數(shù)據(jù)(X)AR0,(X)AR1,(X)AR2,(X)AR3,(X)AR4T0,T1,AR0,AR1,AR2,AR3,AR4AC0,AC1,AC2數(shù)組、字符串、指針、或占用空間長度超過兩個字節(jié)的結(jié)構(gòu)(無符號)字符、短整數(shù),整數(shù)長整數(shù)、浮點數(shù)以及長度小于等于兩個字節(jié)的結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應用65第4章C55x處理器的軟件設計

2.函數(shù)調(diào)用規(guī)則

如果參數(shù)的數(shù)量超過可使用寄存器數(shù)量,多余的參數(shù)會被壓入堆棧,子函數(shù)通過堆棧得到剩余參數(shù)。

子函數(shù)的返回參數(shù)也將根據(jù)返回參數(shù)的類型使用不同的寄存器,表給出了這一對應關(guān)系。

子函數(shù)返回類型

所使用寄存器

說明

Voidchar,unsignedchar,shortint,intlongint,float,doublestructT0AC0(X)AR0無返回參數(shù)返回16位數(shù)據(jù)返回32位數(shù)據(jù)返回地址2023年2月4日TMS320C55xDSP原理及應用66第4章C55x處理器的軟件設計

2.函數(shù)調(diào)用規(guī)則

給出參數(shù)傳遞的例子:首先聲明兩個結(jié)構(gòu),其中big的長度大于兩個字節(jié),small的長度等于兩個字節(jié)。

structbig{longx[10];};structsmall{intx;};intfn(inti1,longl2,int*p3);//參數(shù)返回T0,傳遞參數(shù)分別占用T0、AC0、AR0寄存器longfn(int*p1,inti2,inti3,inti4);//返回AC0,參數(shù)通過AR0、T0、T1、AR1傳遞structbigfn(int*p1);//返回AR0,參數(shù)通過AR1傳遞2023年2月4日TMS320C55xDSP原理及應用67第4章C55x處理器的軟件設計

intfn(structbigb,int*p1);//返回T0,參數(shù)通過AR0、AR1傳遞structsmallfn(int*p1);//參數(shù)返回AC0,參數(shù)通過AR0傳遞intfn(structsmallb,int*p1);//參數(shù)返回T0,參數(shù)通過AC0、AR0傳遞intprintf(char*fmt,...);//參數(shù)返回T0,其余參數(shù)通過堆棧傳遞,并通過fmt的地址進行索引voidfn(longl1,longl2,longl3,longl4,inti5);//參數(shù)通過AC0、AC1、AC2、堆棧和T0傳遞voidfn(longl1,longl2,longl3,int*p4,int*p5,int*p6,int*p7,int*p8,inti9,inti10);//參數(shù)通過AC0、AC1、AC2、AR0、AR1、AR2、AR3、AR4、T0、T1傳遞2023年2月4日TMS320C55xDSP原理及應用68第4章C55x處理器的軟件設計C語言程序:/*聲明外部匯編函數(shù)*/externintasmfunc(int,int*);intgvar;/*定義全局變量*/main(){inti;i=asmfunc(i,&gvar);/*調(diào)用函數(shù)*/}匯編程序:_asmfunc:ADD*AR0,T0,T0;gvar+T0=>i,i=T0RETURN;返回2023年2月4日TMS320C55xDSP原理及應用69第4章C55x處理器的軟件設計

3.被調(diào)用函數(shù)的響應

被調(diào)用函數(shù)需要完成如下工作:

子函數(shù)為本地變量、暫存空間以及函數(shù)本身可能調(diào)用函數(shù)的參數(shù)分配足夠的空間,這些工作要在函數(shù)調(diào)用之初完成。⑵

如果子函數(shù)修改一些寄存器,如T2、T3、AR5~AR7,需要子函數(shù)將這些數(shù)壓?;虬阉鼈兇鎯Φ揭粋€沒有使用的寄存器中。如果子函數(shù)修改其他寄存器則不需要預先存儲這些數(shù)。2023年2月4日TMS320C55xDSP原理及應用70第4章C55x處理器的軟件設計

3.被調(diào)用函數(shù)的響應⑶如果子函數(shù)的參數(shù)是一個結(jié)構(gòu),它所收到的是指向這個結(jié)構(gòu)的指針。如果在被調(diào)用函數(shù)中需要對結(jié)構(gòu)進行寫操作,就需要把這個結(jié)構(gòu)復制到本地空間中,如果不進行寫操作,則可以直接通過指針訪問這個結(jié)構(gòu)。

⑷子函數(shù)執(zhí)行代碼。2023年2月4日TMS320C55xDSP原理及應用71第4章C55x處理器的軟件設計

3.被調(diào)用函數(shù)的響應⑸函數(shù)按照表4-5的規(guī)則返回參數(shù),如果子函數(shù)返回一個結(jié)構(gòu),父函數(shù)為這個結(jié)構(gòu)分配空間,并傳遞指針到(X)AR0中。如果父函數(shù)沒有使用這個結(jié)構(gòu),則在(X)AR0中返回的地址為0。

⑹子函數(shù)將先前存儲的寄存器值重新放到寄存器中。

⑺子函數(shù)使堆棧返回調(diào)用前狀態(tài)。

⑻函數(shù)返回。2023年2月4日TMS320C55xDSP原理及應用72第4章C55x處理器的軟件設計

C/C++與匯編語言可以通過多種方式聯(lián)系在一起,其中包括在C/C++中引用匯編語言中的常量或變量,并可以在C語言模塊中調(diào)用匯編代碼模塊。

C/C++調(diào)用匯編語言模塊時需要符合前面所述的寄存器規(guī)則和函數(shù)調(diào)用規(guī)則。在調(diào)用匯編模塊時還應注意如下問題:4.C/C++與匯編語言的接口2023年2月4日TMS320C55xDSP原理及應用73第4章C55x處理器的軟件設計

4.C/C++與匯編語言的接口⑴調(diào)用C54x匯編函數(shù)時,應使用C54X_CALL或C54X_FAR_CALL關(guān)鍵字。⑵如果用匯編語言編寫中斷例程,則需要保存在中斷例程中使用的所有寄存器。⑶如果在匯編程序中調(diào)用C/C++函數(shù),則只有特定的寄存器在C/C++中被保存,而其他寄存器則可能被C/C++函數(shù)改變。⑷在定義匯編函數(shù)名和變量時,需要在函數(shù)名前加上下劃線“

_”來讓編譯器識別。

2023年2月4日TMS320C55xDSP原理及應用74第4章C55x處理器的軟件設計下面分別給出定義匯編函數(shù)和變量,以及在C語言中調(diào)用這些函數(shù)和變量的例子。調(diào)用匯編函數(shù)的例子如下:

4.C/C++與匯編語言的接口2023年2月4日TMS320C55xDSP原理及應用75第4章C55x處理器的軟件設計C語言程序:/*聲明外部匯編函數(shù)*/externintasmfunc(int,int*);intgvar;/*定義全局變量*/main(){inti;i=asmfunc(i,&gvar);/*調(diào)用函數(shù)*/}匯編程序:_asmfunc:ADD*AR0,T0,T0;gvar+T0=>i,i=T0RETURN;返回2023年2月4日TMS320C55xDSP原理及應用76第4章C55x處理器的軟件設計

4.C/C++與匯編語言的接口調(diào)用匯編模塊中所定義變量的例子如下:

匯編程序:.bss_var,1;定義變量.global_var;定義其為外部引用C語言程序:externintvar;/*外部變量*/var=1;/*使用變量*/2023年2月4日TMS320C55xDSP原理及應用77第4章C55x處理器的軟件設計

4.C/C++與匯編語言的接口⑸如果C/C++中的變量要在匯編語言中訪問,則該變量應用.global聲明。

⑹編譯器所默認的CPL值為1,即采用間接絕對方式尋址,如果在匯編函數(shù)中CPL被設置為0,在函數(shù)返回時應當把這個值改為1。下面的例子是對應CPL=1或=0時所使用的不同匯編語句:MOV*(#global_var),AR3;CPL==1MOVglobal_var,AR3;CPL==0

2023年2月4日TMS320C55xDSP原理及應用78⑺在匯編語言中可以通過.set、.global命令聲明全局常量,這些常量在C/C++中可以通過特殊的方式訪問。例如試圖訪問常量X,則在該常量名前需要加上“&”操作符,即在C/C++中該常量名為&X。例如:

第4章C55x處理器的軟件設計

4.C/C++與匯編語言的接口2023年2月4日TMS320C55xDSP原理及應用79第4章C55x處理器的軟件設計

匯編語言:_table_size.set10000 ;定義常量.global_table_size ;定義的變量可以被全局訪問C語言程序:externinttable_size; /*外部參數(shù)*/#defineTABLE_SIZE((int)(&table_size))………………for(i–0;i<TABLE_SIZE;++i)/*使用該常數(shù)*/2023年2月4日TMS320C55xDSP原理及應用80第4章C55x處理器的軟件設計

匯編器和鏈接器產(chǎn)生的可執(zhí)行文件所采用的格式是通用目標文件格式(COFF),采用通用目標文件格式有助于實現(xiàn)模塊化編程。

匯編器和鏈接器都支持用戶創(chuàng)建多個代碼段和數(shù)據(jù)段,這也有助于用戶的靈活編程。

編譯器產(chǎn)生的可以重新定位的代碼和數(shù)據(jù)塊叫做段。

4.4通用目標文件格式2023年2月4日TMS320C55xDSP原理及應用81第4章C55x處理器的軟件設計

初始化段裝有數(shù)據(jù)或代碼。常用的初始化段包括代碼段(.text段)、常數(shù)段(.const段)等。

未初始化段的作用是在存儲器中保留一定空間供程序生成和存儲變量使用。常用的未初始化段包括堆棧和系統(tǒng)堆棧段(.stack和.sysstack)、存儲全局和靜態(tài)變量的.bss段以及為分配動態(tài)存儲器保留的.sysmem段等。

段可以分成兩大類——初始化段和未初始化段。

4.4通用目標文件格式2023年2月4日TMS320C55xDSP原理及應用82第4章C55x處理器的軟件設計

4.4.1C/C++和匯編語言中段的分配

在C/C++程序中可以使用編譯命令直接將代碼或數(shù)據(jù)分配到所要分配的段中。4.4通用目標文件格式用CODE_SECTION命令可以分配代碼到指定的段中,在C語言中語法如下:#pragmaCODE_SECTION(symbol,“sectionname”)[;]C++中則采用下面的語句:

#pragmaCODE_SECTION(“sectionname”)[;]

2023年2月4日TMS320C55xDSP原理及應用83第4章C55x處理器的軟件設計

例:#pragmaCODE_SECTION(funcA,“codeA”)intfuncA(inta){inti;return(i=a);}編譯后的結(jié)果如下:.sect“codeA”.global_funcA

;*************************************************;*FUNCTIONNAME:_funcA*;*************************************************_funcA:……return;返回2023年2月4日TMS320C55xDSP原理及應用84第4章C55x處理器的軟件設計4.4.1C/C++和匯編語言中段的分配

在C語言中按下面給出的語法定義:#pragmaDATA_SECTION(symbol,“sectionname”)[;]

C++中的語法是:#pragmaDATA_SECTION(“

sectionname”)[;]

2023年2月4日TMS320C55xDSP原理及應用85第4章C55x處理器的軟件設計4.4.1C/C++和匯編語言中段的分配

分配數(shù)據(jù)的例子:

#pragmaDATA_SECTION(bufferB,“my_sect”)charbufferA[512];charbufferB[512];編譯后的結(jié)果如下:.global_bufferA.bss_bufferA,512,0,0.global_bufferB_bufferB:.usect“my_sect”,512,0,02023年2月4日TMS320C55xDSP原理及應用86第4章C55x處理器的軟件設計

4.4.1C/C++和匯編語言中段的分配

下面給出匯編語言中為代碼分配段的例子:.textMOV#10,AC0MOVAC0,AC1

下面給出匯編語言中為數(shù)據(jù)分配段的例子:.data.word9,10.word11,12

2023年2月4日TMS320C55xDSP原理及應用87第4章C55x處理器的軟件設計

TMS320C55x處理器采用改進的哈佛結(jié)構(gòu),在該結(jié)構(gòu)下存儲器被分成幾個獨立的空間:

程序空間

數(shù)據(jù)空間

I/O空間C55x編譯器為這些空間內(nèi)的代碼塊和數(shù)據(jù)塊分配內(nèi)存。4.4.2寄存器模式設置

(略)

2023年2月4日TMS320C55xDSP原理及應用88第4章C55x處理器的軟件設計

在小存儲器模式下,代碼段和數(shù)據(jù)段的長度和位置都受到一定限制。

如下列段都必須在長度為64K字的同一個段內(nèi):

.bss段和.data段(存放靜態(tài)和全局變量).stack和.sysstack段(系統(tǒng)堆棧).system段(動態(tài)存儲空間).const段

1.小存儲器模式

4.4.2寄存器模式設置

2023年2月4日TMS320C55xDSP原理及應用89第4章C55x處理器的軟件設計

小存儲器模式下,.text(代碼段)、.switch(狀態(tài)轉(zhuǎn)化段)以及.cinit/.pinit(變量初始化段)的長度和位置都不受限制;

小存儲器模式下,數(shù)據(jù)指針為16位。在采用數(shù)據(jù)指針尋址時,XARx寄存器的高7位指向.bss段所在的數(shù)據(jù)頁,并在程序運行時始終指向該段。

1.小存儲器模式

2023年2月4日TMS320C55xDSP原理及應用90第4章C55x處理器的軟件設計

如果在編譯器中設置-ml選項,則編譯器將按照大存儲器模式編譯程序。

大存儲器模式下可以更加方便地存放數(shù)據(jù),而不必過多地考慮數(shù)據(jù)頁的限制。

在該模式下,數(shù)據(jù)指針為23位,而堆棧和系統(tǒng)堆棧必須放在同一頁中;

代碼段可以跨越頁邊界以外;除代碼段外的其他所有的段只能放在一頁存儲器之中。

2.大存儲器模式

2023年2月4日TMS320C55xDSP原理及應用91第4章C55x處理器的軟件設計

C55x的堆棧主要用來保存處理器信息,向函數(shù)傳遞參數(shù)以及分配局部變量。堆棧在一塊地址按由高到低排列的連續(xù)存儲器之中,編譯器通過堆棧指針(SP)操作堆棧。C55x還存在輔助堆棧,主堆棧主要存放低16位地址,而輔助堆棧則存放C55x返回的高8位地址,編譯器通過輔助堆棧指針(SSP)操作輔助堆棧。堆棧的大小由鏈接器設置,__STACK_SIZE和__SYSSTACK_SIZE兩個全局符號存放的是堆棧的長度值。

系統(tǒng)默認主堆棧和輔助堆棧的長度都是1000個字節(jié)。

3.C/C++系統(tǒng)堆棧

2023年2月4日TMS320C55xDSP原理及應用92第4章C55x處理器的軟件設計

編譯器為動態(tài)內(nèi)存分配提供了如下函數(shù):malloccallocrealloc在C語言中調(diào)用這些函數(shù)會在.sysmem段定義的內(nèi)存池中分配內(nèi)存。__SYSMEM_SIZE中存放的內(nèi)存池的大小(單位為字節(jié)),系統(tǒng)默認大小為2000個字節(jié)。動態(tài)內(nèi)存分配只能通過指針訪問,可分配的內(nèi)存大小受內(nèi)存池中剩余空間限制,動態(tài)內(nèi)存的優(yōu)點是系統(tǒng)只在需要時才分配,不用時就可以釋放所申請的空間,被系統(tǒng)使用。4.動態(tài)內(nèi)存分配

2023年2月4日TMS320C55xDSP原理及應用93注意:如果所申請的空間需要經(jīng)常訪問,建議申請靜態(tài)內(nèi)存,因為如果申請和釋放內(nèi)存的操作很頻繁,將過多占用系統(tǒng)資源,降低程序的執(zhí)行效率。

第4章C55x處理器的軟件設計

4.動態(tài)內(nèi)存分配

接下來給出申請動態(tài)內(nèi)存的例子,由例子可以看到在定義變量指針時不需要定義數(shù)組的大小,而只在申請內(nèi)存時才需給出申請的內(nèi)存長度。

structbig*table;table=(structbig*)malloc(100*sizeof(structbig));

2023年2月4日TMS320C55xDSP原理及應用94第4章C55x處理器的軟件設計

5.結(jié)構(gòu)的對齊當編譯器為結(jié)構(gòu)分配空間時,將為結(jié)構(gòu)的所有成員分配空間。

例如一個結(jié)構(gòu)包含一個長整型的成員(32位),則長整型會被分配到長整型邊界上。為了保證分配,編譯器會在結(jié)構(gòu)的開頭、中間或結(jié)尾進行填充,以保證結(jié)構(gòu)的長度為偶數(shù)。2023年2月4日TMS320

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論