DSP TMS320FF28335程式從FLASH中拷貝到RAM中的兩種方法及FLASH燒寫方法
程式從FLASH中拷貝到RAM中執行的方法
DSP的程式下載執行方式有兩種:一種是下載到RAM中線上執行,一種是下載到FLASH中執行。在RAM中執行時,具有執行速度快,可以無限次下載的特點,但是RAM的特點是掉電丟失資料。FLASH具有掉電不丟失資料的特點,但是同時存在執行速度慢和擦寫次數有限的缺點。因此綜合兩者的特點,在DSP的開發過程中一般會結合使用兩者。在前期程式除錯過程,由於需要頻繁的擦寫,所以一般選擇在RAM中進行。而程式除錯完成後,由於需要脫離下載器而獨立執行,因此需要燒寫到掉電不丟失資料的FLASH中。下面將以利用CCS5.2對TMS320F28335進行程式在FLASH中的燒寫為例,介紹一下將程式燒寫到FLASH中的操作過程。
程式從在RAM中執行改為下載到FLASH中需要對工程檔案做一些修改。而程式燒寫到FLASH中後,又根據程式執行時的儲存區間的不同,分為程式部分拷貝到RAM中執行和程式整體拷貝到RAM中執行兩種,兩種執行需要對工程作不同的修改和設定。
一、程式部分拷貝到RAM中執行
一般當程式過大,大於DSP的RAM空間或者對程式執行的速率要求不高時,一般將程式下載到FLASH中執行,並且上電後程序在FLASH中執行,僅僅將個別對時間要求比較高的程式拷貝到RAM中去執行。此時需要作如下修改 :
1、首先刪除掉工程檔案中的28335_RAM_link.cmd檔案,改為F28335.cmd檔案。如果在自己原來的工程中有對28335_RAM_link.cmd的儲存區有特殊修改,可以在F28335.cmd中作同樣的修改(僅限於不包括FLASH儲存區的部分)。
2、在工程檔案中加入檔案DSP2833x_MemCopy.c,該檔案提供程式碼賦值的函式。
3、在SECTION中定義ramfuncs段如下所示。段中定義程式下載的區間LOAD(自己指定)、執行的區間RUN(自己指定)、下載開始地址、下載結束地址、執行開始地址(不用改)。
ramfuncs : LOAD = FLASHD,
RUN = RAML123,
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
PAGE = 0
該段定義的作用在於將需要從FLASH中拷貝到RAM的程式歸入到該段中從而實現程式從下載地址到執行地址的拷貝。
4、在主程式的main之前定義需要拷貝到RAM中的函式,定義語句如下所示
#pragma CODE_SECTION(cpu_timer1_isr,"ramfuncs");
#pragma CODE_SECTION(cpu_timer2_isr,"ramfuncs");
其作用是將該子函式定義在ramfuncs段中。然後定義下載開始地址、下載結束地址、執行開始地址變數:
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
5、在main函式內還需要新增兩行程式碼。新增的位置是在InitPieVectTable();之後,程式碼如下(不用修改):
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
InitFlash();
6、最後需要將撥碼開關調到1111的地方,然後編譯燒寫即可。
二、程式整體拷貝到RAM中執行
有些時候程式的執行對於速度要求很高,此時就需要將程式整體拷貝到RAM中去執行。程式整體拷貝同樣需要進行特殊修改和設定。要想詳細瞭解下面設定的原理,可以查詢相關資料來詳細瞭解程式啟動的過程。
1、程式啟動的過程一般為:
code_start->wd_disable->c_int00->mian()
為了完成程式的拷貝,需要在C語言初始化之前插入一個程式拷貝的環節,修改之後的流程為:
code_start->wd_disable->copy_sections->c_int00->mian()
為此在DSP2833x_CodeStartBranch.asm中將所有的c_int00替換為copy_sections。
2、在DSP2833x_CodeStartBranch.asm中將該檔案中的wd_disable前的 .text改為 .sect "wddisable",從而將該段程式歸入到段wddisable中,並在F28335.cmd檔案中定義該段:
wddisable : > FLASHA, PAGE = 0
之所以這麼定義,是因為.text段是需要拷貝到RAM執行的,而在程式拷貝之前首先需要關閉看門狗,從而避免出現錯誤。如果仍然將程式放在.text段中,則看門狗禁止程式無法執行,會出現錯誤,因此在FLASH中定義一個新的段,從而讓看門狗關閉的程式在FLASH中提前執行,
3、在工程中新增DSP28xxx_SectionCopy_nonBIOS.asm檔案,該檔案提供對各個段進行拷貝的程式,十分重要。這部分程式碼不需要修改,直接使用就行。
4、將檔案DSP2833x_usDelay.asm中的.sect "ramfuncs"改為 .text。從而將該段程式碼歸入到.text段中,隨段拷貝到RAM中執行。
5、刪除F28335_sysctrlinit.c檔案中的程式碼:
#pragma CODE_SECTION(InitFlash, "ramfuncs");
從而將InitFlash程式碼歸到.text段中。
6、在F28335.cmd檔案中定義相應的段,程式碼如下。定義codestart、wddisable、copysections 三段在FLASH中執行,定義初始化段的各段的下載區間LOAD、執行區間RUN(前兩者儲存區間自己選擇)、下載開始地址、執行開始地址、段大小(後三者名字不可改變)。注意下面程式碼、格式以及標點符號必須嚴格不錯。
codestart : > BEGIN PAGE = 0
wddisable : > FLASHA, PAGE = 0
copysections : > FLASHA, PAGE = 0
.cinit : LOAD = FLASHD, PAGE = 0
RUN = RAML123, PAGE = 0
LOAD_START(_cinit_loadstart),
RUN_START(_cinit_runstart),
SIZE(_cinit_size)
.pinit : LOAD = FLASHD, PAGE = 0
RUN = RAML123, PAGE = 0
LOAD_START(_pinit_loadstart),
RUN_START(_pinit_runstart),
SIZE(_pinit_size)
.text : LOAD = FLASHD, PAGE = 0
RUN = RAML123, PAGE = 0
LOAD_START(_text_loadstart),
RUN_START(_text_runstart),
SIZE(_text_size)
.const : LOAD = FLASHD, PAGE = 0
RUN = RAML123, PAGE = 0
LOAD_START(_const_loadstart),
RUN_START(_const_runstart),
SIZE(_const_size)
.econst : LOAD = FLASHD, PAGE = 0
RUN = RAML123, PAGE = 0
LOAD_START(_econst_loadstart),
RUN_START(_econst_runstart),
SIZE(_econst_size)
.switch : LOAD = FLASHD, PAGE = 0
RUN = RAML123, PAGE = 0
LOAD_START(_switch_loadstart),
RUN_START(_switch_runstart),
SIZE(_switch_size)
7、最後需要將撥碼開關調到1111的地方,然後編譯燒寫即可。
三、程式燒寫到FLASH中方法
工程經過上面修改後可以進行編譯,編譯無錯誤後就可以燒寫到FLASH中了。CCS5.2已經繼承了燒寫外掛,所以無需再下載任何外掛,極大的方便了程式的燒寫。工程編譯後還需要進行一些設定。在project——property——debug——F28335 Flash Settings裡作如下圖所示的設定:上部根據你所使用的時鐘的真實情況設定晶振頻率,分頻係數和倍頻係數。第二部分勾選不變,第三部分可以只勾選自己用到的儲存區間,最下方不要更改,以免FLASH誤鎖後找不到密碼。
上面設定完成後就可以直接點選debug按鈕,則程式自動燒寫到FLASH中,燒寫完成後可以線上除錯。也可以將下載器拔掉,重新上電,則程式會自動在FLASH中執行。
經過上面的處理,程式燒寫到FLASH中就完成了。