LPC2114啟動代碼分析
1.異常向量表的建立
2.MCU各種模式堆棧的初始化
3.系統(tǒng)基本的初始化工作
下面分別進行介紹.
(一)ARM相關(guān)指令及偽指令
LDR PC,ResetAddr
將ResetAddr標號地址所指的內(nèi)容傳送給PC寄存器
LDR PC,=ResetAddr
將ResetAddr標號地址傳送給PC寄存器
ResetAddr DCD ResetInit
為ResetAddr分配一個字的地址空間,以ResetInit初始化,即ResetAddr地址所指的內(nèi)容為ResetInit標號地址
SvcStackSpace Space SVC_STACK_LENGTH*4
為SvcStackSpace分配一塊SVC_STACK_LENGTH*4大小的地址區(qū)域,并以0初始化區(qū)域內(nèi)容
(二)異常向量表的建立
異常是有內(nèi)部或外部源產(chǎn)生的,以引起處理器處理的一個事件,異常出現(xiàn)后,CPU強制從異常類型對應(yīng)的固定存儲地址開始執(zhí)行程序,如當IRQ中斷產(chǎn)生后,CPU強制跳轉(zhuǎn)到0x00000018出執(zhí)行代碼,我們要做的就是在這個代碼地址出編寫相應(yīng)的指令,讓它順利執(zhí)行IRQ中斷程序.通常我們會在這里放置一條轉(zhuǎn)移指令,因為0x00000018只給你一個字的編程空間.
程序如下:
AREA vectors,CODE,READONLY
ENTRY
;interrupt vectors
;中斷向量表
Reset
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0xff0]
LDR PC, FIQ_Addr
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
;未定義指令
Undefined
B Undefined
;軟中斷
SoftwareInterrupt
B SoftwareInterrupt
;取指令中止
PrefetchAbort
B PrefetchAbort
;取數(shù)據(jù)中止
DataAbort
B DataAbort
;快速中斷
FIQ_Handler
STMFD SP!, {R0-R3, LR}
BL FIQ_Exception
LDMFD SP!, {R0-R3, LR}
SUBS PC, LR, #4
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
**
**
ResetInit
BL InitStack ;初始化堆棧 Initialize the stack
BL TargetResetInit ;目標板基本初始化 Initialize the target board
;跳轉(zhuǎn)到c語言入口 Jump to the entry point of C program
B __main
我們可以看到,每種異常都有相應(yīng)的處理程序,如:當系統(tǒng)復(fù)位后,程序跳轉(zhuǎn)到0x00000000處執(zhí)行指令,那么就執(zhí)行 LDR PC, ResetAddr,及執(zhí)行ResetInit地址處的代碼,這里放置了BL InitStack指令,負責完成各種模式下堆棧的初始化,接著執(zhí)行BL TargetResetInit,完成目標板基本初始化,最后進入c語言入口,執(zhí)行main函數(shù).
(三)MCU各種模式堆棧的初始化
由于各種異常模式下都有自身的SP堆棧指針,因此就必須先進入各自的異常模式進行SP的設(shè)置,各種模式的切換可以通過改變CPSR來實現(xiàn),程序如下:
InitStack
MOV R0, LR
;Build the SVC stack
;設(shè)置管理模式堆棧
MSR CPSR_c, #0xd3
LDR SP, StackSvc
;Build the IRQ stack
;設(shè)置中斷模式堆棧
MSR CPSR_c, #0xd2
LDR SP, StackIrq
;Build the FIQ stack
;設(shè)置快速中斷模式堆棧
MSR CPSR_c, #0xd1
LDR SP, StackFiq
;Build the DATAABORT stack
;設(shè)置中止模式堆棧
MSR CPSR_c, #0xd7
LDR SP, StackAbt
;Build the UDF stack
;設(shè)置未定義模式堆棧
MSR CPSR_c, #0xdb
LDR SP, StackUnd
;Build the SYS stack
;設(shè)置系統(tǒng)模式堆棧
MSR CPSR_c, #0x5f
LDR SP, =StackUsr
MOV PC, R0
**
**
StackSvc DCD SvcStackSpace + (SVC_STACK_LEGTH - 1)* 4
StackIrq DCD IrqStackSpace + (IRQ_STACK_LEGTH - 1)* 4
StackFiq DCD FiqStackSpace + (FIQ_STACK_LEGTH - 1)* 4
StackAbt DCD AbtStackSpace + (ABT_STACK_LEGTH - 1)* 4
StackUnd DCD UndtStackSpace + (UND_STACK_LEGTH - 1)* 4
**
**
;/* 分配堆??臻g */
AREA MyStacks, DATA, NOINIT, ALIGN=2
SvcStackSpace SPACE SVC_STACK_LEGTH * 4 ;Stack spaces for Administration Mode 管理模式堆??臻g
IrqStackSpace SPACE IRQ_STACK_LEGTH * 4 ;Stack spaces for Interrupt ReQuest Mode 中斷模式堆??臻g
FiqStackSpace SPACE FIQ_STACK_LEGTH * 4 ;Stack spaces for Fast Interrupt reQuest Mode 快速中斷模式堆??臻g
AbtStackSpace SPACE ABT_STACK_LEGTH * 4 ;Stack spaces for Suspend Mode 中止義模式堆棧空間
UndtStackSpace SPACE UND_STACK_LEGTH * 4 ;Stack spaces for Undefined Mode 未定義模式堆棧
****
***
AREA Stacks, DATA, NOINIT
StackUsr
說明:MSR CPSR_c, #XX指令完成各種異常模式的切換,如切換到IRQ模式,則執(zhí)行MSR CPSR_c, #0xd2,而SP的值由SvcStackSpace的地址加上SVC_STACK_LEGTH 的所指的大小而定.
(四)系統(tǒng)基本的初始化工作
完成堆棧初始化后執(zhí)行BL TargetResetInit,它負責系統(tǒng)一些基本的初始化,如地址重映射,PLL時鐘初始化,VIC中斷初始化等,具體代碼見Easy Arm2100開發(fā)版的target.c文件.
最后,執(zhí)行B __main,__main是ADS的一個系統(tǒng)函數(shù),它負責一些初始化環(huán)境然后執(zhí)行用戶的main函數(shù).
評論