




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
2023年2月4日TMS320C55xDSP原理及應(yīng)用1第4章C55x處理器的軟件設(shè)計(jì)
內(nèi)容提要
C55x系列處理器應(yīng)用靈活、處理能力強(qiáng)大,為開(kāi)發(fā)、使用提供了一個(gè)很好的硬件平臺(tái),要使這個(gè)平臺(tái)更好的發(fā)揮作用,高效、方便的軟件設(shè)計(jì)是不可或缺的。
程序的主體框架和對(duì)實(shí)時(shí)性要求不高的部分采用C/C++語(yǔ)言,而算法實(shí)現(xiàn)采用匯編語(yǔ)言,這樣能夠充分發(fā)揮二者的優(yōu)點(diǎn),解決易讀性和效率之間的矛盾。同時(shí)也改善了軟件的移植性,在軟件移植時(shí)不用改變程序的主體框架,只要為處理器提供相應(yīng)的算法即可。
本章主要介紹了C55x處理器的程序基本結(jié)構(gòu),C語(yǔ)言編程以及優(yōu)化,C語(yǔ)言與匯編語(yǔ)言的混合編程,通用目標(biāo)文件格式,最后對(duì)C55x處理器的數(shù)字信號(hào)處理庫(kù)和圖像、視頻處理庫(kù)進(jìn)行了介紹。2023年2月4日TMS320C55xDSP原理及應(yīng)用2第4章C55x處理器的軟件設(shè)計(jì)4.1C55x處理器程序基本結(jié)構(gòu)4.2C語(yǔ)言程序開(kāi)發(fā)及優(yōu)化4.3C語(yǔ)言與匯編語(yǔ)言的混合編程4.4通用目標(biāo)文件格式4.5C55x處理器的數(shù)字信號(hào)處理庫(kù)和圖像、視頻處理庫(kù)2023年2月4日TMS320C55xDSP原理及應(yīng)用3第4章C55x處理器的軟件設(shè)計(jì)
C55x處理器軟件開(kāi)發(fā)流程C/C++源文件C編譯器匯編源代碼COFF目標(biāo)文件匯編器鏈接器可執(zhí)行COFF文件宏源文件歸檔器宏調(diào)用庫(kù)歸檔器目標(biāo)文件庫(kù)運(yùn)行支持庫(kù)建立運(yùn)行支持庫(kù)2023年2月4日TMS320C55xDSP原理及應(yīng)用4第4章C55x處理器的軟件設(shè)計(jì)
●匯編器:是把匯編源代碼轉(zhuǎn)換成機(jī)器語(yǔ)言。
●匯編器:是把匯編源代碼轉(zhuǎn)換成機(jī)器語(yǔ)言。
●鏈接器:則將多個(gè)目標(biāo)文件結(jié)合成一個(gè)可執(zhí)行文件。
●歸檔器:可以把一組文件歸檔為一個(gè)庫(kù),供用戶(hù)使用。
如果用戶(hù)只用匯編語(yǔ)言編寫(xiě)程序,則將跳過(guò)C編譯器而直接通過(guò)匯編器生成目標(biāo)文件。2023年2月4日TMS320C55xDSP原理及應(yīng)用5第4章C55x處理器的軟件設(shè)計(jì)
4.1C55x處理器程序基本結(jié)構(gòu)
根據(jù)任務(wù)調(diào)度的方式不同,C55x處理器程序大體可以分為兩類(lèi)
:(1)
由程序自己完成任務(wù)調(diào)度
程序運(yùn)行效率高,對(duì)硬件中斷響應(yīng)快,程序運(yùn)行穩(wěn)定,適合于任務(wù)較為單一,實(shí)時(shí)性較強(qiáng)的應(yīng)用;(2)由嵌入式操作系統(tǒng)完成任務(wù)調(diào)度
但如果要利用處理器同時(shí)完成多個(gè)任務(wù),應(yīng)用嵌入式操作系統(tǒng)是十分有必要的,這是因?yàn)榍度胧讲僮飨到y(tǒng)可以將應(yīng)用分解為多個(gè)任務(wù),簡(jiǎn)化了應(yīng)用系統(tǒng)軟件設(shè)計(jì),更為重要的是良好的多任務(wù)設(shè)計(jì)有助于提高系統(tǒng)的穩(wěn)定性和可靠性。2023年2月4日TMS320C55xDSP原理及應(yīng)用6第4章C55x處理器的軟件設(shè)計(jì)
4.1.1自我調(diào)度程序的基本結(jié)構(gòu)雖然嵌入式操作系統(tǒng)已經(jīng)發(fā)展得較為成熟,但通過(guò)程序自身完成任務(wù)調(diào)度仍然保持著旺盛的生命力,這是因?yàn)檫@種方式適合于DSP這種需要對(duì)大量實(shí)時(shí)數(shù)據(jù)完成順序處理的應(yīng)用。下面給出自我調(diào)度程序的基本結(jié)構(gòu)。2023年2月4日TMS320C55xDSP原理及應(yīng)用7
中斷服務(wù)程序1;//定時(shí)器到時(shí) 中斷服務(wù)程序2;//讀取A/D轉(zhuǎn)換 中斷服務(wù)程序3;//讀取通訊數(shù)據(jù) ……
中斷服務(wù)程序m;//讀取按鍵碼 Main() { DSP_INT(){……}; //DSP初始化
For(;;) //主循環(huán)
{ if(條件1) {處理模塊1;} //條件滿足運(yùn)行處理模塊1 …… if(條件n) {處理模塊n;} //條件滿足運(yùn)行處理模塊n } }
自我調(diào)度程序通常由中斷程序部分、初始化部分和主循環(huán)部分組成
:
中斷服務(wù)程序一般僅讀取數(shù)據(jù)和改變條件,由主循環(huán)中的程序處理,這種處理必須要輪流進(jìn)行,因此此程序僅適于實(shí)時(shí)性要求不高的場(chǎng)合。2023年2月4日TMS320C55xDSP原理及應(yīng)用8第4章C55x處理器的軟件設(shè)計(jì)
初始化部分通常完成DSP軟、硬件的初始化設(shè)置,啟動(dòng)系統(tǒng)硬件,使能DSP中斷等工作。
主循環(huán)部分是程序的主體,將由它完成數(shù)據(jù)輸入、處理和輸出等工作。主循環(huán)由條件判斷和處理模塊組成,當(dāng)滿足條件時(shí)運(yùn)行處理模塊,不滿足條件則自動(dòng)跳到下一個(gè)判斷條件。中斷服務(wù)程序通過(guò)設(shè)置判斷標(biāo)志來(lái)影響主循環(huán)部分的運(yùn)行。但對(duì)于要求立即處理的程序,要放在中斷服務(wù)程序中。4.1.1自我調(diào)度程序的基本結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應(yīng)用9第4章C55x處理器的軟件設(shè)計(jì)
為了滿足實(shí)時(shí)運(yùn)行的要求,自我調(diào)度程序的主循環(huán)部分必須將處理時(shí)延限制在最大可接受時(shí)延內(nèi),具體來(lái)說(shuō)就是運(yùn)行主循環(huán)的所有分支的時(shí)間總和必須小于最大可接受時(shí)延,如果不能滿足這一條件,則在最壞情況下,會(huì)造成處理數(shù)據(jù)的不連續(xù),而無(wú)法實(shí)現(xiàn)數(shù)據(jù)的實(shí)時(shí)處理。
當(dāng)所編寫(xiě)的程序沒(méi)有滿足上述條件時(shí),則需要對(duì)處理流程進(jìn)行修改,或修改處理算法以滿足條件。
4.1.1
自我調(diào)度程序的基本結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應(yīng)用10第4章C55x處理器的軟件設(shè)計(jì)
處理模塊很多場(chǎng)合是要多步驟完成的(比如控制一個(gè)機(jī)械動(dòng)作、按鍵過(guò)程、通訊過(guò)程),一般要用switch結(jié)構(gòu):4.1.1
自我調(diào)度程序的基本結(jié)構(gòu)
中斷服務(wù)程序j:
獲取數(shù)據(jù)和狀態(tài); switch(step){//即時(shí)處理模塊 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原理及應(yīng)用11第4章C55x處理器的軟件設(shè)計(jì)
優(yōu)點(diǎn):這種結(jié)構(gòu)可以適用于大多數(shù)場(chǎng)合,容易掌握,不必使用操作系統(tǒng),實(shí)時(shí)性也好。缺點(diǎn):必須用switch之類(lèi)的程序結(jié)構(gòu)找到要執(zhí)行的程序段,編程繁瑣。在有多個(gè)實(shí)時(shí)多步處理任務(wù)且有時(shí)任務(wù)之間還有協(xié)調(diào)和同步的要求時(shí),編程難度大。4.1.1
自我調(diào)度程序的基本結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應(yīng)用12第4章C55x處理器的軟件設(shè)計(jì)
任務(wù)程序j: //處理模塊:
處理程序0;休息t0;//如果是可剝奪任務(wù),也可不要此休息(也叫掛起)語(yǔ)句。
m1:處理程序1;等待信號(hào)量s1; 處理程序2;休息t2;
if(條件1)gotom1;
elseif(條件2)gotom6; 處理程序3;等待信號(hào)量s2;……m6:處理程序6;等待信號(hào)量s3;……處理程序n;休息t8;返回任務(wù)起點(diǎn);2023年2月4日TMS320C55xDSP原理及應(yīng)用13第4章C55x處理器的軟件設(shè)計(jì)
在數(shù)字信號(hào)處理器中運(yùn)行的操作系統(tǒng)必須滿足系統(tǒng)實(shí)時(shí)性要求,而操作系統(tǒng)的實(shí)時(shí)方式可以分成兩種——硬實(shí)時(shí)方式和軟實(shí)時(shí)方式。
軟實(shí)時(shí)系統(tǒng)由軟件來(lái)進(jìn)行任務(wù)的切換,而硬實(shí)時(shí)系統(tǒng)則按照固定時(shí)鐘節(jié)拍切換任務(wù)。軟實(shí)時(shí)系統(tǒng)使各個(gè)任務(wù)盡快運(yùn)行,而不要求限定某個(gè)任務(wù)在多長(zhǎng)時(shí)間內(nèi)完成;硬實(shí)時(shí)系統(tǒng)中各任務(wù)不僅要執(zhí)行無(wú)誤,而且要準(zhǔn)時(shí)。
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
嵌入式實(shí)時(shí)操作系統(tǒng)的作用就是合理調(diào)度、分配任務(wù)的運(yùn)行,使各個(gè)任務(wù)正確、及時(shí)地執(zhí)行。
2023年2月4日TMS320C55xDSP原理及應(yīng)用14第4章C55x處理器的軟件設(shè)計(jì)
嵌入式操作系統(tǒng)的核心是操作系統(tǒng)內(nèi)核,在多任務(wù)系統(tǒng)中,內(nèi)核負(fù)責(zé)管理各個(gè)任務(wù),為每個(gè)任務(wù)分配CPU時(shí)間,負(fù)責(zé)任務(wù)間的通信和任務(wù)切換。根據(jù)其重要程度的不同系統(tǒng)中每個(gè)任務(wù)被賦予一定的優(yōu)先級(jí),內(nèi)核將根據(jù)任務(wù)的優(yōu)先級(jí)進(jìn)行任務(wù)調(diào)度?;趦?yōu)先級(jí)的內(nèi)核可以分成不可剝奪型和可剝奪型兩種類(lèi)型。
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2023年2月4日TMS320C55xDSP原理及應(yīng)用15第4章C55x處理器的軟件設(shè)計(jì)
1.
不可剝奪型內(nèi)核
不可剝奪型內(nèi)核要求每個(gè)任務(wù)主動(dòng)放棄CPU使用權(quán),這種任務(wù)的調(diào)度方法也可以叫做合作型多任務(wù),每個(gè)任務(wù)相互合作,共享一個(gè)CPU。
不可剝奪型內(nèi)核中的異步事件由中斷服務(wù)來(lái)處理,中斷服務(wù)可以使一個(gè)高優(yōu)先級(jí)的任務(wù)由掛起態(tài)變?yōu)榫途w態(tài);但在中斷服務(wù)之后,CPU的使用權(quán)還給原來(lái)被中斷的任務(wù),直到該任務(wù)主動(dòng)放棄CPU的使用權(quán),一個(gè)高優(yōu)先級(jí)的任務(wù)才能進(jìn)入運(yùn)行態(tài)。4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2023年2月4日TMS320C55xDSP原理及應(yīng)用16第4章C55x處理器的軟件設(shè)計(jì)
這種內(nèi)核的優(yōu)點(diǎn)是響應(yīng)中斷快,采用不可剝奪型內(nèi)核允許任務(wù)使用不可重入函數(shù),每個(gè)任務(wù)調(diào)用不可重入型函數(shù)不必?fù)?dān)心其他任務(wù)可能使用該函數(shù)而造成數(shù)據(jù)破壞。使用不可剝奪型內(nèi)核時(shí),任務(wù)的響應(yīng)時(shí)間取決于最長(zhǎng)任務(wù)的執(zhí)行時(shí)間。使用該內(nèi)核很少需要使用信號(hào)量保護(hù)共享數(shù)據(jù),這是因?yàn)檎谶\(yùn)行的任務(wù)不必?fù)?dān)心其他任務(wù)搶占CPU;但如果任務(wù)使用共享設(shè)備時(shí),還應(yīng)使用互斥型信號(hào)量。
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
1.
不可剝奪型內(nèi)核
2023年2月4日TMS320C55xDSP原理及應(yīng)用17第4章C55x處理器的軟件設(shè)計(jì)
不可剝奪型內(nèi)核的缺點(diǎn)是響應(yīng)時(shí)間具有不確定性,無(wú)法確定最高優(yōu)先級(jí)的任務(wù)何時(shí)能夠獲得CPU的使用權(quán)。
2.可剝奪型內(nèi)核
可剝奪型內(nèi)核運(yùn)行時(shí),一旦具有最高優(yōu)先級(jí)的任務(wù)就緒,就總能得到CPU的使用權(quán)。當(dāng)有一個(gè)具有更高優(yōu)先權(quán)的任務(wù)進(jìn)入就緒態(tài)時(shí),當(dāng)前運(yùn)行的任務(wù)將被掛起,更高級(jí)的任務(wù)立刻得到CPU的使用權(quán)。1.
不可剝奪型內(nèi)核
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2023年2月4日TMS320C55xDSP原理及應(yīng)用18第4章C55x處理器的軟件設(shè)計(jì)
如果是中斷服務(wù)子程序使一個(gè)高優(yōu)先級(jí)的任務(wù)進(jìn)入就緒狀態(tài),中斷完成后,被中斷的任務(wù)被掛起,開(kāi)始運(yùn)行更高級(jí)的任務(wù)。使用可剝奪型內(nèi)核可以隨時(shí)執(zhí)行最高級(jí)任務(wù),這使得任務(wù)的響應(yīng)時(shí)間得以最優(yōu)化。使用可剝奪內(nèi)核要求應(yīng)用程序不應(yīng)直接使用不可重入函數(shù),如果要使用則應(yīng)滿足互斥條件。
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2.可剝奪型內(nèi)核
2023年2月4日TMS320C55xDSP原理及應(yīng)用19第4章C55x處理器的軟件設(shè)計(jì)
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
內(nèi)核的主要工作是完成任務(wù)的調(diào)度,任務(wù)也可稱(chēng)作線程,是一個(gè)簡(jiǎn)單的程序,該程序認(rèn)為CPU完全屬于自己。使用操作系統(tǒng)要求程序員把所要完成的工作分解為多個(gè)任務(wù),每個(gè)任務(wù)都是應(yīng)用的一部分。任務(wù)都被賦予一定的優(yōu)先級(jí),并擁有自己的一套CPU寄存器和獨(dú)立的堆??臻g,每個(gè)任務(wù)堆棧空間大小也可不同,在創(chuàng)建任務(wù)時(shí)指定。2023年2月4日TMS320C55xDSP原理及應(yīng)用20第4章C55x處理器的軟件設(shè)計(jì)
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
任務(wù)是一個(gè)無(wú)限循環(huán),它必須處于下列5個(gè)狀態(tài)之一:
休眠狀態(tài)是任務(wù)駐留在內(nèi)存之中,但并沒(méi)有被系統(tǒng)內(nèi)核所調(diào)用;
就緒狀態(tài)是任務(wù)已經(jīng)準(zhǔn)備好,但由于該任務(wù)的優(yōu)先級(jí)比正在運(yùn)行的任務(wù)的優(yōu)先級(jí)低,還暫時(shí)不能運(yùn)行;
運(yùn)行狀態(tài)是任務(wù)擁有CPU的使用權(quán),正在運(yùn)行;掛起狀態(tài)是任務(wù)正在等待某一個(gè)事件的發(fā)生以結(jié)束目前的等待(如等待外設(shè)的I/O操作、等待共享資源、等待定時(shí)或超時(shí)信息等事件);發(fā)生中斷時(shí),CPU進(jìn)入中斷服務(wù)程序,而暫時(shí)不能運(yùn)行當(dāng)前的任務(wù),任務(wù)就進(jìn)入了被中斷態(tài)。
2023年2月4日TMS320C55xDSP原理及應(yīng)用21第4章C55x處理器的軟件設(shè)計(jì)4.1.2
應(yīng)用嵌入式操作系統(tǒng)
操作系統(tǒng)需要在多個(gè)任務(wù)之間轉(zhuǎn)換和調(diào)度,這是因?yàn)镃PU在某一時(shí)刻只能為一個(gè)任務(wù)提供服務(wù),CPU必須為一系列任務(wù)輪流服務(wù)。多任務(wù)運(yùn)行可以使CPU的利用率達(dá)到最高,并使應(yīng)用程序模塊化,使用多任務(wù)可以使程序更容易設(shè)計(jì)和維護(hù)。
當(dāng)任務(wù)從當(dāng)前任務(wù)切換到另一個(gè)任務(wù)時(shí),必須保存正在執(zhí)行的任務(wù)的當(dāng)前狀態(tài)。所謂“任務(wù)的當(dāng)前狀態(tài)”即CPU寄存器中的所有內(nèi)容;這些內(nèi)容被保存在任務(wù)自己的堆棧中,以備任務(wù)下次執(zhí)行時(shí)恢復(fù)當(dāng)前狀態(tài)。在保存完當(dāng)前任務(wù)后,要把下一個(gè)任務(wù)的當(dāng)前狀態(tài)裝入CPU寄存器,并開(kāi)始下一個(gè)任務(wù)的運(yùn)行,這一過(guò)程叫做“任務(wù)切換”。2023年2月4日TMS320C55xDSP原理及應(yīng)用22第4章C55x處理器的軟件設(shè)計(jì)
4.1.2
應(yīng)用嵌入式操作系統(tǒng)每個(gè)任務(wù)都有其優(yōu)先級(jí),任務(wù)越重要,被賦予的優(yōu)先級(jí)應(yīng)越高。如果程序執(zhí)行過(guò)程中任務(wù)的優(yōu)先級(jí)不變,則稱(chēng)為靜態(tài)優(yōu)先級(jí);反之則稱(chēng)為動(dòng)態(tài)優(yōu)先級(jí)。
所謂“任務(wù)管理”就是在內(nèi)核的控制下任務(wù)在五種狀態(tài)之間切換。下面是一個(gè)常用實(shí)時(shí)操作系統(tǒng)
μC/OS-II的任務(wù)狀態(tài)轉(zhuǎn)換圖。2023年2月4日TMS320C55xDSP原理及應(yīng)用23第4章C55x處理器的軟件設(shè)計(jì)
OSIntExit()OSTaskDel()OSTaskDel()掛起狀態(tài)休眠狀態(tài)就緒狀態(tài)運(yùn)行狀態(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原理及應(yīng)用24第4章C55x處理器的軟件設(shè)計(jì)
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
不同任務(wù)之間有可能會(huì)使用共同的資源,當(dāng)它們同時(shí)使用共享資源時(shí)有可能發(fā)生錯(cuò)誤,嵌入式操作系統(tǒng)提供了信號(hào)量這一約定機(jī)制,通過(guò)該機(jī)制可以控制共享資源的使用權(quán),或標(biāo)志某一事件的發(fā)生,也常用于兩個(gè)任務(wù)之間的同步,或任務(wù)和中斷之間的同步。等待某信號(hào)量:OSSemPend(指向該信號(hào)量的指針);調(diào)用此函數(shù)的任務(wù)會(huì)使自己掛起,直到得到該信號(hào)量(另一任務(wù)或中斷發(fā)送該信號(hào)量)或掛起超時(shí)。發(fā)送某信號(hào)量:OSSemPost(指向該信號(hào)量的指針);2023年2月4日TMS320C55xDSP原理及應(yīng)用25第4章C55x處理器的軟件設(shè)計(jì)
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
信號(hào)量可以看作一把鑰匙。當(dāng)任務(wù)要運(yùn)行時(shí)首先要取得這把鑰匙。如果信號(hào)量已經(jīng)被其他任務(wù)占用,那么該任務(wù)只好掛起并等待信號(hào)量被當(dāng)前使用者釋放。
2023年2月4日TMS320C55xDSP原理及應(yīng)用26第4章C55x處理器的軟件設(shè)計(jì)
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
任務(wù)要使用信號(hào)量,首先要對(duì)信號(hào)量進(jìn)行初始化。
如果任務(wù)要得到信號(hào)量,首先要執(zhí)行“等待”操作。
如果該信號(hào)量有效(信號(hào)量的值大于0),則該信號(hào)量值減1,任務(wù)得以繼續(xù)執(zhí)行。
如果信號(hào)量的值為0,等待信號(hào)量的任務(wù)就被列入等待信號(hào)量任務(wù)表。
2023年2月4日TMS320C55xDSP原理及應(yīng)用27第4章C55x處理器的軟件設(shè)計(jì)
如果等待時(shí)間超過(guò)某一設(shè)定值,該信號(hào)量還無(wú)效,那么等待信號(hào)量的任務(wù)自動(dòng)進(jìn)入就緒狀態(tài)并準(zhǔn)備運(yùn)行,并向系統(tǒng)報(bào)一個(gè)“超時(shí)錯(cuò)誤”信息。4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2023年2月4日TMS320C55xDSP原理及應(yīng)用28第4章C55x處理器的軟件設(shè)計(jì)
實(shí)際上,等待該信號(hào)量的任務(wù)可能有多個(gè)。在嵌入式操作系統(tǒng)中通常依照優(yōu)先級(jí)來(lái)決定由哪個(gè)任務(wù)取得信號(hào)量。
任務(wù)還可以釋放信號(hào)量。
如果有任務(wù)等待該信號(hào)量,那么就會(huì)有一個(gè)任務(wù)進(jìn)入就緒狀態(tài),信號(hào)量的值不增加。
如果這時(shí)沒(méi)有任務(wù)等待信號(hào)量,則信號(hào)量的值加1。4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2023年2月4日TMS320C55xDSP原理及應(yīng)用29第4章C55x處理器的軟件設(shè)計(jì)4.1.2
應(yīng)用嵌入式操作系統(tǒng)
兩個(gè)任務(wù)之間可以利用信號(hào)量來(lái)取得同步,這種同步可以分成兩類(lèi)——單向同步和雙向同步。所謂“單向同步”是指任務(wù)用一個(gè)信號(hào)量觸發(fā)另一個(gè)任務(wù)。單向同步2023年2月4日TMS320C55xDSP原理及應(yīng)用30第4章C55x處理器的軟件設(shè)計(jì)
當(dāng)兩個(gè)任務(wù)需要相互同步對(duì)方,這時(shí)就要用到雙向同步。
兩個(gè)任務(wù)的雙向同步4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2023年2月4日TMS320C55xDSP原理及應(yīng)用31第4章C55x處理器的軟件設(shè)計(jì)4.1.2
應(yīng)用嵌入式操作系統(tǒng)
任務(wù)之間的通信可以通過(guò)兩個(gè)途徑:全局變量或消息。
使用全局變量必須保證任務(wù)或中斷服務(wù)子程序在使用該變量時(shí)沒(méi)有其他的任務(wù)或中斷服務(wù)子程序訪問(wèn)該變量。另外,如果任務(wù)沒(méi)有其他機(jī)制通知其變量已經(jīng)被修改了,任務(wù)就只能周期性地查詢(xún)?cè)撟兞康闹?。要避免這種情況,可以考慮使用消息郵箱或消息隊(duì)列。2023年2月4日TMS320C55xDSP原理及應(yīng)用32第4章C55x處理器的軟件設(shè)計(jì)
4.1.2
應(yīng)用嵌入式操作系統(tǒng)
消息郵箱是一個(gè)任務(wù)或一個(gè)中斷程序通過(guò)一個(gè)指針型變量把一個(gè)消息(指針)放到郵箱之中,而一個(gè)或多個(gè)任務(wù)通過(guò)內(nèi)核服務(wù)可以接收到這個(gè)消息。
內(nèi)核可以提供下列郵箱服務(wù):
初始化郵箱內(nèi)的消息;
將消息放入郵箱;
等待消息進(jìn)入郵箱;
從郵箱中取得消息。2023年2月4日TMS320C55xDSP原理及應(yīng)用33第4章C55x處理器的軟件設(shè)計(jì)
消息隊(duì)列則是任務(wù)或中斷程序把一個(gè)消息指針?lè)诺较㈥?duì)列之中,而一個(gè)或多個(gè)任務(wù)通過(guò)內(nèi)核服務(wù)從消息隊(duì)列中接收消息。
內(nèi)核提供消息隊(duì)列服務(wù)如下:
消息隊(duì)列初始化,即將消息隊(duì)列清空;
將一個(gè)消息放到消息隊(duì)列之中;
等待消息到來(lái);
得到消息。4.1.2
應(yīng)用嵌入式操作系統(tǒng)
2023年2月4日TMS320C55xDSP原理及應(yīng)用34第4章C55x處理器的軟件設(shè)計(jì)
TMS320C55x處理器為C語(yǔ)言開(kāi)發(fā)提供了一系列工具,包括:優(yōu)化C/C++編譯器、鏈接器和歸檔器。
并支持混合編程。
C語(yǔ)言的優(yōu)點(diǎn)在于程序可讀性強(qiáng)。4.2C語(yǔ)言程序開(kāi)發(fā)及優(yōu)化2023年2月4日TMS320C55xDSP原理及應(yīng)用35第4章C55x處理器的軟件設(shè)計(jì)
4.2.1C語(yǔ)言中的數(shù)據(jù)類(lèi)型
C55x支持下列數(shù)據(jù)類(lèi)型包括字符、定點(diǎn)數(shù)、浮點(diǎn)數(shù)、指針等。4.2C語(yǔ)言程序開(kāi)發(fā)及優(yōu)化類(lèi)型長(zhǎng)度內(nèi)容最小值最大值signedchar(有符號(hào)字符)16位ASCII碼-3276832767char,unsignedchar(無(wú)符號(hào)字符)16位ASCII碼065535short,signedshort(短整型)16位二進(jìn)制補(bǔ)碼-3276832767unsignedshort(無(wú)符號(hào)短整型)16位二進(jìn)制數(shù)0655352023年2月4日TMS320C55xDSP原理及應(yīng)用36第4章C55x處理器的軟件設(shè)計(jì)
char,unsignedcharpointers(數(shù)據(jù)指針)小存儲(chǔ)器模式16位0xFFFF類(lèi)型長(zhǎng)度內(nèi)容最小值最大值int,signedint(整型)16位二進(jìn)制補(bǔ)碼3276832767unsignedint(無(wú)符號(hào)整型)16位二進(jìn)制數(shù)065535long,signedlong(長(zhǎng)整型)32位二進(jìn)制補(bǔ)碼21474836482147483647unsignedlong(無(wú)符號(hào)長(zhǎng)整型)32位二進(jìn)制數(shù)04249967295longlong(40位長(zhǎng)整型)40位二進(jìn)制補(bǔ)碼549755813888549755813887unsignedlonglong(40位無(wú)符號(hào)長(zhǎng)整型)40位二進(jìn)制數(shù)01099511627775emum(枚舉型)16位二進(jìn)制補(bǔ)碼3276832767float(浮點(diǎn)型)32位32位浮點(diǎn)數(shù)1.175494e383.40282346e+382023年2月4日TMS320C55xDSP原理及應(yīng)用37第4章C55x處理器的軟件設(shè)計(jì)類(lèi)型長(zhǎng)度內(nèi)容最小值最大值double(雙精度浮點(diǎn)數(shù))32位32位浮點(diǎn)數(shù)1.175494e383.40282346e+38longdouble(長(zhǎng)雙精度浮點(diǎn)數(shù))32位32位浮點(diǎn)數(shù)1.175494e383.40282346e+38大存儲(chǔ)器模式23位二進(jìn)制數(shù)00x7FFFFFpointers(程序指針)24位二進(jìn)制數(shù)00xFFFFFF
指針?lè)譃槌绦蛑羔樅蛿?shù)據(jù)指針兩種,其區(qū)別在于程序指針尋址是按字節(jié)尋址,而數(shù)據(jù)指針以字為單位進(jìn)行尋址。2023年2月4日TMS320C55xDSP原理及應(yīng)用38第4章C55x處理器的軟件設(shè)計(jì)
C55x處理器包含數(shù)據(jù)空間和I/O空間,為了在C/C++中對(duì)I/O空間進(jìn)行尋址,編譯器給出了關(guān)鍵字ioport,以支持I/O尋址模式。
ioport關(guān)鍵字可以用在數(shù)組、結(jié)構(gòu)、聯(lián)合以及枚舉類(lèi)型當(dāng)中。
當(dāng)用在數(shù)組中時(shí),ioport可以作為數(shù)組中的元素;在結(jié)構(gòu)中使用ioport,只能是指向ioport數(shù)據(jù)的指針而不能直接作為結(jié)構(gòu)的成員。
4.2C語(yǔ)言程序開(kāi)發(fā)及優(yōu)化4.2.2對(duì)I/O空間進(jìn)行尋址
2023年2月4日TMS320C55xDSP原理及應(yīng)用39第4章C55x處理器的軟件設(shè)計(jì)
ioport類(lèi)型只能用來(lái)聲明全局或靜態(tài)變量,如果在本地變量中使用ioport類(lèi)型,則變量必須用指針聲明。接下來(lái)給出指針聲明ioport類(lèi)型的例子:voidfoo(void){ioportinti;/*無(wú)效的聲明*/ioportint*j;/*有效聲明*/}應(yīng)當(dāng)注意聲明ioport類(lèi)型的指針只有16位,這是因?yàn)镮/O空間是16位尋址,而不受大/小存儲(chǔ)器模式的限制。4.2.2
對(duì)I/O空間進(jìn)行尋址
2023年2月4日TMS320C55xDSP原理及應(yīng)用40第4章C55x處理器的軟件設(shè)計(jì)
在printf()中不能直接引用ioport指針,如果要引用,則必須進(jìn)行強(qiáng)制類(lèi)型轉(zhuǎn)換“void*”,具體例子如下:ioportint*p;printf(“%p\n”,(void*)p);
4.2.2
對(duì)I/O空間進(jìn)行尋址
2023年2月4日TMS320C55xDSP原理及應(yīng)用41第4章C55x處理器的軟件設(shè)計(jì)
這段代碼的編譯結(jié)果如下:
_foo:MOV#_i,port(#_ioport_pointer) ;存儲(chǔ)i在I/O空間的地址MOVport(#_ioport_pointer),AR3;載入i的地址MOV*AR3,AR1 ;將i的內(nèi)容存放到AR1中MOVAR1,*abs16(#_j) ;將i的內(nèi)容保存到j(luò)return給出在本地變量中使用ioport類(lèi)型的例子:
int*ioportioport_pointer;/*ioport指針*/inti;intj;voidfoo(void){ioport_pointer=&i;j=*ioport_pointer;}2023年2月4日TMS320C55xDSP原理及應(yīng)用42第4章C55x處理器的軟件設(shè)計(jì)
下來(lái)給出一個(gè)指向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) ;存儲(chǔ)_i的地址MOV*abs16(#_ptr_to_ioport),AR3AADD#–1,SPMOV#10,port(#_i) ;向_i中存入10MOV*AR3,AR1MOVAR1,*SP(#0)AADD#1,SPreturn2023年2月4日TMS320C55xDSP原理及應(yīng)用43第4章C55x處理器的軟件設(shè)計(jì)上面代碼編譯結(jié)果如下:
_foo:MOV#10,port(#_i) ;將10存在_i中MOV#_i,port(#_iop_ptr_to_ioport);存儲(chǔ)_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原理及應(yīng)用44第4章C55x處理器的軟件設(shè)計(jì)
4.2.3interrupt關(guān)鍵字中斷操作需要使用特定的寄存器保存規(guī)則,并具有特殊的返回順序。
C55x編譯器使用了關(guān)鍵字“interrupt”定義中斷函數(shù)。
當(dāng)C/C++代碼被中斷時(shí),中斷程序必須保存所有與程序有關(guān)的寄存器。
當(dāng)使用“interrupt”關(guān)鍵字定義函數(shù)時(shí),中斷函數(shù)必須返回空并且沒(méi)有參數(shù)傳遞。
2023年2月4日TMS320C55xDSP原理及應(yīng)用45第4章C55x處理器的軟件設(shè)計(jì)
4.2.3interrupt關(guān)鍵字
中斷函數(shù)可以定義本地變量并且使用堆棧。接下來(lái)給出定義中斷函數(shù)的例子:
interruptvoidint_handler(){unsignedintflags;...}
c_int00是C/C++程序的入口點(diǎn),這個(gè)函數(shù)名被系統(tǒng)復(fù)位中斷保留,該中斷服務(wù)程序用來(lái)初始化系統(tǒng)并調(diào)用main函數(shù)。2023年2月4日TMS320C55xDSP原理及應(yīng)用46第4章C55x處理器的軟件設(shè)計(jì)
onchip關(guān)鍵字的作用是告訴編譯器由該關(guān)鍵字定義的指針?biāo)赶虻臄?shù)據(jù)可以作為一個(gè)雙乘法指令中的操作數(shù)。
如果onchip關(guān)鍵字向函數(shù)傳遞數(shù)據(jù),或者最終所引用的數(shù)據(jù)是用onchip定義的,則該數(shù)據(jù)必須在片上內(nèi)存。如果該數(shù)據(jù)在片外,則當(dāng)通過(guò)BB數(shù)據(jù)總線訪問(wèn)該數(shù)據(jù)時(shí)將產(chǎn)生一個(gè)總線錯(cuò)誤。下面給出用onchip定義數(shù)組和指針的例子。
onchipintx[100]; /*arraydeclaration*/onchipint*p; /*pointerdeclaration*/
4.2.4onchip關(guān)鍵字2023年2月4日TMS320C55xDSP原理及應(yīng)用47第4章C55x處理器的軟件設(shè)計(jì)
4.2.5C語(yǔ)言的優(yōu)化(略)如果將未經(jīng)優(yōu)化的C語(yǔ)言程序直接運(yùn)行會(huì)發(fā)現(xiàn)運(yùn)行效率較低,并且產(chǎn)生的代碼較大,而通過(guò)優(yōu)化可以較好地解決這些問(wèn)題。優(yōu)化的作用是對(duì)循環(huán)進(jìn)行化簡(jiǎn),重新組織表達(dá)式和聲明,將變量直接分配到寄存器中。
通過(guò)優(yōu)化可以提高程序運(yùn)行效率,縮小程序編碼數(shù)量。2023年2月4日TMS320C55xDSP原理及應(yīng)用48第4章C55x處理器的軟件設(shè)計(jì)
4.2.5C語(yǔ)言的優(yōu)化C/C++編譯器提供了不同的優(yōu)化選擇,通過(guò)修改cl55命令行中的-on選擇就可以方便地選擇不同的優(yōu)化等級(jí),n代表優(yōu)化等級(jí),包括0、1、2和3。下面給出不同優(yōu)化等級(jí)的功能。
(1)
O0
簡(jiǎn)化控制流圖
把變量分配到寄存器
分析循環(huán)的各種情況,只保留一個(gè)退出循環(huán)的分支刪除未用的代碼簡(jiǎn)化表達(dá)式和聲明把用inline聲明的函數(shù)變?yōu)檎{(diào)用關(guān)系2023年2月4日TMS320C55xDSP原理及應(yīng)用49第4章C55x處理器的軟件設(shè)計(jì)
4.2.5C語(yǔ)言的優(yōu)化
(2)
O1
除了
O0的各種優(yōu)化功能外,還有如下功能:
在分配變量時(shí),將數(shù)值直接賦給變量而不是給出變量的索引值
去掉沒(méi)有用的分配變量和表達(dá)式
去掉本地通用表達(dá)式2023年2月4日TMS320C55xDSP原理及應(yīng)用50第4章C55x處理器的軟件設(shè)計(jì)
(3)
O2
除了
O1的各種優(yōu)化功能外,還有如下功能:
完成循環(huán)優(yōu)化
去掉全局通用的子表達(dá)式去掉全局沒(méi)有用的分配變量和表達(dá)式
完成循環(huán)的化解
當(dāng)只用-o選項(xiàng)時(shí)優(yōu)化器自動(dòng)進(jìn)行-O2優(yōu)化4.2.5C語(yǔ)言的優(yōu)化2023年2月4日TMS320C55xDSP原理及應(yīng)用51第4章C55x處理器的軟件設(shè)計(jì)
(4)O3除了
O2的各種優(yōu)化功能外,還有如下功能:
去掉未調(diào)用的函數(shù)
簡(jiǎn)化返回值未使用的函數(shù)將小函數(shù)進(jìn)行內(nèi)嵌調(diào)用
對(duì)被調(diào)用的函數(shù)聲明進(jìn)行重新排序,以便被優(yōu)化的調(diào)用方能夠找到該函數(shù)完成文件級(jí)優(yōu)化4.2.5C語(yǔ)言的優(yōu)化2023年2月4日TMS320C55xDSP原理及應(yīng)用52第4章C55x處理器的軟件設(shè)計(jì)4.2.5C語(yǔ)言的優(yōu)化優(yōu)化器分析數(shù)據(jù)流時(shí)將盡量減少對(duì)內(nèi)存的訪問(wèn),如果這個(gè)數(shù)據(jù)必須從內(nèi)存中得到,則該數(shù)據(jù)必須用volatile關(guān)鍵字定義,這樣可以使編譯器不對(duì)該變量進(jìn)行優(yōu)化。例如聲明一個(gè)指針unsignedint*ctrl;
當(dāng)在循環(huán)中有如下語(yǔ)句時(shí)
while(*ctrl!=0xFF);
優(yōu)化器將只在進(jìn)入循環(huán)的初始化中進(jìn)行一次內(nèi)存讀,而在循環(huán)當(dāng)中不在更新該變量的內(nèi)容,如果該變量被中斷或其他程序改變,由于循環(huán)中的ctrl的值沒(méi)有更新,將會(huì)使程序不能按照正確的方式執(zhí)行,這里應(yīng)當(dāng)用如下方法聲明ctrl:volatileunsignedint*ctrl;特別當(dāng)該變量在中斷函數(shù)中被賦值,而該變量在主函數(shù)的循環(huán)中被用到時(shí),必須用volatile聲明該變量。
2023年2月4日TMS320C55xDSP原理及應(yīng)用53第4章C55x處理器的軟件設(shè)計(jì)
4.3.1
在C語(yǔ)言中直接嵌套匯編語(yǔ)句C55x的C/C++編譯器允許使用者在C語(yǔ)言代碼中直接嵌套匯編語(yǔ)句,嵌套匯編語(yǔ)句的語(yǔ)法十分簡(jiǎn)單,只需在嵌入的匯編語(yǔ)句前面加上asm標(biāo)示符,左右加上一個(gè)雙引號(hào)和一個(gè)小括號(hào)即可。
asm("匯編語(yǔ)句")
4.3C語(yǔ)言與匯編語(yǔ)言的混合編程2023年2月4日TMS320C55xDSP原理及應(yīng)用54第4章C55x處理器的軟件設(shè)計(jì)
4.3.1
在C語(yǔ)言中直接嵌套匯編語(yǔ)句采用直接嵌套匯編語(yǔ)句的方法比較適合完成對(duì)硬件進(jìn)行操作、設(shè)置狀態(tài)寄存器、開(kāi)關(guān)中斷等工作,這樣做往往要比用C語(yǔ)言實(shí)現(xiàn)效率更高。
用C語(yǔ)言打開(kāi)中斷的代碼:
IRQ_globalEnable(); //全局開(kāi)中斷2023年2月4日TMS320C55xDSP原理及應(yīng)用55第4章C55x處理器的軟件設(shè)計(jì)
下面給出該代碼編譯后的結(jié)果:
0115A6IRQ_globalEnable:0115A63C3BMOV#3,AR30115A8DF6105MOVuns(*AR3),AC00115AB76080040BFXTR#2048,AC0,T00115AF20NOP0115B046B2BCLRST1_INTM0115B24804RET
可以看到采用C語(yǔ)言打開(kāi)全局中斷共用了6條語(yǔ)句,考慮到調(diào)用子函數(shù)的開(kāi)銷(xiāo),完成該功能一共要花費(fèi)10個(gè)左右的指令周期,而采用嵌套匯編語(yǔ)句的方法則只用一條指令即可:
asm("BCLRST1_INTM")
2023年2月4日TMS320C55xDSP原理及應(yīng)用56第4章C55x處理器的軟件設(shè)計(jì)
4.3.1在C語(yǔ)言中直接嵌套匯編語(yǔ)句采用直接嵌套的方法要十分小心,這是因?yàn)镃語(yǔ)言編譯器并不檢查和分析所嵌入的匯編語(yǔ)句,而嵌入的語(yǔ)句很可能改變C語(yǔ)言的運(yùn)行環(huán)境。
例如嵌入跳轉(zhuǎn)指令或者標(biāo)號(hào)將會(huì)引起不可預(yù)測(cè)的后果。如果采用嵌套匯編語(yǔ)句,在編譯程序時(shí)不應(yīng)采用優(yōu)化功能,采用優(yōu)化功能可能會(huì)調(diào)整匯編語(yǔ)句周?chē)a的排列順序,有可能改變程序的運(yùn)行結(jié)果。
2023年2月4日TMS320C55xDSP原理及應(yīng)用57第4章C55x處理器的軟件設(shè)計(jì)
如果采用該方法實(shí)現(xiàn)較復(fù)雜的功能,會(huì)造成程序的可讀性較差,并影響程序的可移植性,因此在采用匯編語(yǔ)言實(shí)現(xiàn)較復(fù)雜的功能時(shí),更可行的方法是獨(dú)立編寫(xiě)C語(yǔ)言程序和匯編程序,C語(yǔ)言通過(guò)函數(shù)調(diào)用匯編子程序,這樣既可以提高程序的運(yùn)行效率,又保證了程序的可移植性,這要做的優(yōu)點(diǎn)還有程序的結(jié)構(gòu)性較好,并不影響C語(yǔ)言編譯器的優(yōu)化功能。
2023年2月4日TMS320C55xDSP原理及應(yīng)用58第4章C55x處理器的軟件設(shè)計(jì)
要很好地使用C語(yǔ)言與匯編的混合編程技術(shù),必須對(duì)C語(yǔ)言調(diào)用子函數(shù)的規(guī)則詳細(xì)掌握,這些規(guī)則包括C/C++中寄存器的使用、函數(shù)的結(jié)構(gòu)及調(diào)用規(guī)則等,只有這樣才能正確完成C語(yǔ)言對(duì)匯編模塊的調(diào)用。4.3.2C語(yǔ)言調(diào)用匯編模塊的接口2023年2月4日TMS320C55xDSP原理及應(yīng)用59第4章C55x處理器的軟件設(shè)計(jì)
4.3.2C語(yǔ)言調(diào)用匯編模塊的接口1.C/C++中的寄存器規(guī)則
這些規(guī)則決定編譯器在C語(yǔ)言環(huán)境下如何使用寄存器和如何在調(diào)用函數(shù)時(shí)傳遞參數(shù)。
在函數(shù)調(diào)用時(shí)把函數(shù)調(diào)用方叫做父函數(shù),被調(diào)用方叫做子函數(shù)。
規(guī)則規(guī)定在函數(shù)調(diào)用時(shí)所用到的寄存器需要預(yù)先保存,保存工作部分由父函數(shù)完成,父函數(shù)沒(méi)有保存的而又被子函數(shù)用到的寄存器由子函數(shù)保存。
2023年2月4日TMS320C55xDSP原理及應(yīng)用60第4章C55x處理器的軟件設(shè)計(jì)
寄存器保存方保存方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原理及應(yīng)用61第4章C55x處理器的軟件設(shè)計(jì)
2.函數(shù)調(diào)用規(guī)則
父函數(shù)在調(diào)用子函數(shù)時(shí)首先要將所要傳遞的參數(shù)放入寄存器或堆棧:
⑴
如果一個(gè)函數(shù)的變量用一個(gè)省略號(hào)聲明(標(biāo)志參數(shù)的數(shù)量是變化的),則剩余的參數(shù)跟著最后一個(gè)被聲明的參數(shù)被傳到堆棧,而堆棧的地址將作為訪問(wèn)其他未聲明參數(shù)的索引。2023年2月4日TMS320C55xDSP原理及應(yīng)用62第4章C55x處理器的軟件設(shè)計(jì)
2.函數(shù)調(diào)用規(guī)則⑵
編譯器通常先對(duì)所要傳遞的參數(shù)歸類(lèi),之后按照所歸類(lèi)別將參數(shù)放到寄存器中,參數(shù)可以分成三類(lèi):
●數(shù)據(jù)指針(int*,long*,等)●16位數(shù)據(jù)(char,short,int)●32位數(shù)據(jù)(long,float,double,以及函數(shù)指針)如果參數(shù)是指向數(shù)據(jù)類(lèi)型的指針,則該參數(shù)就是數(shù)據(jù)指針;如果一個(gè)參數(shù)能夠放入一個(gè)16位寄存器,則被看成一個(gè)16位數(shù)據(jù);否則該參數(shù)被看成一個(gè)32位數(shù)據(jù)。
2023年2月4日TMS320C55xDSP原理及應(yīng)用63第4章C55x處理器的軟件設(shè)計(jì)
2.函數(shù)調(diào)用規(guī)則⑶一個(gè)32位(兩個(gè)字)或小于32位的結(jié)構(gòu)被當(dāng)作一個(gè)32位數(shù)據(jù)通過(guò)寄存器傳送。⑷如果結(jié)構(gòu)的長(zhǎng)度大于2個(gè)字,則通過(guò)索引傳送,即編譯器把該結(jié)構(gòu)的地址作為一個(gè)數(shù)據(jù)指針傳送。2023年2月4日TMS320C55xDSP原理及應(yīng)用64第4章C55x處理器的軟件設(shè)計(jì)
2.函數(shù)調(diào)用規(guī)則⑹參數(shù)在函數(shù)聲明中的排列位置是與其所分配的寄存器有直接關(guān)系的,它們按照表中所列順序排列。參數(shù)類(lèi)型
寄存器分配順序?qū)?yīng)的數(shù)據(jù)類(lèi)型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ù)組、字符串、指針、或占用空間長(zhǎng)度超過(guò)兩個(gè)字節(jié)的結(jié)構(gòu)(無(wú)符號(hào))字符、短整數(shù),整數(shù)長(zhǎng)整數(shù)、浮點(diǎn)數(shù)以及長(zhǎng)度小于等于兩個(gè)字節(jié)的結(jié)構(gòu)2023年2月4日TMS320C55xDSP原理及應(yīng)用65第4章C55x處理器的軟件設(shè)計(jì)
2.函數(shù)調(diào)用規(guī)則
如果參數(shù)的數(shù)量超過(guò)可使用寄存器數(shù)量,多余的參數(shù)會(huì)被壓入堆棧,子函數(shù)通過(guò)堆棧得到剩余參數(shù)。
子函數(shù)的返回參數(shù)也將根據(jù)返回參數(shù)的類(lèi)型使用不同的寄存器,表給出了這一對(duì)應(yīng)關(guān)系。
子函數(shù)返回類(lèi)型
所使用寄存器
說(shuō)明
Voidchar,unsignedchar,shortint,intlongint,float,doublestructT0AC0(X)AR0無(wú)返回參數(shù)返回16位數(shù)據(jù)返回32位數(shù)據(jù)返回地址2023年2月4日TMS320C55xDSP原理及應(yīng)用66第4章C55x處理器的軟件設(shè)計(jì)
2.函數(shù)調(diào)用規(guī)則
給出參數(shù)傳遞的例子:首先聲明兩個(gè)結(jié)構(gòu),其中big的長(zhǎng)度大于兩個(gè)字節(jié),small的長(zhǎng)度等于兩個(gè)字節(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ù)通過(guò)AR0、T0、T1、AR1傳遞structbigfn(int*p1);//返回AR0,參數(shù)通過(guò)AR1傳遞2023年2月4日TMS320C55xDSP原理及應(yīng)用67第4章C55x處理器的軟件設(shè)計(jì)
intfn(structbigb,int*p1);//返回T0,參數(shù)通過(guò)AR0、AR1傳遞structsmallfn(int*p1);//參數(shù)返回AC0,參數(shù)通過(guò)AR0傳遞intfn(structsmallb,int*p1);//參數(shù)返回T0,參數(shù)通過(guò)AC0、AR0傳遞intprintf(char*fmt,...);//參數(shù)返回T0,其余參數(shù)通過(guò)堆棧傳遞,并通過(guò)fmt的地址進(jìn)行索引voidfn(longl1,longl2,longl3,longl4,inti5);//參數(shù)通過(guò)AC0、AC1、AC2、堆棧和T0傳遞voidfn(longl1,longl2,longl3,int*p4,int*p5,int*p6,int*p7,int*p8,inti9,inti10);//參數(shù)通過(guò)AC0、AC1、AC2、AR0、AR1、AR2、AR3、AR4、T0、T1傳遞2023年2月4日TMS320C55xDSP原理及應(yīng)用68第4章C55x處理器的軟件設(shè)計(jì)C語(yǔ)言程序:/*聲明外部匯編函數(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原理及應(yīng)用69第4章C55x處理器的軟件設(shè)計(jì)
3.被調(diào)用函數(shù)的響應(yīng)
被調(diào)用函數(shù)需要完成如下工作:
⑴
子函數(shù)為本地變量、暫存空間以及函數(shù)本身可能調(diào)用函數(shù)的參數(shù)分配足夠的空間,這些工作要在函數(shù)調(diào)用之初完成。⑵
如果子函數(shù)修改一些寄存器,如T2、T3、AR5~AR7,需要子函數(shù)將這些數(shù)壓?;虬阉鼈兇鎯?chǔ)到一個(gè)沒(méi)有使用的寄存器中。如果子函數(shù)修改其他寄存器則不需要預(yù)先存儲(chǔ)這些數(shù)。2023年2月4日TMS320C55xDSP原理及應(yīng)用70第4章C55x處理器的軟件設(shè)計(jì)
3.被調(diào)用函數(shù)的響應(yīng)⑶如果子函數(shù)的參數(shù)是一個(gè)結(jié)構(gòu),它所收到的是指向這個(gè)結(jié)構(gòu)的指針。如果在被調(diào)用函數(shù)中需要對(duì)結(jié)構(gòu)進(jìn)行寫(xiě)操作,就需要把這個(gè)結(jié)構(gòu)復(fù)制到本地空間中,如果不進(jìn)行寫(xiě)操作,則可以直接通過(guò)指針訪問(wèn)這個(gè)結(jié)構(gòu)。
⑷子函數(shù)執(zhí)行代碼。2023年2月4日TMS320C55xDSP原理及應(yīng)用71第4章C55x處理器的軟件設(shè)計(jì)
3.被調(diào)用函數(shù)的響應(yīng)⑸函數(shù)按照表4-5的規(guī)則返回參數(shù),如果子函數(shù)返回一個(gè)結(jié)構(gòu),父函數(shù)為這個(gè)結(jié)構(gòu)分配空間,并傳遞指針到(X)AR0中。如果父函數(shù)沒(méi)有使用這個(gè)結(jié)構(gòu),則在(X)AR0中返回的地址為0。
⑹子函數(shù)將先前存儲(chǔ)的寄存器值重新放到寄存器中。
⑺子函數(shù)使堆棧返回調(diào)用前狀態(tài)。
⑻函數(shù)返回。2023年2月4日TMS320C55xDSP原理及應(yīng)用72第4章C55x處理器的軟件設(shè)計(jì)
C/C++與匯編語(yǔ)言可以通過(guò)多種方式聯(lián)系在一起,其中包括在C/C++中引用匯編語(yǔ)言中的常量或變量,并可以在C語(yǔ)言模塊中調(diào)用匯編代碼模塊。
C/C++調(diào)用匯編語(yǔ)言模塊時(shí)需要符合前面所述的寄存器規(guī)則和函數(shù)調(diào)用規(guī)則。在調(diào)用匯編模塊時(shí)還應(yīng)注意如下問(wèn)題:4.C/C++與匯編語(yǔ)言的接口2023年2月4日TMS320C55xDSP原理及應(yīng)用73第4章C55x處理器的軟件設(shè)計(jì)
4.C/C++與匯編語(yǔ)言的接口⑴調(diào)用C54x匯編函數(shù)時(shí),應(yīng)使用C54X_CALL或C54X_FAR_CALL關(guān)鍵字。⑵如果用匯編語(yǔ)言編寫(xiě)中斷例程,則需要保存在中斷例程中使用的所有寄存器。⑶如果在匯編程序中調(diào)用C/C++函數(shù),則只有特定的寄存器在C/C++中被保存,而其他寄存器則可能被C/C++函數(shù)改變。⑷在定義匯編函數(shù)名和變量時(shí),需要在函數(shù)名前加上下劃線“
_”來(lái)讓編譯器識(shí)別。
2023年2月4日TMS320C55xDSP原理及應(yīng)用74第4章C55x處理器的軟件設(shè)計(jì)下面分別給出定義匯編函數(shù)和變量,以及在C語(yǔ)言中調(diào)用這些函數(shù)和變量的例子。調(diào)用匯編函數(shù)的例子如下:
4.C/C++與匯編語(yǔ)言的接口2023年2月4日TMS320C55xDSP原理及應(yīng)用75第4章C55x處理器的軟件設(shè)計(jì)C語(yǔ)言程序:/*聲明外部匯編函數(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原理及應(yīng)用76第4章C55x處理器的軟件設(shè)計(jì)
4.C/C++與匯編語(yǔ)言的接口調(diào)用匯編模塊中所定義變量的例子如下:
匯編程序:.bss_var,1;定義變量.global_var;定義其為外部引用C語(yǔ)言程序:externintvar;/*外部變量*/var=1;/*使用變量*/2023年2月4日TMS320C55xDSP原理及應(yīng)用77第4章C55x處理器的軟件設(shè)計(jì)
4.C/C++與匯編語(yǔ)言的接口⑸如果C/C++中的變量要在匯編語(yǔ)言中訪問(wèn),則該變量應(yīng)用.global聲明。
⑹編譯器所默認(rèn)的CPL值為1,即采用間接絕對(duì)方式尋址,如果在匯編函數(shù)中CPL被設(shè)置為0,在函數(shù)返回時(shí)應(yīng)當(dāng)把這個(gè)值改為1。下面的例子是對(duì)應(yīng)CPL=1或=0時(shí)所使用的不同匯編語(yǔ)句:MOV*(#global_var),AR3;CPL==1MOVglobal_var,AR3;CPL==0
2023年2月4日TMS320C55xDSP原理及應(yīng)用78⑺在匯編語(yǔ)言中可以通過(guò).set、.global命令聲明全局常量,這些常量在C/C++中可以通過(guò)特殊的方式訪問(wèn)。例如試圖訪問(wèn)常量X,則在該常量名前需要加上“&”操作符,即在C/C++中該常量名為&X。例如:
第4章C55x處理器的軟件設(shè)計(jì)
4.C/C++與匯編語(yǔ)言的接口2023年2月4日TMS320C55xDSP原理及應(yīng)用79第4章C55x處理器的軟件設(shè)計(jì)
匯編語(yǔ)言:_table_size.set10000 ;定義常量.global_table_size ;定義的變量可以被全局訪問(wèn)C語(yǔ)言程序:externinttable_size; /*外部參數(shù)*/#defineTABLE_SIZE((int)(&table_size))………………for(i–0;i<TABLE_SIZE;++i)/*使用該常數(shù)*/2023年2月4日TMS320C55xDSP原理及應(yīng)用80第4章C55x處理器的軟件設(shè)計(jì)
匯編器和鏈接器產(chǎn)生的可執(zhí)行文件所采用的格式是通用目標(biāo)文件格式(COFF),采用通用目標(biāo)文件格式有助于實(shí)現(xiàn)模塊化編程。
匯編器和鏈接器都支持用戶(hù)創(chuàng)建多個(gè)代碼段和數(shù)據(jù)段,這也有助于用戶(hù)的靈活編程。
編譯器產(chǎn)生的可以重新定位的代碼和數(shù)據(jù)塊叫做段。
4.4通用目標(biāo)文件格式2023年2月4日TMS320C55xDSP原理及應(yīng)用81第4章C55x處理器的軟件設(shè)計(jì)
初始化段裝有數(shù)據(jù)或代碼。常用的初始化段包括代碼段(.text段)、常數(shù)段(.const段)等。
未初始化段的作用是在存儲(chǔ)器中保留一定空間供程序生成和存儲(chǔ)變量使用。常用的未初始化段包括堆棧和系統(tǒng)堆棧段(.stack和.sysstack)、存儲(chǔ)全局和靜態(tài)變量的.bss段以及為分配動(dòng)態(tài)存儲(chǔ)器保留的.sysmem段等。
段可以分成兩大類(lèi)——初始化段和未初始化段。
4.4通用目標(biāo)文件格式2023年2月4日TMS320C55xDSP原理及應(yīng)用82第4章C55x處理器的軟件設(shè)計(jì)
4.4.1C/C++和匯編語(yǔ)言中段的分配
在C/C++程序中可以使用編譯命令直接將代碼或數(shù)據(jù)分配到所要分配的段中。4.4通用目標(biāo)文件格式用CODE_SECTION命令可以分配代碼到指定的段中,在C語(yǔ)言中語(yǔ)法如下:#pragmaCODE_SECTION(symbol,“sectionname”)[;]C++中則采用下面的語(yǔ)句:
#pragmaCODE_SECTION(“sectionname”)[;]
2023年2月4日TMS320C55xDSP原理及應(yīng)用83第4章C55x處理器的軟件設(shè)計(jì)
例:#pragmaCODE_SECTION(funcA,“codeA”)intfuncA(inta){inti;return(i=a);}編譯后的結(jié)果如下:.sect“codeA”.global_funcA
;*************************************************;*FUNCTIONNAME:_funcA*;*************************************************_funcA:……return;返回2023年2月4日TMS320C55xDSP原理及應(yīng)用84第4章C55x處理器的軟件設(shè)計(jì)4.4.1C/C++和匯編語(yǔ)言中段的分配
在C語(yǔ)言中按下面給出的語(yǔ)法定義:#pragmaDATA_SECTION(symbol,“sectionname”)[;]
C++中的語(yǔ)法是:#pragmaDATA_SECTION(“
sectionname”)[;]
2023年2月4日TMS320C55xDSP原理及應(yīng)用85第4章C55x處理器的軟件設(shè)計(jì)4.4.1C/C++和匯編語(yǔ)言中段的分配
分配數(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原理及應(yīng)用86第4章C55x處理器的軟件設(shè)計(jì)
4.4.1C/C++和匯編語(yǔ)言中段的分配
下面給出匯編語(yǔ)言中為代碼分配段的例子:.textMOV#10,AC0MOVAC0,AC1
下面給出匯編語(yǔ)言中為數(shù)據(jù)分配段的例子:.data.word9,10.word11,12
2023年2月4日TMS320C55xDSP原理及應(yīng)用87第4章C55x處理器的軟件設(shè)計(jì)
TMS320C55x處理器采用改進(jìn)的哈佛結(jié)構(gòu),在該結(jié)構(gòu)下存儲(chǔ)器被分成幾個(gè)獨(dú)立的空間:
程序空間
數(shù)據(jù)空間
I/O空間C55x編譯器為這些空間內(nèi)的代碼塊和數(shù)據(jù)塊分配內(nèi)存。4.4.2寄存器模式設(shè)置
(略)
2023年2月4日TMS320C55xDSP原理及應(yīng)用88第4章C55x處理器的軟件設(shè)計(jì)
在小存儲(chǔ)器模式下,代碼段和數(shù)據(jù)段的長(zhǎng)度和位置都受到一定限制。
如下列段都必須在長(zhǎng)度為64K字的同一個(gè)段內(nèi):
.bss段和.data段(存放靜態(tài)和全局變量).stack和.sysstack段(系統(tǒng)堆棧).system段(動(dòng)態(tài)存儲(chǔ)空間).const段
1.小存儲(chǔ)器模式
4.4.2寄存器模式設(shè)置
2023年2月4日TMS320C55xDSP原理及應(yīng)用89第4章C55x處理器的軟件設(shè)計(jì)
小存儲(chǔ)器模式下,.text(代碼段)、.switch(狀態(tài)轉(zhuǎn)化段)以及.cinit/.pinit(變量初始化段)的長(zhǎng)度和位置都不受限制;
小存儲(chǔ)器模式下,數(shù)據(jù)指針為16位。在采用數(shù)據(jù)指針尋址時(shí),XARx寄存器的高7位指向.bss段所在的數(shù)據(jù)頁(yè),并在程序運(yùn)行時(shí)始終指向該段。
1.小存儲(chǔ)器模式
2023年2月4日TMS320C55xDSP原理及應(yīng)用90第4章C55x處理器的軟件設(shè)計(jì)
如果在編譯器中設(shè)置-ml選項(xiàng),則編譯器將按照大存儲(chǔ)器模式編譯程序。
大存儲(chǔ)器模式下可以更加方便地存放數(shù)據(jù),而不必過(guò)多地考慮數(shù)據(jù)頁(yè)的限制。
在該模式下,數(shù)據(jù)指針為23位,而堆棧和系統(tǒng)堆棧必須放在同一頁(yè)中;
代碼段可以跨越頁(yè)邊界以外;除代碼段外的其他所有的段只能放在一頁(yè)存儲(chǔ)器之中。
2.大存儲(chǔ)器模式
2023年2月4日TMS320C55xDSP原理及應(yīng)用91第4章C55x處理器的軟件設(shè)計(jì)
C55x的堆棧主要用來(lái)保存處理器信息,向函數(shù)傳遞參數(shù)以及分配局部變量。堆棧在一塊地址按由高到低排列的連續(xù)存儲(chǔ)器之中,編譯器通過(guò)堆棧指針(SP)操作堆棧。C55x還存在輔助堆棧,主堆棧主要存放低16位地址,而輔助堆棧則存放C55x返回的高8位地址,編譯器通過(guò)輔助堆棧指針(SSP)操作輔助堆棧。堆棧的大小由鏈接器設(shè)置,__STACK_SIZE和__SYSSTACK_SIZE兩個(gè)全局符號(hào)存放的是堆棧的長(zhǎng)度值。
系統(tǒng)默認(rèn)主堆棧和輔助堆棧的長(zhǎng)度都是1000個(gè)字節(jié)。
3.C/C++系統(tǒng)堆棧
2023年2月4日TMS320C55xDSP原理及應(yīng)用92第4章C55x處理器的軟件設(shè)計(jì)
編譯器為動(dòng)態(tài)內(nèi)存分配提供了如下函數(shù):malloccallocrealloc在C語(yǔ)言中調(diào)用這些函數(shù)會(huì)在.sysmem段定義的內(nèi)存池中分配內(nèi)存。__SYSMEM_SIZE中存放的內(nèi)存池的大小(單位為字節(jié)),系統(tǒng)默認(rèn)大小為2000個(gè)字節(jié)。動(dòng)態(tài)內(nèi)存分配只能通過(guò)指針訪問(wèn),可分配的內(nèi)存大小受內(nèi)存池中剩余空間限制,動(dòng)態(tài)內(nèi)存的優(yōu)點(diǎn)是系統(tǒng)只在需要時(shí)才分配,不用時(shí)就可以釋放所申請(qǐng)的空間,被系統(tǒng)使用。4.動(dòng)態(tài)內(nèi)存分配
2023年2月4日TMS320C55xDSP原理及應(yīng)用93注意:如果所申請(qǐng)的空間需要經(jīng)常訪問(wèn),建議申請(qǐng)靜態(tài)內(nèi)存,因?yàn)槿绻暾?qǐng)和釋放內(nèi)存的操作很頻繁,將過(guò)多占用系統(tǒng)資源,降低程序的執(zhí)行效率。
第4章C55x處理器的軟件設(shè)計(jì)
4.動(dòng)態(tài)內(nèi)存分配
接下來(lái)給出申請(qǐng)動(dòng)態(tài)內(nèi)存的例子,由例子可以看到在定義變量指針時(shí)不需要定義數(shù)組的大小,而只在申請(qǐng)內(nèi)存時(shí)才需給出申請(qǐng)的內(nèi)存長(zhǎng)度。
structbig*table;table=(structbig*)malloc(100*sizeof(structbig));
2023年2月4日TMS320C55xDSP原理及應(yīng)用94第4章C55x處理器的軟件設(shè)計(jì)
5.結(jié)構(gòu)的對(duì)齊當(dāng)編譯器為結(jié)構(gòu)分配空間時(shí),將為結(jié)構(gòu)的所有成員分配空間。
例如一個(gè)結(jié)構(gòu)包含一個(gè)長(zhǎng)整型的成員(32位),則長(zhǎng)整型會(huì)被分配到長(zhǎng)整型邊界上。為了保證分配,編譯器會(huì)在結(jié)構(gòu)的開(kāi)頭、中間或結(jié)尾進(jìn)行填充,以保證結(jié)構(gòu)的長(zhǎng)度為偶數(shù)。2023年2月4日TMS320
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 內(nèi)科查房課件教學(xué)
- 欲取姑予成語(yǔ)教學(xué)課件
- 酒吧吧臺(tái)設(shè)計(jì)與施工承包協(xié)議
- 紋唇教學(xué)課件
- 電氣作業(yè)安全知識(shí)及操作規(guī)范相關(guān)試題測(cè)試卷
- 2024-2025學(xué)年江蘇省百校聯(lián)考高一下學(xué)期5月月考生物試題及答案
- 消費(fèi)者對(duì)農(nóng)產(chǎn)品質(zhì)量安全的認(rèn)知與態(tài)度考核試卷
- 合成氣在能源結(jié)構(gòu)優(yōu)化中的政策支持體系構(gòu)建考核試卷
- 國(guó)際工程項(xiàng)目技術(shù)標(biāo)準(zhǔn)與規(guī)范應(yīng)用考核試卷
- 五金產(chǎn)品創(chuàng)新設(shè)計(jì)中的數(shù)字化工具應(yīng)用研究考核試卷
- 2024年廣州市黃埔軍校紀(jì)念中學(xué)小升初分班考試數(shù)學(xué)模擬試卷附答案解析
- 山東青島市李滄區(qū)2023-2024學(xué)年七年級(jí)下學(xué)期期末考試英語(yǔ)試題
- 遭遇暴徒的應(yīng)急預(yù)案及流程
- 《城市排水管渠數(shù)字化檢測(cè)與評(píng)估技術(shù)規(guī)程》
- 醫(yī)保基金監(jiān)管培訓(xùn)課件
- 穿越華裾-中華服飾之美智慧樹(shù)知到期末考試答案2024年
- 咳喘疾病中氣道重塑的機(jī)制及治療靶點(diǎn)研究
- 藥店人際關(guān)系建設(shè)與溝通技巧培訓(xùn)
- 機(jī)電安裝質(zhì)量檢測(cè)報(bào)告
- 30道醫(yī)院眼科醫(yī)生崗位高頻面試問(wèn)題附考察點(diǎn)及參考回答
- 北師大版數(shù)學(xué)小學(xué)二年級(jí)下冊(cè)期末無(wú)紙筆化檢測(cè)題
評(píng)論
0/150
提交評(píng)論