《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 嵌入式技術(shù) > 設(shè)計(jì)應(yīng)用 > 嵌入式C語(yǔ)言開(kāi)發(fā)ADSP21XX系列DSP
嵌入式C語(yǔ)言開(kāi)發(fā)ADSP21XX系列DSP
互聯(lián)網(wǎng)
摘要: 詳細(xì)介紹使用VisualDSP開(kāi)發(fā)工具進(jìn)行ADSP21XX的C語(yǔ)言編程的方法,;分析其C語(yǔ)言運(yùn)行庫(kù)的結(jié)構(gòu),,并且結(jié)合實(shí)例介紹C語(yǔ)言工具的使用方法,包括C語(yǔ)言與匯編語(yǔ)言混合編程的方法,,從C運(yùn)行庫(kù)提取代碼用于自己的匯編語(yǔ)言程序的方法,、修改運(yùn)行庫(kù)的源代碼以適應(yīng)自己開(kāi)發(fā)需要的方法等。
Abstract:
Key words :
  摘要:詳細(xì)介紹使用VisualDSP開(kāi)發(fā)工具進(jìn)行ADSP21XX的C語(yǔ)言編程的方法,;分析其C語(yǔ)言運(yùn)行庫(kù)的結(jié)構(gòu),,并且結(jié)合實(shí)例介紹C語(yǔ)言工具的使用方法,包括C語(yǔ)言與匯編語(yǔ)言混合編程的方法,,從C運(yùn)行庫(kù)提取代碼用于自己的匯編語(yǔ)言程序的方法,、修改運(yùn)行庫(kù)的源代碼以適應(yīng)自己開(kāi)發(fā)需要的方法等。

    關(guān)鍵詞:DSP VisualDSP 嵌入式C語(yǔ)言 匯編語(yǔ)言

引言

長(zhǎng)期以來(lái),,在DSP系統(tǒng)開(kāi)發(fā)中,,一直把匯編語(yǔ)言作為主要的開(kāi)發(fā)工具;但匯編語(yǔ)言與自然語(yǔ)言差距很大,,不易常,,而且匯編語(yǔ)言是依賴于處理器的,不利于軟件的可重復(fù)利用和系統(tǒng)的穩(wěn)定性,,程序不易移植,,給開(kāi)發(fā)工作帶來(lái)了很大的困難。隨著嵌入式系統(tǒng)復(fù)雜程度的不斷提高,,用匯編語(yǔ)言編寫(xiě)一個(gè)巨大的程度將是困難,,甚至是不可能的,。為此,AD公司推出了針對(duì)ADSP21XX系列DSP的嵌入式C和C++語(yǔ)言集成開(kāi)發(fā)工具,,分別是VisualDSP和VisualDSP++系列,,這些開(kāi)發(fā)工具提供了C語(yǔ)言和C++語(yǔ)音的開(kāi)發(fā)功能。以下就以筆者在實(shí)際開(kāi)發(fā)中的一些經(jīng)驗(yàn),,結(jié)合VisualDSP6.1版本,,介紹用C語(yǔ)言開(kāi)發(fā)VisualDSP6.1版本,介紹用C語(yǔ)言開(kāi)發(fā)ADSP21XX的方法,。VisualDSP提供了一個(gè)開(kāi)放源碼軟件組織GNU的C編譯器,,和一套成熟穩(wěn)定的C運(yùn)行時(shí)間庫(kù)(C Run time Library)等。GNU的編譯器一向以編譯效率高著稱,,在編譯后的代碼長(zhǎng)度和運(yùn)行速度方面非常優(yōu)秀,;C運(yùn)行時(shí)間庫(kù)則把很多重復(fù)性的工作,如浮點(diǎn)運(yùn)行,、三角函數(shù),、FFT等作為C語(yǔ)言的庫(kù)函數(shù),提供給用戶,,大大提高了用戶的開(kāi)發(fā)效率和程序的穩(wěn)定性,,降低了開(kāi)發(fā)難度,另外,,由于把這些庫(kù)函數(shù)的源代碼提供給了用戶,,還提高了C語(yǔ)言與匯編語(yǔ)言之間的透明性,使用戶開(kāi)發(fā)的程序兼具兩者的優(yōu)點(diǎn),。

1 Visual DSP簡(jiǎn)介

VisualDSP是AD公司的DSP開(kāi)發(fā)工具,,主要由可執(zhí)行文件、庫(kù)文件和各種幫助文檔組成,。6.1版本還帶有一個(gè)基于圖形界面,,針對(duì)21XX系列DSP的軟件仿真和調(diào)試工具。

VisualDSP的可執(zhí)行文件包括匯編,、編譯,、鏈接工具以及可執(zhí)行文件重新格式化工具等,見(jiàn)表1,。

表1 VisualDSP的可執(zhí)行文件及用途

可執(zhí)行文件名

用      途

Asmpp.exe* 匯編預(yù)處理程序
Asm2.exe* 21XX系列匯編程序的匯編程序
Asm21.exe 21XX系列命令行匯編程序
Ld21.exe 21XX系列鏈接工具
G21.exe 基于GNU的21XX系列C編譯器
Bld21.exe 系統(tǒng)編譯工具,,產(chǎn)生相應(yīng)于不同硬件體系的.ACH文件
Lib21.exe 21XX系列的庫(kù)管理工具
Hspl21.exe 把21XX系列可執(zhí)行文件變成HIP口可加載的格式
Spl21.exe 把21XX系列可執(zhí)行文件變成PROM可燒寫(xiě)的格式

注:“*”代表該程序一般不單獨(dú)使用,而昌由G21.exe或Asm21.exe調(diào)用,。

VisualDSP套件中的軟件仿真調(diào)試工具DEBUGAPP,,采用Windows圖形界面,使用方便,。它的主要特點(diǎn)是:可以仿真調(diào)試從ADSP2101~2189全系列的DSP,;支持?jǐn)帱c(diǎn),、單步、全速運(yùn)行等各種常見(jiàn)調(diào)試方法,;可以隨時(shí)查詢和修改DSP的程序RAM(PM),、數(shù)據(jù)RAM(DM)和各寄存器的內(nèi)容;可以仿真中斷,,進(jìn)行可執(zhí)行程序性能評(píng)估(Profile),,因此可以進(jìn)行時(shí)序仿真。DEBUGAPP是調(diào)試程序和驗(yàn)證復(fù)雜算法的極好工具,。

VisualDSP6.1還提供了豐富的幫助文檔,,包括21XX系列的用戶手冊(cè)、匯編和C語(yǔ)言工具以及仿真調(diào)試程序的使用手冊(cè),;還有C運(yùn)行庫(kù)的參考手冊(cè),,列出了所有可用的C庫(kù)函數(shù)。用C語(yǔ)言開(kāi)發(fā)DSP的典型流程如圖1所示,。

2 C語(yǔ)言運(yùn)行庫(kù)結(jié)構(gòu)

C語(yǔ)言運(yùn)行時(shí)間庫(kù)是位于LIB目錄下的*.a文件,是整個(gè)C開(kāi)發(fā)工具的核心之一,,提供了大量的可以直接調(diào)用的庫(kù)函數(shù),。這些庫(kù)函數(shù)的函數(shù)原型包含在INCLUDE目錄下的頭文件中。這些頭文件有的還包含一些宏定義,。另外,,VisualDSP還把這些庫(kù)函數(shù)的匯編語(yǔ)言源代碼提供給出了用戶,方便了用戶從中提取有用的代碼,,甚至修改源代碼,,生成新的庫(kù),來(lái)適應(yīng)自己的要求,。利用LIB21程序,,還可以把自己的常用匯編子程序做成庫(kù),或是將實(shí)時(shí)性要求較高的代碼用匯編語(yǔ)言來(lái)寫(xiě),,做成庫(kù),,供C語(yǔ)言程序調(diào)用。

VisualDSP的C語(yǔ)言運(yùn)行庫(kù)由兩部分組成:應(yīng)用程序框架和預(yù)定義的各種庫(kù)函數(shù),。

不同的DSP型號(hào)有不同的硬件結(jié)構(gòu),、中斷向量表,所以對(duì)應(yīng)的應(yīng)用程序框架庫(kù)也不同,,相應(yīng)的文件是21*_HDR.DSP.其中*代表不同的DSP型號(hào),。應(yīng)用程序框架的主體是中斷向量處理部分,把中斷向量引到合適的地址,。其中最重要的是對(duì)系統(tǒng)復(fù)位(RESET_VECTOR)的中斷向量的處理:

_Reset_vector:CALL_lib_setup_everything;

CALL main_,;

JUMP_lib_prog_term;

NOP,;

第一條指令是調(diào)用C庫(kù)函數(shù)中的_ _lib_setup_everything函數(shù)作程序啟動(dòng)時(shí)的初始化工作。接下來(lái),,調(diào)用C語(yǔ)言程序中的main_函數(shù),,進(jìn)入C程序的主體,也就是進(jìn)入用戶自己程序,,開(kāi)始正常工作,。主程序結(jié)束后,再調(diào)用_lib_prog_term函數(shù),,作程序退出時(shí)的結(jié)尾工作,。由于嵌入式系統(tǒng)的特性,系統(tǒng)絕大多數(shù)都在主程序運(yùn)行時(shí)被繼電了,,所以_lib_prog_term得到執(zhí)行的機(jī)會(huì)很小,。

其它的中斷向量由C運(yùn)行庫(kù)來(lái)管理,匯編指令如下:

_Interrupt2:JUMP_lib_int2_ctrl;NOP;NOP;NOP,;

其中的_lib_int2_crtl就是C語(yǔ)言庫(kù)中控制INT2的函數(shù),。如果用戶要使用該中斷,應(yīng)先把中斷服務(wù)程序用一個(gè)C庫(kù)函數(shù)Interrupt()把服務(wù)函數(shù)指針設(shè)定好,,并打開(kāi)相應(yīng)的中斷允許位,,當(dāng)該中斷發(fā)生時(shí),_lib_int2_ctr1函數(shù)就會(huì)控制DSP跳轉(zhuǎn)到相應(yīng)的指針位置,。

VisualDSP預(yù)定義的C語(yǔ)言庫(kù)函數(shù)包括數(shù)學(xué)函數(shù),、FFT函數(shù)、ANSI標(biāo)準(zhǔn)內(nèi)存管理和字符串管理函數(shù)的一個(gè)子集,。所有的函數(shù)列表可參考VisualDSP的聯(lián)機(jī)文檔,。這些庫(kù)函數(shù)以二進(jìn)制代碼的形式,打包集合在lib*.a文件中,,用戶的C語(yǔ)言程序可以像使用自己的子程序一樣方便地調(diào)用這些庫(kù)函數(shù),。下面是調(diào)用庫(kù)函數(shù)的一個(gè)例子。

#include //包含所需的頭文件

……

float a,b,c; //定義所需的變量

……

c=a*sin(b); //數(shù)學(xué)運(yùn)算

編譯后產(chǎn)生的匯編源代碼中有call sin_指令,,就是調(diào)用sin庫(kù)函數(shù)的匯編語(yǔ)言指令語(yǔ)句,。

從嵌入式開(kāi)發(fā)的角度講,VisualDSP的C語(yǔ)言工具已經(jīng)提供了一個(gè)操作系統(tǒng)雛形的功能,。在AD公司的ADMC系列DSP中,,已經(jīng)把這些庫(kù)函數(shù)和一些電機(jī)控制專用的函數(shù),以及程序加載功能,,集成在了DSP的片內(nèi)ROM中,。

3 C語(yǔ)言與匯編語(yǔ)言混合編程方法

用C語(yǔ)言開(kāi)發(fā)的缺點(diǎn)是不能精確控制程序運(yùn)行的時(shí)間,對(duì)于實(shí)時(shí)性要求較高的應(yīng)用,,必須用匯編語(yǔ)言,。VisualDSP為用戶提供了兩種與匯編語(yǔ)言的接口方法:用ASM()方法,,直接嵌入?yún)R編語(yǔ)言語(yǔ)句;用匯編語(yǔ)言編寫(xiě)子程序,,供C語(yǔ)言程序調(diào)用,。為了支持C語(yǔ)言與匯編程序程序的接口,VisualDSP預(yù)定義了諸如FUNCTION_ENTRY,、EXIT,、SAVE_REG、RESTORE_REG等13個(gè)宏,。限于篇幅,,不詳細(xì)介紹其功能。使用這些宏以前,,要包含asm_sprt.h頭文件,。

3.1 使用ASM()嵌入行的方法

使用這一方法時(shí),一定要注意各寄存器和堆棧當(dāng)前的狀態(tài),,以免破壞程序運(yùn)行的環(huán)境,,產(chǎn)生錯(cuò)誤的結(jié)果。VisualDSP保留了一些內(nèi)部寄存器供用戶的匯編代碼使用,。用戶可以自由地修改其內(nèi)容,,而不會(huì)對(duì)程序造成破壞。這些寄存器包括AR,、AF,、AY1,、M5,、11、16,、MF,、MR0等18個(gè)。如果不夠用,,可以用系統(tǒng)定義的宏save_reg和restore_reg保護(hù)現(xiàn)場(chǎng),,得到另外11個(gè)可用寄存器。另外要注意的是,,在匯編語(yǔ)言中操作C語(yǔ)言中定義的變量時(shí),,要在變量名后加下劃線。下面是一個(gè)嵌套匯編語(yǔ)言的例子:

int img228; //定義C語(yǔ)言變量

asm("ax0=0x5c;")

asm("dm(ing228_)=ax0"); //用匯編語(yǔ)言賦值要將Img228變成Img228_

img228=0x5c; //直接用C語(yǔ)言賦值

編譯后的匯編語(yǔ)言代碼是

ax0=0x5c;

dm(img228_)=ax0

my1=92;

dm(img228_)=my1;

注意前者可能會(huì)破壞程序結(jié)構(gòu),,因?yàn)樗褂昧宋唇?jīng)保護(hù)的寄存器AX0,;而由C語(yǔ)言產(chǎn)生的匯編代碼,則會(huì)自動(dòng)選擇合適的臨時(shí)寄存器MY1,。

3.2 使用匯編子程序的方法

使用匯編子程序是C語(yǔ)言程序與匯編語(yǔ)言接口的另一種方法,。用戶定義的子程序放在單獨(dú)的匯編文件中,,或是做成二進(jìn)制的庫(kù)文件,并將子程序的定義用GLOBEL輸出,,匯編后就可以供C語(yǔ)言程序調(diào)用,。下面是一個(gè)不需要參數(shù)的子程序的例子:

.MODULE/RAM_delay_;

.external del_cycle; //聲明del_cycle是外部變量

.global delay; //聲明delay為全局函數(shù)

delay_:

runction_entry; //子程序開(kāi)始標(biāo)志,,必須要的

ar=dm(del_cycle_);

cntr=ar;

do d_loop until ce;

d_loop:nop;

exit; //子程序結(jié)束標(biāo)志,,必須要的

.ENDMOD;

如果匯編語(yǔ)言子程序中用到了參數(shù),,情況就復(fù)雜些,。子程序中的入口參數(shù)前兩個(gè)一定要保存在AR、AY1中,。如果參數(shù)多于兩個(gè)就要把其余的放在堆棧中,。所有子程序的第一個(gè)返回值放在AR中。如果返回值不止一個(gè),,就要用到變量型參數(shù)或者指針來(lái)獲得取所有的返回值了,。下面是一個(gè)有5個(gè)輸入?yún)?shù)、1個(gè)返回值的子程序例子,。

add5_:

function_entry;

ar=ar+ay1; //前面的兩個(gè)變量放在AR,、AY1中

readsfirst(ay1); //從程序堆棧中讀取第三個(gè)變量

ar=ar+ay1;

ay1=readsnext; //從程序堆棧中讀取第四個(gè)變量

ar=ar+ay1;

ay1=readsnext; //從程序堆棧中讀取第五個(gè)變量

ar=ar+ay1; //返回值放在AR中

exit,;

注意其中的readsfirst和readsnext都是匯編語(yǔ)言接口宏,。其功能是從堆棧中讀取所有的參數(shù)。

4 C運(yùn)行庫(kù)的匯編源代碼

如果只用C語(yǔ)言來(lái)開(kāi)發(fā)21XX程序,,只要有C運(yùn)行庫(kù)的二進(jìn)制版就夠了,。幸運(yùn)的是,AD公司把所有C運(yùn)行庫(kù)的匯編源代碼隨VisualDSP提供給了用戶,,所以對(duì)那些用匯編語(yǔ)言開(kāi)發(fā)的工程師來(lái)說(shuō),,這些源代碼也提供了很大的幫助。因此這代表很多功能的子程序不需要自己去編碼,、調(diào)試,,用到某功能時(shí)只要把相應(yīng)的匯編代碼鏈接進(jìn)自己的程序就可以。C運(yùn)行庫(kù)的源代碼是擴(kuò)展名為DSP的文本文件,?;旧弦粋€(gè)庫(kù)函數(shù)對(duì)應(yīng)一個(gè)文件,文件名就是函數(shù)名,。比如說(shuō)sin.dsp是正弦,、余弦查找、使用都很方便,但是對(duì)于其中的交叉調(diào)用要注意,。

反過(guò)來(lái),,用戶也可以把自己已經(jīng)調(diào)試、驗(yàn)證過(guò)的匯編子程序,,做成二進(jìn)制庫(kù)文件,,供C程序調(diào)用,這樣可以大大提高軟件的可重復(fù)利用率,。要制作二進(jìn)制庫(kù)文件,,只要用lib21.exe工具處理就行了。注意,,生成的二制庫(kù)文件的名字必須以.a作為文件擴(kuò)展名,。

筆者在實(shí)際的開(kāi)發(fā)中,遇到這樣的情況,,自制的2181目標(biāo)板上有一個(gè)自己開(kāi)忍氣吞聲駐留程序,,通過(guò)軟件模擬的異步串口與PC通信,加載程序,。但是這個(gè)駐留程序占據(jù)了0~0x500的空間,,用戶開(kāi)發(fā)的程序只能加載到從0x500開(kāi)始的空間內(nèi),而用C語(yǔ)言開(kāi)發(fā)的程序起始地址都是從0開(kāi)始的,。為了解決這個(gè)問(wèn)題,,只能自己修改2181_hdr.dsp源文件。首先把第一行的.MODULE/ABS=0改成.MODULE/ABS=0x500,,然后匯編成obj文件,,代替原來(lái)的文件。另外,,在自己的程序中定義一個(gè)從0開(kāi)始0x500大小的PM區(qū)域,,并初始化成0,就可以防止編譯器在該區(qū)域內(nèi)分配別的變量或程序代碼,,這樣編譯后的可執(zhí)行文件的0~0x500空間都是0,,加載時(shí)把它剔除,,而其它有用的指令代碼都在0x500之后,,解決了這一個(gè)問(wèn)題。

5 總結(jié)

從實(shí)際開(kāi)發(fā)的經(jīng)驗(yàn)來(lái)看,,VisualDSP的C語(yǔ)言開(kāi)發(fā)功能十分豐富,。雖然提供的庫(kù)函數(shù)只是ANSI的一個(gè)不完備子集,但是對(duì)于一般的工程開(kāi)發(fā)來(lái)說(shuō)已經(jīng)足夠用了,,而且VisualDSP還提供了C運(yùn)行庫(kù)的源代碼,,這對(duì)于解決函數(shù)不完備的問(wèn)題也好處。用C語(yǔ)言開(kāi)發(fā)的好處還包括開(kāi)發(fā)時(shí)間大大減少,,程序的穩(wěn)定性大大提高,,這對(duì)于面對(duì)激烈的市場(chǎng)競(jìng)爭(zhēng),,對(duì)于減輕設(shè)計(jì)工程師的工作量都很有好處。最后,,用C語(yǔ)言開(kāi)發(fā)是趨勢(shì),,必將更加流行。

此內(nèi)容為AET網(wǎng)站原創(chuàng),,未經(jīng)授權(quán)禁止轉(zhuǎn)載,。