TQ2440啟動代碼分析(一)
IsrIRQ
sub sp,sp,#4 ;reserved for PC,給PC寄存器保留
stmfd sp!,{r8-r9};工作寄存器入棧保護
ldr r9,=INTOFFSET;INTOFFSET在2440addr.inc中定義
ldr r9,[r9]
ldr r8,=HandleEINT0;HandleEINT0 的地址就是中斷的入口地址
add r8,r8,r9,lsl #2;邏輯左移就相當(dāng)于乘以4
ldr r8,[r8]
str r8,[sp,#8]
ldmfd sp!,{r8-r9,pc},將地址從堆棧中彈出給PC
LTORG
;用于聲明一個數(shù)據(jù)緩沖池
;=======
上電和復(fù)位后,程序開始從位于0x0 執(zhí)行b ResetHandler 程序跳轉(zhuǎn)到這里執(zhí)行,將看門
狗,中斷之類的程序關(guān)掉,以免打擾初始化程序的進行。
; ENTRY
;=======
ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
WTCON 為看門狗控制寄存器,此處將其寫入0x0,就是禁止它的所有功能,包括定時
器定時,溢出中斷及溢出復(fù)位。
ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
INTMSK 為中斷屏蔽寄存器,寫入0xffffffff,就是禁止所有的中斷產(chǎn)生,因為中斷
向量表還未初始化,如果此時產(chǎn)生中斷會使程序進入未知的狀態(tài)而跑飛。因為外設(shè)的中斷太
多,INTMSK 不夠用,還需要INTSUBMSK 來將剩余的中斷源也禁止掉。
ldr r0,=INTSUBMSK
ldr r1,=0x7fff ;all sub interrupt disable
str r1,[r0]
[ {FALSE} ;亮燈用的,可以用來調(diào)試用
;rGPFDAT = (rGPFDAT & ~(0xf<<4)) | ((~data & 0xf)<<4);
; Led_Display
ldr r0,=GPBCON
ldr r1,=0x155500
str r1,[r0]
ldr r0,=GPBDAT
ldr r1,=0x0
str r1,[r0]
]
;To reduce PLL lock time, adjust the LOCKTIME register.
ldr r0,=LOCKTIME;設(shè)置pll 鎖定時間
ldr r1,=0xffffff
str r1,[r0]
LOCKTIME 為PLL 鎖定時間計數(shù)寄存器,重新設(shè)定分頻值時,PLL 進入鎖定,輸出穩(wěn)
定頻率的時鐘需要一定的時間。這里設(shè)置成默認的值,以滿足鎖定的要求。
[ PLL_ON_START
; Added for confirm clock divide. for 2440.
; Setting value Fclk:Hclk:Pclk
ldr r0,=CLKDIVN;用于設(shè)定FCLK,HCLK和PCLK的比例
ldr r1,=CLKDIV_VAL ; 0=1:1:1, 1=1:1:2, 2=1:2:2, 3=1:2:4, 4=1:4:4, 5=1:4:8, 6=1:3:3, 7=1:3:6.,在option.inc中有定義
str r1,[r0]
;program has not been copied, so use these directly
[ CLKDIV_VAL>1 ; means Fclk:Hclk is not 1:1.
mrc p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000;R1_nF:OR:R1_iA
mcr p15,0,r0,c1,c0,0
|
mrc p15,0,r0,c1,c0,0
bic r0,r0,#0xc0000000;R1_iA:OR:R1_nF
mcr p15,0,r0,c1,c0,0
]
;Configure UPLL
ldr r0,=UPLLCON
ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) ;Fin = 12.0MHz, UCLK = 48MHz
str r1,[r0]
nop ; Caution: After UPLL setting, at least 7-clocks delay must be inserted for setting hardware be completed. ;在UPP 設(shè)定之后,必須等待7 個時鐘的延遲,設(shè)定才會有效
nop
nop
nop
nop
nop
nop
;Configure MPLL,設(shè)置MPLL
ldr r0,=MPLLCON
ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin = 12.0MHz, FCLK = 400MHz
str r1,[r0]
]
;查看是否是由睡眠狀態(tài)啟動,如果是則跳轉(zhuǎn)到WAKEUP_SLEEP狀態(tài)
;Check if the boot is caused by the wake-up from SLEEP mode.
ldr r1,=GSTATUS2
ldr r0,[r1]
tst r0,#0x2
;In case of the wake-up from SLEEP mode, go to SLEEP_WAKEUP handler.
bne WAKEUP_SLEEP
EXPORTStartPointAfterSleepWakeUp
StartPointAfterSleepWakeUp
初始化內(nèi)存控制器其實就是對S3C2440 的memory bank 進行設(shè)置,使其擴展的存儲器
或外部設(shè)備能夠被處理器通過內(nèi)存控制器正確讀寫。由于S3C2440 的最終應(yīng)用程序是在
SDRAM(bank6)中運行,并與C 語言變量等的用戶數(shù)據(jù),各種模式的堆棧,中斷向量表,
都被定位在SDRAM 的空間,所以它必須在涉及這些處理之前完成初始化工作。
;Set memory control registers
;ldr r0,=SMRDATA
adrl r0, SMRDATA ;be careful!
ldr r1,=BWSCON ;BWSCON Address
add r2, r0, #52 ;End address of SMRDATA
0
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne %B0
這段是功能寄存器初始化,把13 個存儲控制器的內(nèi)容批量的讀取到了對應(yīng)的特殊功能
寄存器中,首先是下面有一個數(shù)據(jù)區(qū)SMRDATA,在程序的后面有定義,這個數(shù)據(jù)區(qū)給13 個寄存器分配52 字節(jié)的地址空間。在上面的代碼中,r0 是這個數(shù)據(jù)區(qū)的起始地址,r2 是數(shù)據(jù)區(qū)的結(jié)束地址,r1 是寄存器的起始地址。這樣,用一個判斷語句就可以把內(nèi)存中的數(shù)據(jù)賦給這13 個存儲控制寄存器了。
評論