第五章Blackfin嵌入式C編程課件_第1頁
第五章Blackfin嵌入式C編程課件_第2頁
第五章Blackfin嵌入式C編程課件_第3頁
第五章Blackfin嵌入式C編程課件_第4頁
第五章Blackfin嵌入式C編程課件_第5頁
已閱讀5頁,還剩73頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

大家好Blackfin嵌入式C編程本章要點CCES集成開發(fā)環(huán)境嵌入式C編程31.CCES集成開發(fā)環(huán)境ADSP程序開發(fā)流程4CCES(CrosscoreEmbeddedStudio)是ADI公司針對ADSP系列處理器提供的新一代集成開發(fā)工具。其使用方法與VisualDSP++非常類似。CCES通過圖形窗口的方式與用戶進行信息交換,程序開發(fā)人員可以在窗口中進行高效的工程管理,輕松地在編輯、編譯和調試之間互相切換,實現高效率的程序開發(fā)。CCES集成開發(fā)環(huán)境5CrossCore?Embedded StudioisADI’sNew Eclipse?basedToolchain???????IDEDebuggerCompilersAssemblersLinkerLoaderAlgorithmLibraries76CCESIDE特點基于Eclipse的集成開發(fā)環(huán)境

支持多核開發(fā)與調試優(yōu)異的代碼生成工具,包括Compilers,Assemblers,Linker,Loader.成熟的算法庫優(yōu)化的系統服務及設備驅動軟件插件便于集成,包括RTOS,TCP/IPStack,USBStack,&FileSystem.硬件兼容性強,支持多核處理器板、擴展子板,支持音視頻采集、處理、顯示與播放.7步驟1:新建工程(1/7)—啟動CCESCCES程序開發(fā)、調試步驟8步驟1:新建工程(2/7)—點擊新建工程9步驟1:新建工程(3/7)—輸入工程名稱與類型10步驟1:新建工程(5/7)—配置路徑11步驟1:新建工程(5/7)—配置目標平臺12步驟1:新建工程(6/7)—配置插件13步驟1:新建工程(7/7)—配置開發(fā)語言14步驟2:編程(1/2)—添加sourcefileC/C++視圖Folder&fileautoGenerated15步驟2:編程(2/2)—編寫代碼GeneratedbyCCES16步驟3:編譯及配置(1/10)—點擊BuildProject17步驟3:編譯及配置(2/10)—觀察編譯結果18步驟3:編譯及配置(3/10)—點擊屬性配置19步驟3:編譯及配置(4/10)—Assembler配置Commandline20步驟3:編譯及配置(5/10)—C/C++CompilerAssemblerleveloptimization21步驟3:編譯及配置(6/10)—definition&include22步驟3:編譯及配置(7/10)—LDRfileconfigIfyoumakeaLDRfile23步驟3:編譯及配置(8/10)—目標處理器選擇目標器件24步驟3:編譯及配置(9/10)—編譯類型配置25步驟3:編譯及配置(10/10)—環(huán)境變量26步驟4:調試(1/10)—點擊DebugAs27步驟4:調試(2/10)—選擇目標處理器28步驟4:調試(3/10)—選擇連接類型29步驟4:調試(4/10)—選擇平臺選擇仿真器,具體型號查看仿真器型號:本實驗使用HPUSB-ICE仿真器30步驟4:調試(5/10)—配置自動斷點31步驟4:調試(6/10)—用戶板卡配置32步驟4:調試(7/10)—多處理器配置33步驟4:調試(8/10)—配置載入程序34步驟4:調試(9/10)—切換視圖Debug視圖(customperspective)35步驟4:調試(10/10)—變量、內存、寄存器監(jiān)測可查看變量、內存、寄存器36步驟4:導入已有工程(1/3)—點擊Import37步驟4:導入已有工程(2/3)—選擇ExistingProject38步驟4:導入已有工程(3/3)—導入項目文件39步驟5:關閉與刪除工程(1/3)—關閉工程CloseNon-currentproject40步驟5:關閉與刪除工程(2/3)—刪除工程41步驟5:關閉與刪除工程(3/3)—是否從磁盤刪除工程42C/C++編譯器CCES使用ccblkfn編譯器,此C/C++編譯器有如下功能:處理C和C++源文件,產生機器級源代碼和目標文件。在目標文件中包含可重定位的代碼和調試信息。在處理器存儲區(qū)中提供可由鏈接器替換的可重定位數據和程序存儲段。

C/C++編譯器處理C和C++語言源文件并生成Blackfin匯編源文件。匯編源文件由BlackfinDSP系列匯編器(easmblkfn.exe)匯編產生。匯編器進一步產生ELF(ExecutableandLinkableFormat)目標文件,由它可以鏈接(使用鏈接器)產生一個BlackfinDSP可執(zhí)行文件或將其包含在一個檔案文件庫(elfar.exe)中。編譯器如何控制處理過程的匯編,鏈接和存檔階段取決于輸入源文件和所用的編譯器選項。2.嵌入式C編程43BlackfinC/C++編譯器支持的數據類型類型位大小數學表示方式使用sizeof()返回值char8位有符號8位二進制補碼1unsignedchar8位無符號8位無符號量1short16位有符號16位二進制補碼2unsignedshort16位無符號16位無符號量2int32位有符號32位二進制補碼4unsignedint32位無符號32位無符號量4long32位有符號32位二進制補碼4unsignedlong32位無符號32位無符號量4指針32位32位二進制補碼4函數指針32位32位二進制補碼4float32位32位IEEE單精度4double64位64位IEEE雙精度8fract1616位有符號1.15小數形式2fract3232位有符號1.31小數形式444注意:Blackfin定點處理器只支持定點運算,寬度最高32位,所以浮點數據及64位數據不直接支持,需通過軟件轉換來實現轉換,速度會降低很多。分數形式的數據類型fract16和fract32并不是實際存在的數據類型,事實上就是以short和int形式存儲,即1.15的16位有符號short整型(定點型),1.31的32位有符號int整型(定點型),用于表示有符號小數。typedefshortfract16;

typedefintfract32;使用該數據類型時需要先#include<fract.h>45邏輯操作符與位操作符邏輯操作符——與(&&)、或(||)、非(!)對操作數執(zhí)行邏輯操作,主要用于if等判斷語句中。例如:if(x<SCR_XSIZE&&SCR_YSIZE)位操作符——與(&)、或(|)、求反(~)、異或(^)、左移(<<)、右移(>>)&位與——清除某個位或某些位例:#definepLCDCON(volatileunsignedint*)0x1F00000*pLCDCON&=0xfffffffe;//清除LCD控制寄存器的最低位來關閉LCD|位或——設置某個位或某些位例:*pLCDCON|=0x1;//設置LCD控制寄存器的最低位來打開LCD^位異或——將某個位或某些位取反46<<左移——設置寄存器的位或乘以2n

例:*pLCDCON=0x6<<6;//設置LCDCON寄存器的第8位、第9位為1。(Binary:110000000)>>右移——實現除法(除以2n

)如果除數是2的n次方,編譯器就會調用移位操作來完成除法運算(無符號除法比有符合除法的效率高)。~求反——將每一位取反。47Volatile的用法編譯器有一種技術叫數據流分析,分析程序中的變量在哪里賦值、哪里使用、哪里失效,分析結果可以用于常量合并,常量傳播等優(yōu)化。當它覺察到代碼沒有修改變量的值時,就可能在訪問變量時提供上次訪問的緩沖值,這能夠提高程序的效率。但這些優(yōu)化可能會帶來問題(特別是對硬件寄存器操作的程序中),這時需要用volatile關鍵詞來禁止做這些優(yōu)化?!嬖V編譯器:變量已經變化,不要用緩存值(變量可能會隨時改變,不要對其優(yōu)化,而是每次用的時候去讀寫該變量。)48使用volatile變量的場合硬件寄存器通常要加volatile說明。#definepFlashA_PortA_Dir(volatileunsignedchar*)0x20270006在中斷服務程序中修改的供其它程序檢測的變量需要加volatile。例:中斷服務程序常常通過改變一些全局變量來通知應用程序某個外部事件已經發(fā)生,這些全局變量不應該被優(yōu)化。多任務環(huán)境中各任務間共享的標志應該加volatile。49C/C++編譯語言擴展

編譯器支持對ISO/ANSI標準的C語言和C++語言的擴展。為了使C/C++擴展中附加關鍵字與ISO/ANSI標準C/C++的關鍵字不沖突,C/C++擴展中附加關鍵字在形式上均以雙下劃線“__”打頭。標準C/C++關鍵字用一個下劃線“_”打頭,編譯器擴展C/C++關鍵字用兩個下劃線“__”打頭;標準庫函數名用一個下劃線“_”打頭,編譯器擴展的庫函數(由編譯器給出的內嵌函數)名用兩個下劃線“__”打頭。50內聯函數關鍵字(inline),ccblkfn的inline關鍵字使聲明為inline類型的函數代碼內嵌到調用它的地方。inline是C++的標準特點,ccblkfn將它作為C的擴展。使用該選項節(jié)省了調用函數的額外時間開銷,因此提高了程序執(zhí)行速度。內聯匯編語言關鍵字(asm),ccblkfn的asm()結構可在C/C++函數中內嵌BlackfinDSP匯編語言指令。對程序中用C或C++不易或不能高效實現的地方可以用asm()結構利用匯編語言實現。51指定要放置數據的存儲器位置的關鍵字(section),section關鍵字使編譯器在匯編器的交叉輸出文件的.SECTION中放置目標或函數代碼??梢杂胹ection()中的字符串參數命名.SECTION。如果對目標或函數聲明沒有指定section(),編譯器會使用默認值。例如:section(“buffer”)intin[1024]={#include“sine.dat”};指針受限關鍵字(restrict),restrict關鍵字支持受限制的指針特性。restrict的使用局限于聲明一個指針,并指明指針是訪問它所指向內容的惟一途徑。簡單來說,restrict使指針不能使用別名,即兩個不同受限指針不能指向同一個對象(指針不能有別名)。52內置函數(buildin),編譯器支持使用內置函數,從而有效利用硬件資源。有關這些函數的信息已經內嵌在編譯器中。用戶程序使用正常的函數調用句法調用它們。編譯器處理此類函數調用,會生成一條或多條機器指令,就像處理正常的操作符(如+和*)那樣。內置函數名是以__builtin_開始的。頭文件為內置函數定義一個可讀性更好的名稱,這個名稱不使用__builtin_前綴。例如在ccblkfn.h中:

#definesysreg_write(A,B)__builtin_sysreg_write(A,B)53預處理命令預處理器在編譯器之前運行,它在編譯之前對等待處理的代碼進行預處理。預處理器指令以“#”開始,以回車符結束(不能有“;”號),如何預處理器指令長于一行,用“\”續(xù)行。預處理器指令對大小寫敏感,必須用小寫。預處理命令的功能如下包含系統和用戶定義頭文件,例如#include定義宏和標志常量,例如#define提供條件匯編和編譯,例如#ifdef、#ifndef、#if(均以#endif結束)54#if和#endif

條件編譯指令,例如:#defineLCD_TYPEMLCD_320_240#if(LCD_TYPE==MLCD_320_240)#defineSCR_XSIZE(640)#defineSCR_XSIZE(480)#defineLCD_XSIZE(320)#defineLCD_XSIZE(240)#if(LCD_TYPE==CLCD_240_320)#defineSCR_XSIZE(640)#defineSCR_XSIZE(480)#defineLCD_XSIZE(240)#defineLCD_XSIZE(320)#endif技巧:在程序調試中,可以用#if臨時注釋掉一段代碼,如下所示:#if0…#endif當需要這段代碼時,只需將0變?yōu)?即可。55系統庫函數(內置函數)編譯器內置函數(CompilerBuiltinFunction),主要針對一些常用的操作,其實現大多與處理器硬件電路有關。內置函數一般采用匯編語言編寫,一旦用戶調用此函數,編譯器直接映射到相應的匯編代碼中(會被編譯器識別出來,使用固定的匯編語句來代替庫函數的調用),運行效率很高。有一些內置函數是系統管理函數,這些內置函數將系統管理的各項操作封裝成函數,直接調用這些內置函數將能提高代碼的可讀性。例如:獲取系統時鐘周期的函數示例如下//使用內聯匯編程序,程序可讀性差//使用ADI提供的內置函數,可讀性好unsignedintget_cycles(void){unsignedintret_val;asm(“%0=CYCLES;”:”=d”.(ret_val)::);returnret_val;}#include<ccblkfn.h>#include<sysreg.h>unsignedintget_cycles(void){returnsysreg_read(reg_CYCLES);}Clevelfunctionswithseveralassemblyinstructionsandexpandedintocompilerintermediateinstruction56系統庫函數內部函數通常支持16位或32位數的操作包括libc、libdsp、libetsi、libio、lwip、libbtc等庫,支持如下的操作和函數:小數值內部函數ETSI(歐洲電信標準協會)標準的支持復數小數數據和操作Viterbi編碼和解碼函數循環(huán)緩沖區(qū)函數高低字節(jié)交換(Endian-swapping)函數系統內部函數視頻操作函數未對齊的數據函數內部函數支持防止溢出的飽和算法,這一點與標準C程序不同。庫文件位置:安裝目錄\Blackfin\lib\頭文件位置:安裝目錄\Blackfin\includes\源代碼位置:安裝目錄\Blackfin\lib\src\可根據需要對源代碼進行修改,請將文件復制到其它地方,重命名后再進行修改。調用庫文件時需要先引用相應的頭文件。57示例:完成一個256階的FIR濾波器:

#include<fract.h>fract32filter(fract16*in,fract16*coeff){inti;fract32acc=0;for(i=0;i<128;i++){acc=add_fr1x32(acc,mult_fr1x32(in[i],coeff[i]));}returnacc;}intfilter(short*in,short*coeff){inti;intacc=0;for(i=0;i<128;i++){acc+=((in[i]*coeff[i])>>15);}returnacc;}58ETSIBuiltins–fullyoptimisedFractional

arithmetictoastandardspecificationEuropeanTelecommunicationsStandardsInstitute'sfractfunctionscarefullymappedontothecompilerbuilt-ins.頭文件libetsi.h包含了ETSI內部函數,ETSI函數與小數值內部函數類似,可以完成16位和32位小數值算術運算。還包含復數小數運算。add() sub()abs_s()shl()shr() mult()mult_r()negate()round() L_add()L_sub()L_abs()L_negate()L_shl()L_shr()L_mult()L_mac() L_msu()saturate()extract_h()extract_l() L_deposit_l()L_deposit_h()div_s()norm_s() norm_l()L_Extract()L_Comp()Mpy_32() Mpy_32_16()使用時需包含:#include<libetsi.h>,且需要將libetsi.dlb庫加入到工程中Highlyrecommended!59C/C++Run-time環(huán)境運行時環(huán)境是為了使應用程序能夠正常運行需要維護的一套環(huán)境。例如,系統復位跳轉到開始地址后要執(zhí)行的代碼,這些代碼(即C/C++Run-timeheaders,又稱CRT)需要將寄存器的值由未知狀態(tài)設置為已知狀態(tài),完成用于維護工作環(huán)境的操作。運行時環(huán)境還包括C/C++語言中的函數調用約定。在運行時環(huán)境中,有一部分是約定好了的,由編譯器自己自動完成;另有一部分是需要編寫代碼實現的,如重啟時的CRT代碼。ADI提供了默認的CRT文件,即安裝目錄下Blackfin\lib\src\libc\crt中的basiccrt.s文件。60C/C++Run-timeLibraryC/C++Run-timeLibrary是實現運行時環(huán)境時可能被代碼使用的函數、宏定義、類模板的集合。這個庫提供了對語言而講最基本的應用:分配內存、字符、字符串的轉換、數學計算等。頭文件位置:安裝目錄\Blackfin\includes\源代碼位置:安裝目錄\Blackfin\lib\src\libc\函數名是基于C/C++語言的,如需要在匯編語言里調用它們,需要使用這些函數的匯編版本的名稱(一般后綴帶_s,例如write_s.asm)。61C/C++Run-timeLibrary提供的常用庫函數ccblkfn.h

與Blackfin系列DSP系統功能相關的函數。ctype.h

針對字符處理的函數,包括isdigit,islower,toupper等等math.h

數學運算函數(乘方、三角函數、對數、指數等)signal.h

標準ANSI中的信號相關功能的函數,主要用于處理C程序中的外部中斷信號或定時器中斷信號,包括raise(建立和強制使能低優(yōu)先級的中斷)、signal、interruptstdio.h

輸入、輸出操作(會受到中斷干擾,不能在中斷服務程序中調用這些函數),包括:fwrite、fclose、printf等stdlib.h

提供C語言標準中通用的功能,像定點算術功能(abs、div、rand)、通用字符串至數字的轉換、存儲器內存空間管理(malloc、free)之類string.h

處理字符串的函數,例如strcpy、strcmp、memcpy等time.h

與時間相關的數據類型、宏,以及與表達式相關的用于時間計算的信息,如clock、asctime、ctime等62C/C++Run-timeLibrary提供的常用庫函數float.h

浮點數據的處理limits.h

定義Cdatatype的最大、最小值等等iso646.h

布爾運算device.h

交互設備驅動程序的宏和數據結構device_int.h

交互設備驅動的列舉和原型errno.h

錯誤處理…63DSPRun-timeLibrary(libdsp)支持很多通用的DSP算法,例如濾波、FFT、矢量和矩陣函數、數學函數、窗函數等。這些DSP函數支持不同的數據類型,包括float、double、fract16等。庫文件位置:安裝目錄\Blackfin\lib\頭文件位置:安裝目錄\Blackfin\includes\源代碼位置:安裝目錄\Blackfin\lib\src\libdsp\可根據需要對源代碼進行修改,請將文件復制到其它地方,重命名后再進行修改。調用庫文件時需要先引用相應的頭文件。64Libdsp提供的庫函數comples.h

基本復數運算。包含各類復數類型(如complex_float、complex_fract16)變量的定義和基本數學操作,例如復數絕對值、復數加減法、復數乘除法、獲取復數相位、共軛、歸一化等filter.h

濾波和變換濾波包括FIR、IIR、直接I型IIR、抽取/內插FIR、復數FIR等等變換FFT、獲得FFT旋轉因子、IFFT、R4-FFT等卷積卷積操作、二維卷積、3*3矩陣的二維卷積等壓縮/擴展的相關函數包括A律、u律壓縮/擴展math.h

數學函數,例如求絕對值、指數、對數、冪運算、三角運算、最大值、最小值、平方根等。matrix.h

矩陣函數,如實數/復數矩陣加/減/乘一個標量、矩陣轉置等stats.h

統計函數。包括自相關、互相關、柱狀圖、均值、方差、過零點等vector.h

向量函數,包含實數與復數的向量操作,例如點積、向量加/減/乘一個標量、向量中的最大、最小元素及各自的索引等。window.h

濾波、譜分析加窗時的窗函數。包括Gaussian窗、Hamming窗、Kaiser窗、三角窗等。65數字濾波的實現濾波及頻譜分析可以采用ADI提供的濾波器庫函數(DSPrun-timelibrary中的庫函數),需要包含filter.h(濾波器及變換的頭文件),即#include<filter.h>。濾波器初始化fir_init(state,coefs,delay,NUM_TAPS,1);其中state為初始狀態(tài),coefs為濾波器系數,delay為線性緩沖區(qū)的首地址,NUM_TAPS為濾波器階數,最后一個參數表示是否內插或抽取(interpolation/decimationindex)事實上,fir_init就是一個宏,即:#definefir_init(state,coeffs,delay,ncoeffs,index)\(state).h=(coeffs);\(state).d=(delay);\(state).p=(delay);\(state).k=(ncoeffs);\(state).l=(index)66對輸入信號進行濾波fir_fr16(in,out,VEC_SIZE,&state);其中in為輸入信號緩沖區(qū)的首地址,out為輸出信號緩沖區(qū)的首地址,VEC_SIZE為每次參與濾波的數據的長度(緩沖區(qū)的長度),&state表示初始狀態(tài),由fir_init(state,coefs,delay,NUM_TAPS,1);獲得。源代碼可以在:安裝目錄下\Blackfin\lib\src\libdsp\找到fir_fr16.asm67輸入信號產生與引入在進行設計時輸入的信號可以事先由Matlab編程獲得fid=fopen('signal.dat','w');fprintf(fid,'0x%04x,\n',x1);fclose(fid);使用時在DSP程序中采用fract16in[256]={#include“signal.dat”};也可以在DSP程序中編程得到信號#include<math.h>#include<math_const.h>*out=(fract16)(0.5*sin(2*PI*f*step)*32768.0);加噪聲#include<stdlib.h>*out+=(fract16)((rand()-0x20000000)>>15;68設備驅動庫函數drivers\adi_dev.hdrivers\adi_uart.hservices\services.h69采用設備驅動這種方式,使應用程序不用考慮控制硬件設備的細節(jié),對應用程序而言,設備的控制與正常的調用函數沒有什么不同。設備驅動程序位于系統服務程序的上方,設備驅動程序將調用系統服務程序,如中斷。設備驅動庫是ADI提供的部分器件的設備驅動程序集合。如果在系統中使用的是設備驅動庫中的設備,則對BlackfinDSP來說直接調用設備驅動庫中相應的文件和函數即可;如果使用的設備不在設備驅動庫中,也可以參照ADI的同類型器件的設備驅動程序來編寫所用設備的驅動程序。使用時需要包含:#include<services\services.h>//系統服務程序#include<drivers\adi_dev.h>//設備管理器#include<drivers\adi_uart.h>//UART驅動程序70

#include<services\services.h>//系統服務程序包括了所有的系統服務程序,如DMA、中斷、接口控制等服務程序#include<drivers\adi_dev.h>//設備管理器包括了所有關于設備驅動程序的一般信息,如API、返回碼、事件代碼即所有的設備驅動程序一般信息#include<drivers\adi_xxx.h>//xxx設備的驅動程序特定的設備的驅動程序的包含文件,應當包含設備驅動程序本身。相關文件所在位置如下:頭文件在安裝目錄下Blackfin\include\drivers或services文件夾中各個驅動程序的源代碼在安裝目錄下Blackfin\lib\src\drivers或services文件夾中庫文件在安裝目錄下Blackfin\lib文件夾中71設備管理adi_dev.hadi_dev_Open()–Opensadeviceforuseadi_dev_Close()–Closesdownadeviceadi_dev_Read()–Providesadevicewithbuffersforinbounddataadi_dev_Write()–Providesadevicewithbuffersforoutbounddataadi_dev_Control()–Sets/detectscontrolandstatusparametersforadevice72系統服務:SystemInterruptControllerFunctions

adi_int_SICEnable–EnablesperipheralinterruptstobepassedtotheCECadi_int_SICDisable–DisablesperipheralinterruptsfrombeingpassedtotheCECadi_int_SICSetIVG–SetstheIVGleveltowhichaperipheralinterruptismappedadi_int_SICGetIVG–DetectstheIVGleveltowhichaperipheralinterruptismappedadi_int_SICWakeup–Establisheswhetherornotaperipheralinterruptwakesuptheprocessorfromanidledstateadi_int_SICInterruptAsserted()–Detectswhetherornotaperipheralinterruptisasserted.73C與匯編混合編程用C語言編程結構化程度高,易于編寫,但執(zhí)行速度相對較慢;與之相反,匯編程序速度

溫馨提示

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

最新文檔

評論

0/150

提交評論