在基于DSP的系統設計中,為了保證掉電時程序不丟失,總是將程序保存在非易失性存儲器中,以便系統在上電復位時可將其引導到DSP內部的RAM中執行。以TI公司的TMS320C6713浮點DSP和AMD公司的AM29LV040Flash存儲器為例,通過JTAG加載來設計一個完整的自舉引導方案。著重描述了引導引腳以及相關寄存器的設置,分析了采用EDMA傳輸方式將代碼從Flash復制到DSP的過程,并對引導程序給出基于匯編語言的代碼實現。工程實踐證明,該設計方案是可行、有效的。 在許多基于DSP的系統設計中,程序代碼總是保存在ROM、Flash或其他非易失存儲器中,以保證掉電時代碼仍存在,因此必須要解決引導裝載的問題。自舉引導(Bootload)是指系統上電時,DSP將一段存儲在外部非易失性存儲器的代碼搬移到內部的高速存儲器單元中執行(如片內RAM)。本文以TI 公司的TMS320C6713(以下簡稱為C6713)浮點DSP和AMD公司的AM29LV040Flash存儲器為例,通過JTAG口加載來設計一個完整的引導裝載方案。 TMS320C6713的引導配置 外部信號BOOTMODE[4:3]決定了C6713的引導配置,在RESET信號的上升沿BOOTMODE[4:3]信號被獲取。C6713DSP只有2種引導方式: (1)ROM/Flash引導。外部存儲器的一部分通過EDMA控制器拷貝到DSP內部地址0處。盡管引導程序在器件從外部復位釋放后才開始執行,但在 CPU被保持在內部復位時,這個拷貝就進行了。Flash寬度也通過BOOTMODE[4:3]選擇。在Flash寬度小于32bit的情況下,DSP通過EMIF讀取時,可以自動將相鄰的8bit字節或16bit半字打包形成32bit的指令字,并且這些數值在外部存儲器中可以通過設定HD8來確定 endian存儲模式。 (2)主機引導。核心CPU停留在復位狀態,器件其余部分保持正常狀態。外部主機通過HPI或擴展總線初始化CPU的存儲空間。在必要的初始化完成之后,主機在HPI控制寄存器的DSPINT位寫1,這個寫操作引起DSPINT信號的跳變,從而導致引導配置邏輯使CPU脫離復位狀態,然后CPU從地址0處開始運行。 Flash引導模式的實現 硬件設計 C6713引導引腳說明如表1所列。 設計時將DSP主機口引腳HD[4:3]中的HD4通過下拉電阻接地,HD3通過上拉電阻接3.3V電源,即HD[4:3]=01B。C6713的 EMIF含有4個CE空間寄存器,由于Flash加載程序是從CE1空間搬入的,因此DSP的CE1與Flash(AM29LV040)的片選相連,這種連接將Flash的內部地址映射到DSP的0x90000000處,從而完成了基本的硬件設計。DSP與Flash接口的硬件連接如圖1所示。 圖1 DSP與Flash的引腳連接 引導程序的設計 Flash存儲器的擦除 在對AM29LV040Flash進行讀寫操作之前,應對其進行擦除,擦除操作需要6個總線周期: (1)向555H地址的存儲單元寫入數據AAH; (2)向2AAH地址的存儲單元寫入數據55H; (3)向555H地址的存儲單元寫入數據80H; (4)向555H地址的存儲單元寫入數據AAH; (5)向2AAH地址的存儲單元寫入數據55H; (6)向555H地址的存儲單元寫入數據10H; 完成上述操作后,Flash存儲器完全擦除。 在CCS環境下,用C語言編寫上述操作如下: voidFlash_Erase() { *(char*)FLASH_ADR1=0xAA; *(char*)FLASH_ADR2=0x55; *(char*)FLASH_ADR1=0x80; *(char*)FLASH_ADR1=0xAA; *(char*)FLASH_ADR2=0x55; *(char*)FLASH_ADR1=0x10; } 根據前面的設計,Flash的內部地址已經映射到C6713的CE1空間,其開始地址為0x90000000。因此FLASH_ADR1,FLASH_ADR2的定義如下: #define FLASH_ADR1 0x90000555 #define FLASH_ADR2 0x900002AA 匯編源代碼文件 對于C6713而言,DSP上電復位后,EDMA自動從CE1空間拷貝1KB數據(引導代碼應定位與此)到地址0處,然后從0地址處開始執行引導代碼指令。本引導代碼的主要功能是將用戶程序段從Flash復制到DSP內部RAM中,然后再跳轉到程序的入口處開始執行主程序。在引導程序內復制程序段要使用 EDMA,以快速、靈活地實現DSP存儲空間內數據的搬移。數據搬移的源/目的可以是片內存儲器、片內外設或外部器件。而此時需要對EDMA的源、目的地址、搬移長度以及基本的傳輸方式進行相關的設置,如表2所示,然后運用匯編語言編程加入到引導程序即可。 核心引導程序如下: .sect“.BootCode” ;將引導代碼分配到BootCode段中 .global myBootCode .ref_c_int00 ;C程序的入口地址 MVKL .S1EDMA0_OPT ,A5 MVKL . S10x50010001 ,B4 ;低16bit寫入寄存器 MVKH .S1EDMA0_OPT ,A5 MVKH .S10x50010001 ,B4 ;高16bit寫入寄存器 STW .D1B4,*A5 ;裝載EDMA的OPT參數 MVKL .S1EDMA0_SRA ,A5 MVKL .S10x90001000 ,B4 ;低16bit寫入寄存器 MVKH .S1EDMA0_SRA ,A5 MVKH .S10x90001000 ,B4 ;高16bit寫入寄存器 STW.D1B4,*A5 ;裝載EDMA的SRC參數 .... .... 接下來啟動EDMA復制主程序段:CPU可以通過寫事件置位寄存器(ESR)啟動一個EDMA通道。 ESR中某一位寫1時,將強行觸發對應的事件。程序如下: MVKL .S10x00000001, B4 MVKL .S1EDMA_ESR, A5 ;低16bit寫入寄存器 MVKH .S1EDMA_ESR, A5 MVKH .S10x00000001, B4 ;高16bit寫入寄存器 STW .D1 B4, *A5 ;將ESR第一位置1 NOP5 傳輸 結束后,跳轉到C程序的入口地址 _c_int00處,開始執行主程序: MVKL .S2_c_int00, B0 MVKH .S2_c_int00, B0 B.S2B0 NOP5 鏈接命令文件 鏈接命令文件是DSP開發過程中生成可執行文件(.out)必不可少的一個環節。它對段的功能有2 個,一是將由匯編器產生的COFF格式的OBJ文件作為輸入塊,當有多個文件進行鏈接時,將相應的段結合在一起生成可執行輸出模塊;二是重新定位,將輸出的段分配到存儲器中的指定地址。 編寫命令文件時,有時希望將代碼裝入存儲器的一個地方,而在另一個地方運行。例如:一些關鍵的執行代碼必須裝在系統的ROM中,但希望在較快的RAM中運行。鏈接器提供了一個處理該問題的簡單方法。利用SECTIONS偽指令選項可讓鏈接器定位2次。第一次使用裝載關鍵字load設置裝入地址,再使用運行關鍵字run設置它的運行地址。裝載地址確定段的原始數據或代碼裝入的地方,而任何對段的引用則參考它的運行地址。在應用中必須將該段從裝載地址復制到運行地址,本引導程序便使用EDMA方式完成這一復制過程。鏈接命令文件(boot.cmd)如下: MEMORY { VEC:ORG=0x00000000,LEN=0x00001000 PMEM:ORG=0x00001000,LEN=0x00004000 CEVEC:ORG=0x90000000,LEN=0x00001000 CEPMEM:ORG=0x90001000,LEN=0x00004000 } 以上設置是將整個存儲器分成具有不同名稱的存儲區域。VEC,PMEM代表內部RAM的兩塊存儲空間,而CEVEC,CEPMEM代表Flash內的兩塊存儲空間。對目標文件中各段的加載地址和運行地址在SECTIONS段實現。 SECTIONS { .BootCode:load=CEVEC;用戶的引導代碼段定位在Flash的最開始。 .text:load=CEPMEM,run=PMEM;用戶程序段裝載于 Flash空間,而運行在C6713內部RAM中。 } 通過JTAG口的Flash在線燒寫 用匯編語言編寫一個搬移程序,內容僅是Flash的擦除過程,以及對EDMA的多次操作構成的由片內RAM到片外Flash的寫入過程。把該搬移程序直接嵌入主程序中,這樣程序代碼長度很短,不會占用過多的主程序空間。在主機引導方式下,通過JTAG口load后,手工更改PC值使其指向這段代碼,控制其運行結束,完成自舉程序的在線燒寫。而在此之后,這段短小的搬移程序不會被主程序中任何一段代碼所調用。 結束語 工程實際應用表明該方法是切實可行的,與以往Flash引導程序編寫方法相比避免了目標代碼的格式轉換,利用EDMA直接搬移,無需編程器,Flash也不需頻繁拆卸,利于工程上的快速開發。 |