摘 要:為解決特殊場合DSP程式更新困難的問題,以TMS320F28035為例,介紹了一種基于序列槽通信的适合于TMS320C2000系列DSP實作程式更新的線上更新方法。描述了該線上更新方法的基本思想和實作步驟,給出了關鍵部分的程式代碼。實驗證明,該方法簡單可靠,可用于嵌入式裝置軟體程式的更新更新中。
關鍵詞: 線上更新; DSP;序列槽通信; Flash
TMS320C2000系列DSP是美國德州儀器公司(簡稱TI)推出的集微控制器和高性能DSP特點于一身的DSP系列。該系列的DSP具有強大的控制信号處理能力[1],能夠實作複雜的控制算法。随着電子技術的不斷發展以及使用者需求的不斷提升,可能需要經常對已經投入使用的嵌入式裝置程式進行更新,而目前一般的程式更新方法是實地取下裝置,露出JTAG端口後通過仿真器來更新程式[2-4]。這種方法雖然簡單有效,但對于某些特殊場合,會給程式更新帶來了極大的不便[2]。本文以TMS320F28035為例,描述了一種可以脫離JTAG仿真器,不改變DSP上電啟動方式,實作TMS320C2000系列DSP應用程式線上更新的方法。
1 線上更新的基本思想
一般的基于DSP的軟體程式更新是在CCS環境下通過JTAG接口操作來實作的。基于JTAG接口的方法雖然易于操作,而且調試友善,但經常受空間以及傳輸距離的限制。例如一台DSP系統安裝在複雜、封閉的環境下,當程式需要更新或更新時,利用JTAG接口難以實作程式的線上更新[3]。而基于序列槽通信的線上更新技術是通過用底層程式燒寫應用程式的方法來達到程式更新的目的,該方法則不受複雜系統和複雜環境的限制。另外,線上更新方法不需要改變DSP的啟動方式,直接采用DSP預設的内部Flash方式啟動[5],進而省去了要對DSP的一些引腳進行硬體設定的麻煩。底層程式指已經固化在DSP指定Flash空間中的程式,不允許使用者修改和擦除,主要用于實作線上更新的時機判斷、資料接收及代碼燒寫等功能,該程式中使用了Flash2803x_API庫存函數(詳見2.2節);應用程式即為使用者的更新程式[3]。
F28035 DSP每次上電複位,先運作底層程式,與PC機建立聯系,然後根據PC機的指令來判斷是否需要更新應用程式。若需要,則将通過序列槽發送來的應用程式代碼燒寫至F28035片内Flash指定扇區;否則将繼續執行原有的應用程式。當應用程式很大或DSP的RAM空間比較小時,可采用将應用程式代碼分批發給DSP,DSP接收并燒寫完一批代碼後,再進行下一批代碼的接收和燒寫工作,直到所有的應用程式代碼都燒寫完畢。
2 線上更新的具體實作
2.1 應用程式
使用者的應用程式經過CCS編譯連接配接生成具有子產品化格式的目标檔案(.out),該檔案中的代碼和資料分别存放在不同的段中,因而不能直接用來燒寫Flash,需将其轉換為Flash能識别的資料格式——二進制檔案 (.bin)。本文采用hex2000.exe和FileOshell.exe工具來實作檔案轉換。首先,應用程式經過編譯連接配接生成.out檔案,然後通過hex2000.exe把.out檔案轉換成.hex檔案,再通過FileOshell.exe将檔案轉換成.bin檔案。先做一個批處理檔案,内容如下:
Example_2803xAdcSoc.out
-map Example_2803xAdcSoc.map
-o Example_2803xAdcSoc.hex
-m
-memwidth 16
-image
ROMS
{
Flash28035: origin = 0x3e8000, len= 0x1000, romwidth=
16, fill=0xFFFF
}
其中,Example_2803xAdcSoc.out 是應用程式經過CCS生成的檔案;-map是生成map檔案;-o是生成hex檔案;-m是Motorola-S 格式;-memwidth 16指存儲器位數為16 bit;-image指選擇映像檔案;ROMS 是所需要轉換的起始位址、長度、位數及填充。本文選擇從0x3e8000開始,長度是4 KB,即FlashH,FlashH中未用的部分用0xFFFF填充,本文把這個批處理檔案命名為:Example_2803xAdcSoc.cmd。接下來要生成.bin檔案,先做一個MS-DOS型批處理檔案,其内容如下: IFileIOShell.exe -i Example_2803xAdcSoc.hex -o Example_2803xAdcSoc.bin
注意要把Example_2803xAdcSoc.out、hex2000.exe、FileIO
Shell.exe、Example_2803xAdcSoc.cmd和MS-DOS型批處理檔案放在同一目錄下,然後輕按兩下MS-DOS型批處理檔案,即生成所需要的Example_2803xAdcSoc.bin檔案。
2.2 底層程式
底層程式用于實作将序列槽發送的資料燒寫至Flash的指定部分,涉及到應用程式的正确定位和複位後的啟動過程,是實作整個線上更新的重點。底層程式流程圖如圖1所示。底層程式主要實作以下功能[3]:
(1)上電複位查詢功能。上電複位後通過接收上位機發送的指令判斷是否更新。若上位機發送的是更新指令,則跳轉到底層程式中更新部分執行;否則,跳轉到原有的應用程式處執行。
(2)搬移燒寫程式的功能。由于F28035片上Flash不支援在其中一個扇區運作程式去擦除或燒寫其他扇區,故完成接收資料和燒寫Flash工作的這部分程式(即底層程式中的更新部分程式)需搬移至片内RAM或片外RAM上運作。實作程式搬移的函數為:
void MemCopy (Uint16 *SourceAddr, Uint16 *Source End
Addr, Uint16 *DestAddr)
{
while (SourceAddr < SourceEndAddr)
{
*DestAddr++ = *SourceAddr++;
}
return ;
}
其中,SourceAddr為Flash中更新程式的起始位址,SourceEndAddr為Flash中更新程式的結束位址;DestAddr為搬移至記憶體的首位址。
(3)接收上位機發送的應用程式代碼并儲存到DSP
指定的記憶體中(一般為RAM區)。這是通過序列槽RS232來實作的。并确定用于資料儲存的這部分記憶體未被占用。例如,若需要将應用程式代碼暫存到F28035的L0 SARAM區域(位址空間0x3F8000-0x3F8800)。定義數組Uint16 BlockBuffer[2048]用于存儲應用程式代碼,在底層程式中采用存儲器定位語句,将上面的緩沖數組定位到相應的存儲空間:
#pragma DATA_SECTION(BlockBuffer,“BlockTransferbuffer”);
在底層程式CMD檔案中,采用定位語句,将BlockTransferbuffer定位到DSP的L0 SRAM空間:
BlockTransferBuffer:> L0 SARAM PAGE=2
//位址空間:0x3F8000~0x3F8800
通過以上底層程式的設定,可将應用程式緩存到指定的RAM區域中。
(4)代碼接收結束後,将記憶體中的代碼燒寫至指定Flash扇區,該步驟通過調用Flash2803x_API庫函數完成。底層程式中所用到的Flash2803x_API庫函數如下[6]:
①擦除扇區的函數為Uint16 Flash28035_Erase(Uint16 SectorMask,&Fstatus),其中,SectorMask為即将被擦除的扇區;&Fstatus為執行擦除操作後傳回的狀态值,用來判斷擦除操作是否成功。②将程式燒寫到Flash扇區的函數為Uintl6 Flash28035_Program(&FlashAddr, &BuffAddr,Length,&Fstatus),其中,&FlashAddr為即将被燒寫的Flash扇區的起始位址;&BuffAddr為即将準備燒寫的程式目前存放在記憶體空間的首位址;Length為程式長度;&Fstatus為執行燒寫操作後傳回的狀态值,用來判斷燒寫操作是否成功。③校驗燒寫到Flash中的程式為Uint16 Flash28035_Verify(&FlashAddr,&BuffAddr,Length,&Fstatus),其中,&FlashAddr指定從Flash内開始比較的首位址;&BuffAddr為被比較檔案的存儲首位址;Length是需要比較的16 bit字的個數,程式長度;&Fstatus是執行校驗操作後傳回的狀态值,用來判斷校驗操作是否成功。
2.3 底層程式和應用程式的定位
DSP F28035上電複位後,CPU将從内部Boot Rom獲得複位向量。複位向量指向Boot Rom并執行其内部的Bootloader程式,執行完畢後确定從内部Flash啟動。程式指針跳轉到Flash的0x3F7FF6處。由于這個位址是固定的,是以底層程式必須燒寫在以這個位址為起始位址的空間内。DSP進入底層軟體程式中運作,首先通過接收上位機的指令來判斷是否進行線上更新,如果進行線上更新,則跳轉到相應更新程式中執行;否則,跳轉到原有的應用程式處執行。由底層程式跳轉到原有的應用程式處執行時,采用絕對位址跳轉。部分程式如下所示:
#define Jumpgxcx (void (*)(void))0x3E8FFE
//定義應用程式的跳轉位址
SCI_SendStatus(“upgrade program? (y/n):”)
//向上位機詢問是否更新
temp = SCIA_GetByteData_app();
//接收上位機發送來的是否更新指令
if (temp==’y’)
{
main2(); //如果更新,則跳轉到更新程式中執行
}
Else
{
(*Jumpgxcx)();
//如果不更新,則采用絕對位址跳轉到應用程式中執行
}
}
底層程式的cmd配置與應用程式的cmd配置要保持一緻,不能産生位址沖突。同時,要注意底層程式和應用程式的跳轉位址配置。
底層程式cmd檔案的部配置設定置如下:
BEGIN : origin = 0x3F7FF6, length = 0x000002
RESET : origin = 0x3FFFC0, length = 0x000002 /*
codestart : > BEGIN PAGE = 0
應用程式cmd檔案的部配置設定置如下:
BEGIN : origin = 0x3E8FFE, length = 0x000002
codestart : > BEGIN PAGE = 0
3 燒寫步驟
首先把底層程式通過JTAG接口燒寫到F28035中,然後再進行應用程式的燒寫。應用程式的燒寫步驟為:先把序列槽調試工具的參數配置為波特率9 600 bit/s、8 bit資料位、1 bit停止位、沒有奇偶校驗位;選擇發送文本檔案方式,發送應用程式的.bin檔案到DSP。由于F28035的RAM區比較小,可以采取把應用程式代碼分為多次發送的方式。燒寫過程如圖2所示。
本文介紹了一種基于序列槽通信的DSP應用程式線上更新技術,可以在不打開機箱的條件下實作子產品軟體的更新更新。經過實驗發現,采用線上更新技術來更新程式所耗費的時間比采用JTAG口燒寫程式所耗費的時間要長一些,但解決了複雜情況下程式更新困難的問題。總之,該方法簡單可靠,可應用于嵌入式裝置的軟體程式更新更新中。