TMS320C6000 DSP自動引導的方法和編程
1 TMS320C6000 DSP硬件結構概述
?。裕停樱常玻埃茫叮埃埃笆牵裕晒旧a(chǎn)的TMS320系列產(chǎn)品中新一代高性能的DSP芯片,適用于高速數(shù)字信號處理。TMS320C6000主要由三個部分組成:CPU內(nèi)核、外設和存儲器。CPU中8個功能單元可以并行工作,這些功能單元被分成類似的兩組,每組由4個基本功能單元組成。CPU有兩組寄存器,每組寄存器由16個32位寄存器組成。由于在運行期間不做硬件數(shù)據(jù)相關性檢查,所以程序運行時可以同時執(zhí)行8條指令,極大地提高了芯片處理速度,這使得該系列的芯片在電子測量、測控、圖像、雷達、聲納和軟件無線電等領域得到了廣泛的應用。
?。?加電后DSP的運行過程
系統(tǒng)加電后,RESET信號為低,芯片復位。在RESET信號上升沿處,鎖存BOOTMODE[4:0]信號,借以決定芯片的存儲器映射方式、地址0處的存儲器類型以及復位后芯片的自舉模式,復位結束后,芯片從存儲器的0地址開始執(zhí)行指令。 TMS320C6000器件可以設置成三種自舉方式,其加載過程分別敘述如下: (1)不加載。CPU直接從存儲器的0地址處開始執(zhí)行指令。如果系統(tǒng)中使用的是SDRAM,那么CPU會先掛起,直到SDRAM的初始化完成。TMS320C621X/C671X不具有這類方式。 (2)ROM加載。位于外部空間的ROM中的程序首先通過DMA/EDMA搬入地址0處。盡管加載過程是在芯片外部被復位信號釋放以后才開始的,但是當芯片仍處于內(nèi)部復位保持時,就開始了上述的傳輸過程了。用戶可以指定外部ROM的存儲寬度,EMIF會自動將相鄰的8bit/16bit數(shù)據(jù)合并成32bit。ROM中的程序必須以little endian的格式存儲。用DMA/EDMA進行的這一加載過程是一個單幀的數(shù)據(jù)塊傳輸。傳輸過程完成之后,CPU退出復位狀態(tài),開始執(zhí)行地址0處的指令。對于不同的芯片,這一過程略有不同,整個過程如圖1所示。 對于TMS320C620X/C670X,DMA使用默認的ROM時序從CE1空間中拷貝64KB數(shù)據(jù)到地址0處。 對于TMS320C621X/C671X/C64X,EDMA使用默認的ROM時序從CE1空間(C64X從EMIFB CE1空間)拷貝1KB數(shù)據(jù)到地址0處。 (3)主機(HPI)引導。CPU停留在保持狀態(tài),其余硬件部分均保持正常狀態(tài)。在這期間,外部主機通過主機口初始化CPU的存儲空間。主機完成所有的初始化工作后,將主機口控制寄存器中的DSPINT位設置為1,結束引導過程。此時CPU退出復位狀態(tài),開始執(zhí)行地址0處的指令。在主機引導過程中,主機可以對DSP所有的存儲空間進行讀和寫。 此外,用戶應選擇存儲器的映射方式(當有多種映射方式可供選擇時)和首地址為0存儲空間的類型。TMS320C6201/C6701芯片有專門的BOOTMODE管腳決定芯片的各種設置。TMS320C6202則通過將擴展總線上的XD[4:0]直接映射為BOOTMODE40確定芯片的設置,這些管腳可通過電阻上拉或下拉設置引導方式和存儲器映射方式。TMS320C6211/C6711僅有一種存儲器映射方式,引導方式只需要兩位進行設置,主機口的HD[4:3}映射為BOOTMODE[4:0]同樣是利用電阻上拉或下拉設置引導方式實現(xiàn)的。 圖2 代碼生成流程圖
?。?ROM引導模式實現(xiàn)
在許多基于TMS320C6000 DSP的應用程序的開發(fā)中,程序代碼或數(shù)據(jù)表總是保存在ROM、 FLASH或其它非易失存儲器中,以保證掉電時代碼仍在。但這些存儲器的速度很慢,對速度性能要求很嚴格的代碼就需要運行到其它快速存儲器中,如片內(nèi)RAM或片外靜態(tài)RAM。這就需要在運行前將代碼從ROM存儲器中裝載到RAM中,這是開發(fā)人員遇到的難點之一。從ROM引導的應用程序的開發(fā)過程分以下幾個步驟:
在CCS環(huán)境中,調(diào)試程序,編寫相應的命令文件(.cmd),編譯連接以形成.hex(COFF格式)文件,通過編程器轉化成.bin文件(二進制文件),燒到ROM中;
系統(tǒng)加電復位,芯片從ROM中拷貝固定長度的數(shù)據(jù)塊(其中包括用戶自身的引導代碼)到RAM中,用以初始化部分存儲器;
執(zhí)行用戶的引導代碼和其它數(shù)據(jù)段以及程序段初始化所必需的段復制; %26;#183;使用包含.cinit段中的數(shù)據(jù)初始化.bss段中C語言變量;
程序從main()處開始執(zhí)行。 在開發(fā)從ROM引導的應用程序時,必須考慮以下幾點:用戶引導代碼必須連接到應用程序中,這樣在系統(tǒng)加電復位后,用戶的引導程序才能被合適地加載和執(zhí)行;只有通過編寫自己的引導代碼用戶才能正確地從ROM中拷貝COFF格式的段;在程序連接時,只有通過合理編寫命令文件(.cmd),使這些段被合理地連接后,才能實現(xiàn)從ROM中加載,從DSP內(nèi)部RAM中執(zhí)行。在這個過程中,命令文件和用戶引導代碼編寫對于程序能否正確地執(zhí)行起著非常重要的作用。在某軟件無線電工程的開發(fā)中,筆者就是在C語言環(huán)境下,成功地開發(fā)了TMS320C6701的自引導程序。下面就針對這兩個方面加以詳細說明,以供大家借鑒。
?。常?命令文件
利用TI的代碼產(chǎn)生工具,可以按照圖2所示的步驟生成可執(zhí)行文件(.out)。 匯編器接收匯編優(yōu)化器或編譯器產(chǎn)生的.asm文件,經(jīng)過匯編后產(chǎn)生可重新分配地址的COFF格式的目標文件.obj。該格式文件包含了匯編器所生成的各個段(如表1所示),命令文件就是指導連接器如何將各段分配到相應的存儲器中。編寫命令文件時,有一點需要注意,那就是在很多情況下需要對某段說明兩個不同的地址:加載地址和運行地址。加載地址決定了二進制程序代碼的存儲位置和程序的引導地址,但在運行過程中對于該段的任何引用則是以它的運行地址作為參考的。因此,當用戶對某段分別說明了加載地址和運行地址時,只有將該段從加載地址復制到運行地址上,該段才可以被訪問。 表1 編譯器產(chǎn)生的默認代碼段和數(shù)據(jù)段 段 名段數(shù)據(jù)段說明建議分配方法 .text 代碼段程序代碼 Load=ROM,Run=RAM .switch 初始化數(shù)據(jù)段 Switch語句跳轉表 Load=ROM,Run=RAM .bss,.far 未初始化數(shù)據(jù)段 c變.運行時從.cinit中自動初始化 Load=Run=RAM .cinit,.pinit 初始化數(shù)據(jù)段 C變量和函數(shù)初始化表 Load=Run=ROM .const 初始化數(shù)據(jù)段常量 Load=Run=ROM .data,.cio,.sysmem 未初始數(shù)據(jù)段其它的.data段 Load=Run=RAM 在命令文件中,合理地分配.cinit段對于整個程序的正確運行起到關鍵的作用。在TI可查閱的文檔和相關網(wǎng)站上,很少有涉及這方面內(nèi)容的文章。經(jīng)過反復實踐,筆者取得了處理.cinit段的一些經(jīng)驗,請大家在下面的命令文件和用戶引導程序中注意該段的處理過程。 下面是在實踐中編寫的命令文件(.cmd) -c ;說明復位后的初始化方式 -stack 0x5000 ;說明堆的大小 -heap 0x400 ;說明棧的大小 -l rts6701.lib ;說明程序中引用的庫文件 MEMORY ;將整個存儲器分成具有不同名稱的存儲區(qū)域 { VECS: origin = 0x00000000, len = 0x00000200 PMEM: origin = 0x00000200, len = 0x0000d000 PCINIT: origin = 0x0000d200, len = 0x00001e00 CE1VECS: origin=0x01400000, len = 0x00000200 CE1PMEM:origin = 0x01400200, len = 0x0000d000 CE1INIT: origin = 0x0140d200, len = 0x00001e00 CE3: origin = 0x03000000, len = 0x01000000 DRAM: origin = 0x80000000, len = 0x00010000 } SECTIONS ;說明目標文件中各段的加載地址和運行地址 { .myBootCode :load=CE1VECS, run=VECS ;用戶的引導代碼段 .text : load=CE1PMEM, run=PMEM .cinit : load=CE1INIT, run=DRAM ;裝載到ROM中,在片內(nèi)數(shù)據(jù)區(qū)運行 .const > DRAM .data > DRAM .bss > DRAM .sysmem > DRAM .stack > DRAM .far > CE3 }
?。常?編寫用戶引導代碼
?。模樱屑与姀臀缓?,自動從CE1空間中拷貝64K數(shù)據(jù)(程序代碼)到地址0處,然后從0地址處開始執(zhí)行指令。由于在命令文件中,將.cinit裝載到外部ROM中,但其運行地址卻在片內(nèi)數(shù)據(jù)區(qū),所以采用下面這段程序,其主要作用是將Cinit從外部ROM中搬到片內(nèi)數(shù)據(jù)區(qū),使其能在C編程環(huán)境下進行正確的初始化工作,保證程序的順利進行。 .sect “.myBootCode” ;將用戶引導代碼分配到 myBootCode段中 .global myBootCode .ref _c_int00 ;C程序的入口地址 myBootCode ...... ;EMIF寄存器和DMA寄存器初始化 ;使用DMA方式將以原地址0x0000d200開始的0x380長的存儲空間拷貝到目標地址上 mvkl DMA0_SRA ,A5 ;裝載原地址0xd200 mvkl 0x0000d200, B4 mvkh DMA0_SRA ,A5 mvkh 0x0000d200m B4 stw B4,*A5 mvkl DMA0_DSA, A5 ;裝載目標地址0x80000000 mvkl 0x80000000, A4 mvkh DMA0_DSA, A5 mvkh 0x80000000, A4 stw A4,*A5 mvkl DMA0_CNT A5 ;裝載數(shù)據(jù)長度0x380(這個長度可以通過查看.map文件中.cinit的長度獲得) mvkl 0x00000380, B1 mvkh DMA0_CNT ,A5 mvkh 0x00000380, B1 ;啟動DMA開始傳輸 wait: mvkl DMA0_PCR ,A5 mvkh DMA0_PCR ,A5 ldw *A5 ,B2 mvkl 0x0000000c,A5 mvkh 0x0000000c ,A5 and A5,B2,B2 b2 b wait nop 5 ;傳輸結束后,跳轉到C程序的入口地址c_int00處, 開始執(zhí)行程序 mvkl .s2 _c_int00B0 mvkh .s2 _c_int00B0 B .s2 B0 nop 5。
評論