28335的啟動步驟介紹
一、28335的啟動介紹
TI支援很多種方式的boot,內部的ram(saram),flash,sci,但無論哪種啟動都遵循下面的流程:
而該流程中的reset,initboot,call selectbootmode, read i/o state, call boot loader這些步驟都是固化在晶片內的程式自己執行的,也就是說這些程式碼在出廠的時候已經在TI的晶片內。(我們寫的程式是從codestart出開始的,其程式碼在DSP2833x_CodeStartBranch.asm內,其指定位置在CMD檔案內定義。下載到flash中時是在0x3f7ff6處,因為復位的時候指向的0x3fffc0,先執行固化的
在28335中是一段的8k*16的read-only的memory,地址位於0x3fe000-0x3fffff,見下圖:
根據上面的流程圖,詳細的解釋一下流程:
1.在3fffc0到3fffff其實是放了中斷向量表的地方:系統一開機當然是處於reset中斷,因此直接跳至reset的地方執行(0x3fffc0)。而這個地方的兩個位元組只是放了一條指令,就是跳至initboot函式,也就是3ff34c的地址執行bootloader。
.reset 與reset是不同的,一個在memory,一個在sections中。
.reset只包含一個32位的中斷向量,指向實時支援庫rts2800_ml.lib中的C編譯器導引函式,即_c_int00子程式。通常我們不用此塊,而是另外建立分支指令指向開始程式碼。如4中介紹。
2.在3ff34c的bootloader的程式,這裡主要有initboot, 和SelectBootMode, 以及一些外設引導的函式。SeleteBootMode根據晶片的硬體或軟體設定來判斷晶片該去哪裡尋找程式入口,直接目的是如何找到main,然後執行應用程式。bootloader操作中會去檢測外部GPIO口的狀態,從而判斷是哪種方式的啟動:
3.然後根據相應的啟動方式跳至相應的入口地址:比如FLASH啟動就是0x33fff6, 內部SARAM啟動就是0x0。
4.而這裡的入口地址就是cmd檔案中定義的begin段。因此對於flash啟動和ram啟動,begin的定義是不同的,在flash啟動時begin就是0x33fff6,而ram啟動begin就是0x0.這個2個字的區間也就是放了我們程式最初執行的第一條指令(通常是code_start).一條長跳轉指令LB剛好佔兩個位元組。
bootloader執行完畢之後會跳到0x3f7ff6處,而codestart被放置到了BEGIN處。故即是執行DSP2833x_CodeStartBranch.asm程式碼。
codestart包含一條長跳轉指令,指向實時支援庫rts2800_ml.lib中的C編譯器導引函式,即_c_int00子程式。不同的是:如果系統的程式(.text)放在系統內部RAM中模擬執行,則本塊應放入片內RAM中,如地址單元0x3F8000;如果是固化程式進FLASH,則.codestart應定位與FLASH中的其實地址為0x3F7FF6中。(一條長跳轉指令佔2個字)。
ramfuncs作用是程式的搬移。load=allocation(強制地址或儲存空間名稱)同>allocation:定義輸出段將會被裝載到哪裡。
run= allocation(強制地址或儲存空間名稱)同>allocation:定義輸出段將會在哪裡執行。
另:CMD檔案中只出現一個關鍵字load或run時,表示兩者的地址時表示兩者的地址時重合的。
LOAD_START(_RamfuncsLoadStart)令編譯器建立了一個變數RamfuncsLoadStart,該變數指向段ramfuncs的裝載地址的首地址(LOAD_ START為編譯偽指令,請見CCS的幫助文件);
LOAD_START(_RamfuncsLoadEnd)令編譯器建立了一個變數RamfuncsLoadEnd,該變數指向段ramfuncs的裝載地址的末地址(LOAD_ END為編譯偽指令,請見CCS的幫助文件);
RUN_START(_RamfuncsRunStart)令編譯器建立了一個變數RamfuncsRunStart,該變數指向段ramfuncs的執行地址的首地址(LOAD_ START為編譯偽指令,請見CCS的幫助文件);
或通過這個方式可以把一些程式放入指定的位置。(放置的位置與執行時的位置不同時,如下載到flash中,但是執行時要在RAM中執行)
學習一款處理器晶片,搞明白晶片的執行過程,特別是程式的啟動階段,對於更好的應用晶片很有幫助。對F28335來講,它提供的方式很多。首先F28335中有片內flash,可以將程式儲存在這裡;其次,F28335也提供了bootloader功能;最後,F28335還具有片上OTP,使用者可以在這裡設定自己的啟動方式。
在28335的TI提供的例程中,程式的起始位置是code_start,在這裡先禁止看門狗,然後再跳轉到c_int00處執行;而在一般的C工程中,這個起始位置一般是c_int00;這個起始位置在編譯選項(build options)中設定,在C環境建立之前將看門狗禁止,使得程式更可靠。
查閱到“DSP2833x_CodeStartBranch.asm”中的說明,如下:
For these examples, code_start is thefirst code that is executed after exiting the boot ROM code. The codestart section in the linker cmd fileis used to physically place this code at the correct memory location. Thissection should be placed at the location the BOOT ROM will re-direct the codeto. For example, for boot to FLASH thiscode will be located at 0x3f7ff6.
In addition, the example DSP2833x projectsare setup such that the codegen entry point is also set to the code_startlabel. This is done by linker option -e in the project build options. When thedebugger loads the code,it will automatically set the PC to the "entrypoint" address indicated by the -e linker option. In this case the debugger is simplyassigning the PC, it is not the same as a full reset of the device.
從上面的說明,可以看到,在模擬模式下忽略了啟動模式的選擇,而是讓模擬器直接將程式的起始地址賦給PC的。特別對這個程式來講,由於在C環境之前,還禁止了看門狗,程式的起始地址是code_start。但是這裡有一點還應注意,在模擬模式下,模擬的是將程式引導到M0SARAM中,所以在CMD檔案中,將code_start硬體定位到了M0 SARAM的起始位置處,如果固化程式的話,需要更改code_start的位置,將其放在對應方式的位置處。
二、我們最常用到的主要有兩種引導模式:
一種是boot to RAM,即跳到0x000000的RAM中,去開始執行指令,主要針對程式載入在RAM的模擬模式;另外一種是boot to Flash,則跳到0x3F7FF6中去開始執行程式碼。
相應的,程式會在這兩個入口地址0x000000, 0x3F7FF6放一條跳轉指令,在codestart.asm原始檔中,原因是在Flash的入口地址處只有兩個單元的空間,後面是CSM模組,所以需要跳轉;而在RAM中之所以也需要跳轉,主要是因為在跳轉到main之前,需要執行一小段程式碼_c_int00,該程式碼會使用0x000003之後的一段RAM,如果程式碼放在那裡,在執行_c_int00之後會損壞程式碼。下載到RAM中的時候CMD檔案有上面的兩句,codestart是在檔案“DSP2833x_CodeStartBranch.asm”中有定義,實際上codestart段只是包含了一個跳轉指令,是程式跳轉到_c_int00處,_c_int00在boot.asm in RTS library中有定義,_c_int00的程式碼最終會呼叫c的main函式,之後就是main函式的執行。
下載到flash中的時候CMD檔案有上面的兩句。(而復位的時候指向的是0x3fffc0)
另外就是一些外設引導模式,如SCI引導以及SPI引導等,像我們常使用的C2PROG軟體就支援SCI引導,然後通過串列埠下載程式。
三、c_int00介紹
_c_int00 is branch to start of boot.asm in RTS libray //翻譯為中文就是:_c_int00是rts2800_ml.lib的入口地址;
· _c_int00是C初始化程式碼的入口地址
· 在你用C程式設計的時候,DSP需要執行一段C執行支援庫程式碼以完成C執行環境的初始化,_c_int00就是這段初始化程式碼的入口地址,
· _c_int00函式在執行支援庫(rts,runtime-support library)中。聯結器會將這個函式的入口地址放置在復位中斷向量處,使其可以在初始化時被呼叫。c_int0函式進行以下工作以建立C執行環境:為系統堆疊產生.stack塊,並初始化堆疊指標。從.cinit塊將初始化資料拷貝到.bss塊中相應的變數。
· 執行完初始化程式碼後,就跳轉到main函式,開始執行C程式;
· rts2800.lib:C/C++執行支援庫;
· rts2800_ml.lib C/C++大記憶體模式執行支援庫.
· rts2800_ml.lib中有大量浮點運算處理的函式而rts2800.lib沒有
· 在指標的訪問空間上有區別,rts2800.lib中庫函式的指標為near,故不能訪問3Fxxxx,rts2800_ml.lib可以訪問(大小記憶體模式故名思議就是可以訪問的記憶體的大小有區別,小記憶體模式只能訪問低64k地址,也就是16位地址線)
四、2812的啟動步驟(可參照理解28335)
下面是2812的flash啟動流程,可參照學習28335的啟動
2812從內部flash啟動的詳細流程說明:
(a)上電覆位
(b) 判斷是否從flash啟動
(c)復位向量是指向片內Flash的0x3FFFC0,2812有一塊flash地址從0x3FF000-0x3FFFFF在出廠時已經固化好了載入程式。在0x3FFFC0處是一條跳轉指令,跳到iniboot(地址0x3FFC00)函式處執行iniboot程式碼,該iniboot程式碼就是TI在dsp出廠時固化在flash中的
(d)InitBoot assembly Routine將選擇SelectBootMode function啟動模式函式。這個函式由GPIO 引腳的狀態決定啟動型別。一旦啟動結束,選擇啟動模式函式返回一入口地址給InitBoot函式。入口地址是退出bootloader之後程式碼開始執行的起始點。InitBoot接著將會呼叫ExitBoot子程式,把CPU暫存器的狀態恢復到復位狀態。比如flash boot模式。
(e)那麼initboot執行完後跳轉到0x3F7FF6處(codestart處),此位置剛好在128位(CSM)密碼位置之前。
(f)你要在0x3F7FF6處放置跳轉指令,以跳轉到你要去的地方,比如是boot loader或應用程式碼,通常的跳轉去處是_c_int00。
(g)上面程式碼執行後跳到C初始化的入口_c_int00(0x3F6000) ,在C初始化的入口,_c_int00對一些變數,堆疊和暫存器進行必要的設定。
(h)呼叫main函式開始執行C程式。