TMS320F2812從內部Flash啟動的詳細流程說明:
1>程序硬件復位或者軟件復位;
2>判斷XMP/MC信號狀態;若該信號為高電平時是微處理器模式,此時外部接口Zone7有效,Zone7被映射到存儲空間的高位,這樣向量表指向外部,系統從Zone7啟動。若該信號為低電平時是微計算機模式,此時Zone7被禁止,向量表指向Boot ROM,這樣系統既可以從內部存儲空間啟動,也可以從外部存儲空間啟動。
3>到Boot ROM的0x3FFC00處取出復位向量,跳到Boot函數;(TMS320F2812有一塊Flash地址從0x3FF000-0x3FFFFF在出廠時TI已經固化好了引導程序InitBoot,InitBoot函數判斷幾個GPIO引腳來判斷使用哪一種引導模式,比如Flash Boot模式,檢測SPICLKA(GPIOF2),SPISTEA(GPIOF3),SCITXDA(GPIOF4),MDXA(GPIOF12)的電平,當都為高電平時表明是片內Flash Boot模式,那么InitBoot執行完后跳轉到0x3F7FF6處,這個時候指令占據兩個字節,剛好在代碼模塊之前。一定是跳轉指令才行)
4>采集I/O管腳狀態;
5>根據I/O狀態選擇Boot方式;
6>如果是Flash,程序退出Boot函數,跳轉到0x3F7FF6(codestart);
7>取出跳轉指令,跳轉到自己的指定地址或者C初始化的入口_C_INT00(0x3F6000)處(DSP281x_CodeStartBranch.asm中);
8>在C初始化的入口_C_INT00對一些變量,堆棧和寄存器進行必要的設置,該函數在C的庫函數內(RTS Library);
9>進入main函數(0x3F658E,這個地址不是固定的,但是在Flash里面)。
從上電到我們的主函數運行之間這段時間里TMS320F2812到底做了些什么?TMS320F2812是怎樣引導程序運行的?下面敘述其啟動過程:
在TMS320F2812中有一個引腳XMP/MC,當該引腳的為高電平時表示是微處理器模式(Microprocessor),當該引腳為低電平時表示微機算計模式(Microcomputer)。當為微處理器模式時,TMS320F2812內部的Boot ROM被禁止,通過Zone7(0x3FC000)從外部調引導程序啟動,TMS320F2812復位以后,其復位向量是固定的0x3FFFC0,如果為微處理器模式,那么復位后的復位向量指向的外部的地址,即0x3FFFC0是Zone7處的地址;若為微機算計模式,那么0x3FFFC0指向的是TMS320F2812的片內Flash的址。下面就以微機算計模式加以說明其過程。
上電復位后,復位向量是指向片內Flash的0x3FFFC0,TMS320F2812有一塊Flash地址從0x3FF000-0x3FFFFF在出廠時已經固化好了引導程序。在0x3FFFC0處是一條跳轉指令,跳到InitBoot(地址0x3FFC00)函數處執行InitBoot代碼,該InitBoot代碼就是TI在DSP出廠時固化在Flash中的。InitBoot Assembly Routine將選擇SelectBootMode Function啟動模式函數。這個函數由GPIO 引腳的狀態決定啟動類型。
引導模式選擇
SCITXDA (GPIOF4) |
MDXA (GPIOF12) |
SPISTEA (GPIOF3) |
SPICLK (GPIOF2) |
Mode Selected |
1 | x | x | x | 跳轉到地址為0x3F7FF6的Flash,用戶必須在這里編寫分支語句優先於復位,以按需要重新定位代碼的執行 |
0 | 1 | x | x | 調用SPI_Boot 以從外部的EEPROM載入 |
0 | 0 | 1 | 1 | 調用SCI_Boot 以從SCI-A載入 |
0 | 0 | 1 | 0 | J跳轉到 H0 SARAM 0x3F8000 |
0 | 0 | 0 | 1 | 跳轉到OTP地址0x3D7800 |
0 | 0 | 0 | 0 | 調用Parallel_Boot從GPIO 端口B載入 |
一旦啟動結束,選擇啟動模式函數返回一入口地址給InitBoot函數。入口地址是退出BootLoader之后代碼開始執行的起始點。InitBoot接着將會調用ExitBoot子程序,把CPU寄存器的狀態恢復到復位狀態。比如Flash Boot模式,那么InitBoot執行完后跳轉到0x3F7FF6處(codestart處),此位置剛好在128位(CSM)密碼位置之前,你要在0x3F7FF6處放置跳轉指令,以跳轉到你要去的地方,比如是BootLoader或應用代碼,通常的跳轉去處是_c_int00。在0x3F 7FF6 處放置跳轉指令的方法如下(DSP281x_CodeStartBranch.asm中):
1 *********************************************************************** 2 *File:DSP281x_CodeStartBranch.asm 3 *Apply to:F2810,F2811,F2812 devices. 4 *Author: David Chan, WintechDigital System Inc. 5 *********************************************************************** 6
7 WD_DISABLE .set 1 ;set to 1 to disable WD, else set to 0
8
9 .ref _c_int00 10
11 *********************************************************************** 12 * Function: codestart section 13 * 14 * Description: Branch to code starting point 15 *********************************************************************** 16
17 .sect "codestart"
18
19 code_start:
20 .if WD_DISABLE == 1
21 LB wd_disable ;Branch to watchdog disable code
22 .else 23 LB _c_int00 ;Branch to start of boot.asm in RTS library
24 .endif 25
26 ;end codestart section
27
28
29 *********************************************************************** 30 * Function: wd_disable 31 * 32 * Description: Disables the watchdog timer 33 *********************************************************************** 34 .if WD_DISABLE == 1
35
36 .text 37 wd_disable:
38 SETC OBJMODE ;Set OBJMODE for 28x object code
39 EALLOW ;Enable EALLOW protected register access
40 MOVZ DP, #7029h>>6 ;Set data page for WDCR register
41 MOV @7029h, #0068h ;Set WDDIS bit in WDCR to disable WD
42 EDIS ;Disable EALLOW protected register access
43 LB _c_int00 ;Branch to start of boot.asm in RTS library
44
45 .endif 46
47 ;end wd_disable
48
49
50 .end 51
52 ; end of file CodeStartBranch.asm
1 MEMORY 2 { 3 PAGE 0 : 4 RAMM0 : origin = 0x000000, length = 0x000400 5 /****************************************************************** 6 *On F281x L0 SARAM is 0x008000-0x008FFF, and L1 SARAM is 7 * 0x009000-0x009FFF. 8 * Hence, whole SECURE_RAM is 0x008000-0x009FFF 9 *******************************************************************/ 10 SECURE_RAM : origin = 0x008000, length = 0x002000 11 BEGIN_FLASH : origin = 0x3F7FF6, length = 0x000002 /*RAM run:0x3F9FFa*/ 12
13 RESET : origin = 0x3FFFC0, length = 0x000002 14 VECTORTS : origin = 0x3FFFc2, length = 0x00003e 15
16 FLASH : origin = 0x3d8000, length = 0x01FF80 /* for Flash */ 17
18 /*PRAMH0 : origin = 0x3F8000, length = 0x001ff4 */ /*for RAM 0x001ffe*/ 19
20
21 PAGE 1 : 22 /* SARAM */ 23 RAMM1 : origin = 0x000400, length = 0x000400 24 DRAMH0 : origin = 0x3f8000, length = 0x002000 25
26 } 27
28
29 SECTIONS 30 { 31 /* Allocate program areas: */ 32 secureRamfuncs : LOAD=FLASH, PAGE = 0 /*PRAMH0*/ 33 RUN=SECURE_RAM,PAGE=0
34 RUN_START(_secureRamFuncs_runstart), 35 LOAD_START(_secureRamFuncs_loadstart), 36 LOAD_END(_secureRamFuncs_loadend) 37 .reset : > FLASH, PAGE = 0 /*PRAMH0*/ 38 .text : > FLASH, PAGE = 0 /*PRAMH0*/ 39 .cinit : > FLASH, PAGE = 0 /*PRAMH0*/ 40 /* zhaowritefunc : LOAD=FLASH,PAGE=0
41 RUN=SECURE_RAM,PAGE=0
42 RUN_START(_zhaowritefunc_runstart), 43 LOAD_START(_zhaowritefunc_loadstart), 44 LOAD_END(_zhaowritefunc_loadend) 45 zhaoreadfunc : LOAD=FLASH,PAGE=0
46 RUN=SECURE_RAM,PAGE=0
47 RUN_START(_zhaoreadfunc_runstart), 48 LOAD_START(_zhaoreadfunc_loadstart), 49 LOAD_END(_zhaoreadfunc_loadend) 50 transmit_work_scifunc : LOAD=FLASH,PAGE=0
51 RUN=SECURE_RAM,PAGE=0
52 RUN_START(_transmit_work_scifunc_runstart), 53 LOAD_START(_transmit_work_scifunc_loadstart), 54 LOAD_END(_transmit_work_scifunc_loadend) 55 transmit_work_usbfunc : LOAD=FLASH,PAGE=0
56 RUN=SECURE_RAM,PAGE=0
57 RUN_START(_transmit_work_usbfunc_runstart), 58 LOAD_START(_transmit_work_usbfunc_loadstart), 59 LOAD_END(_transmit_work_usbfunc_loadend)*/ 60
61 /* frame_valid_low_test_programfuncs: LOAD=FLASH,PAGE=0
62 RUN=SECURE_RAM,PAGE=0
63 RUN_START(_frame_valid_low_test_programfuncs_runstart), 64 LOAD_START(_frame_valid_low_test_programfuncs_loadstart), 65 LOAD_END(_frame_valid_low_test_programfuncs_loadend) 66
67 frame_valid_high_test_programfuncs: LOAD=FLASH,PAGE=0
68 RUN=SECURE_RAM,PAGE=0
69 RUN_START(_frame_valid_high_test_programfuncs_runstart), 70 LOAD_START(_frame_valid_high_test_programfuncs_loadstart), 71 LOAD_END(_frame_valid_high_test_programfuncs_loadend) 72 */ 73 /* fifo_empty_test_programfuncs : LOAD=FLASH,PAGE=0
74 RUN=SECURE_RAM,PAGE=0
75 RUN_START(_fifo_empty_test_programfuncs_runstart), 76 LOAD_START(_fifo_empty_test_programfuncs_loadstart), 77 LOAD_END(_fifo_empty_test_programfuncs_loadend) 78 fifo_half_test_programfuncs : LOAD=FLASH,PAGE=0
79 RUN=SECURE_RAM,PAGE=0
80 RUN_START(_fifo_half_test_programfuncs_runstart), 81 LOAD_START(_fifo_half_test_programfuncs_loadstart), 82 LOAD_END(_fifo_half_test_programfuncs_loadend) 83 */ 84
85
86 /* tint0_sub_lowRAMFUNCS : LOAD=FLASH,PAGE=0
87 RUN=SECURE_RAM,PAGE=0
88 RUN_START(_tint0_sub_lowRAMFUNCS_runstart), 89 LOAD_START(_tint0_sub_lowRAMFUNCS_loadstart), 90 LOAD_END(_tint0_sub_lowRAMFUNCS_loadend) */ 91 /* Jump to the Flash boot mode Entry! */ 92 codestart : LOAD = BEGIN_FLASH, PAGE = 0
93
94 /* Allocate data areas: */ 95 .stack : > RAMM1, PAGE = 1
96 .bss : > DRAMH0, PAGE = 1
97 .ebss : > DRAMH0, PAGE = 1
98 .const : > DRAMH0, PAGE = 1
99 .econst : > DRAMH0, PAGE = 1
100 .sysmem : > DRAMH0, PAGE = 1
101 }
上面代碼執行后跳到C初始化的入口_c_int00(0x3F6000) ,在C初始化的入口,_c_int00對一些變量,堆棧和寄存器進行必要的設置,這個函數在運行支持庫(rts.lib)中,_c_int00函數為建立C運行環境,需完成以下工作:
- 為系統堆棧產生.stack塊,並初始化堆棧指針;
- 從.cinit塊將初始化數據拷貝到.bss塊中相應的變量;
- 對寄存器進行必要的配置,調用main函數開始運行C程序。