嵌入式開(kāi)發(fā)中的S3C2410初始化
S3C2410的初始化代碼主要涉及到對系統主要模塊的配置、運行環(huán)境的建立、系統時(shí)鐘、MMU等模塊的配置,下面按執行順序依次都各個(gè)部分進(jìn)行分析:
l程序入口:(ResetHandler)
在程序一開(kāi)始,首先進(jìn)行的一些操作主要保證初始化程序能夠順利的運行,因此主要包括關(guān)閉WDT、中斷,配置鎖相環(huán)等。
l配置memory接口
memory接口是確保數據訪(fǎng)問(wèn)正確的基本保障,此處主要配置SFR寄存器中0x48000000開(kāi)始的memory接口寄存器組,確保每個(gè)bank的位寬、訪(fǎng)問(wèn)類(lèi)型(waitable)以及時(shí)序參數正確。如果沒(méi)有特別的要求,一般來(lái)說(shuō)時(shí)序參數使用默認值即可。
l初始化堆棧
ARM 有6種運行模式,必須為每一種模式提供獨立的堆??臻g,在堆棧設置之前是不能進(jìn)行C函數的調用的。arm的堆棧模式是從高地址遞減的,我們可以將堆棧的首地址設在0x33ff8000處,往低依次為FIQ、IRQ、Abort、Undef、SVC,其中SVC和User模式不予區分。堆棧大小一般可在頭文件或者當前文件中修改。
l運行空間的初始化
這段代碼主要完成兩個(gè)功能,一是將RW數據搬運到RW空間(我們生成ROM鏡像時(shí),RW數據是跟在RO數據之后的),二是初始化ZI數據段。當然,這段代碼存在的前提是代碼的運行環(huán)境只是標準的兩段式:一段RO空間和一段RW空間;并且在C程序入口時(shí)沒(méi)有調用編譯器的鏈接庫(__main)。后者已經(jīng)提供相應的功能,并且支持更加復雜的運行環(huán)境定義(使用SCF文件)。
l__rt_lib_init
在A(yíng)DS1.2的環(huán)境中,如果在C入口沒(méi)有調用編譯器的鏈接庫(__main),那么在C程序一開(kāi)始要調用該函數以初始化運行時(shí)的函數庫,以保證對ADS提供的某些庫函數能夠正常調用。
lMMU初始化
2410 的MMU支持1級&2級地址映射,在我們目前的應用中均采用1級section模式的地址映射,一個(gè)section的大小為1M,也就是說(shuō)從邏輯地址到物理地址的轉變是這樣的一個(gè)過(guò)程:一個(gè)32位的地址,高12位決定了該地址在頁(yè)表中的index,這個(gè)index的內容決定了該邏輯section對應的物理section;低20位決定了該地址在section中的偏移(index)。
因此從0x0~0xffffffff的地址空間總共可以分成0x1000(4K)個(gè)section,頁(yè)表中每項的大小為32個(gè)bit,因此頁(yè)表的大小為0x4000(16K)。所有示例程序的頁(yè)表統一存放在地址0x33ff8000。
每個(gè)頁(yè)表項的內容如下:
31 20 19 12 11 10 9 8 5 4 32 1 0
Section對應的物理地址 | NULL | AP | 0 | Domain | 1 | C | B | 1 | 0 |
AP:Access Permission,區分只讀、讀寫(xiě)、SVC&其它模式。
C | B | 具體含義 |
0 | 0 | 無(wú)cache,無(wú)寫(xiě)緩沖,任何對memory的讀寫(xiě)都反映到ASB總線(xiàn)上。對memory的操作過(guò)程中CPU需要等待。 |
0 | 1 | 無(wú)cache,有寫(xiě)緩沖,讀操作直接反映到ASB總線(xiàn)上。寫(xiě)操作CPU將數據寫(xiě)入到寫(xiě)緩沖后繼續運行,由寫(xiě)緩沖進(jìn)行ASB操作。 |
1 | 0 | 有cache,寫(xiě)通模式,讀操作首先考慮cache hit;寫(xiě)操作時(shí)直接將數據寫(xiě)入寫(xiě)緩沖,如果同時(shí)出現cache hit,那么也更新cache。 |
1 | 0 | 有cache,寫(xiě)回模式,讀操作首先考慮cache hit;寫(xiě)操作也首先考慮cache,如果hit,則只修改cache,并將cache對應半行的dirty比特置位;如果miss,則寫(xiě)入寫(xiě)緩沖,觸發(fā)ASB總線(xiàn)操作。 |
雖然MMU只是使用了邏輯地址到物理地址的linear transfer(值不改變),但是由于MMU能夠引入cache&write buffer,因此系統性能有很大的提高!
配置時(shí)鐘比、重新設置PLL
2410內部有三個(gè)時(shí)鐘:FCLK、HCLK、PCLK,分別供CPU、AHB總線(xiàn)和
APB總線(xiàn)使用,為了降低功耗,一般都選擇周期比為1:2:4的合理配置。 同時(shí)將PLL配置為運行環(huán)境時(shí)鐘,一般都達到最高202M。
IO初始化
將IO口配置為對應的功能選項,同時(shí)一般會(huì )點(diǎn)亮相應的LED燈。
中斷初始化
2410的內存空間沒(méi)有remap的機制,應該中斷入口時(shí)鐘位于零地址。因此中
斷服務(wù)機制可以描述如下:
首先,不管使用那種啟動(dòng)方式,必須確保一下代碼段位于內存的0x0地址:
b ResetHandler
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
除ResetHandler外,其余各項都是由如下的宏定義的一段代碼:
HandlerFIQ HANDLER HandleFIQ
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0};PUSH the work register to stack
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
這段代碼的含義是通過(guò)堆棧將中斷向量表中的內容賦給PC指針(如HandleFIQ是存放著(zhù)FIQ服務(wù)程序入口地址的地址),自然程序就跳到相應的入口地址。
可見(jiàn),中斷向量表存放的是各個(gè)中斷服務(wù)程序的入口地址,它是用來(lái)被加載的,而并不是可執行代碼。為了統一,所有示例程序都將中斷向量表放在0x33ffff00開(kāi)始的地址,并根據入口地址依次排列。
需要注意的是如果各種模式的服務(wù)程序用C語(yǔ)言定義,那么類(lèi)型必須用__irq定義,以保證能夠正確返回。
初始化串口
串口統一選用UART0,模式采用115200、1bit STOP、No Parity。
評論