?? cstartup.s79
字號:
#include "AT91SAM7S64_inc.h"
;-----------------------------------------------------------------------------
; ?RESET
; 復位向量。通常INTVEC段被連接到0地址,為程序調試方便,也可以將其放在其它地址。
;-----------------------------------------------------------------------------
PROGRAM ?RESET
RSEG INTRAMSTART_REMAP
RSEG INTRAMEND_REMAP
RSEG ICODE:CODE:ROOT(2)
CODE32 ; Always ARM mode after reset
org 0
reset:
;------------------------------------------------------------------------------
;異常向量。
;------------------------------------------------------------------------------
;這些向量可以從0地址或RAM地址讀取,必須采用相對尋址方式以保證跳轉指令的合法性。
;如果異常發生在重映射之前,將導致死循環。
;------------------------------------------------------------------------------
B InitReset ; 0x00 復位句柄
undefvec: B undefvec ; 0x04 未定義指令
swivec: B swivec ; 0x08 軟件中斷
pabtvec: B pabtvec ; 0x0C 預取中止
dabtvec: B dabtvec ; 0x10 數據中止
rsvdvec: B rsvdvec ; 0x14 保留
irqvec: B IRQ_Handler_Entry ; 0x18 IRQ
fiqvec: ; 0x1c FIQ
;------------------------------------------------------------------------------
;- 函數:FIQ_Handler_Entry
;- 說明:FIQ控制器中斷句柄
;- 調用函數:AIC_FVR[interrupt]
;------------------------------------------------------------------------------
FIQ_Handler_Entry:
;由于FIQ還未被承認,故切換管理/用戶模式,允許用戶堆棧訪問C代碼。
mov r9,r0 ;保存R0
ldr r0 , [r8, #AIC_FVR]
msr CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC
stmfd sp!, { r1-r3, r12, lr} ;將暫存寄存器和鏈接寄存器LR保存在用戶堆棧中
mov r14, pc ;跳轉到由AIC_FVR指向的子程序
bx r0
ldmia sp!, { r1-r3, r12, lr} ;從用戶堆棧中恢復暫存寄存器和鏈接寄存器LR
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ ;保持關中斷,切換回FIQ模式
mov r0,r9 ;恢復R0
subs pc,lr,#4 ;恢復程序計數器PC
InitReset:
;------------------------------------------------------------------------------
;由C函數AT91F_LowLevelInit完成的底層初始化(PMC, AIC, ? ....)
;------------------------------------------------------------------------------
EXTERN AT91F_LowLevelInit
#define __iramend SFB(INTRAMEND_REMAP)
;最小C初始化,調用 AT91F_LowLevelInit( void)
ldr r13,=__iramend ;內部RAM中的臨時堆棧
ldr r0,=AT91F_LowLevelInit ;通過交互模式直接調用底層初始化函數
mov lr, pc
bx r0
;-------------------------------------------------------------------------------------
;定義堆棧大小
;
;采用向量時,中斷堆棧要求 2字 x 8 優先級 x 4 字節,假設為FIQ。
;中斷堆棧必須根據中斷句柄進行調整。FIQ中斷不需要堆棧,如果用戶程序需要的話,應在此定義。
;未定義系統堆棧,它取決于空余內部SRAM。
;-------------------------------------------------------------------------------------
;-------------------------------------------------------------------------------------
;定義棧頂
;
;為了提高異常處理和保存/恢復上下文的速度,中斷和管理隊戰定位于內部存儲器的頂部。
;ARM_MODE_SVC(C應用程序)堆棧定位于外部存儲器的頂部。
;-------------------------------------------------------------------------------------
IRQ_STACK_SIZE EQU (3*8*4) ;每個中斷優先級3個字
ARM_MODE_FIQ EQU 0x11
ARM_MODE_IRQ EQU 0x12
ARM_MODE_SVC EQU 0x13
I_BIT EQU 0x80
F_BIT EQU 0x40
;-------------------------------------------------------------------------------------
;為各種模式設置堆棧
;-------------------------------------------------------------------------------------
ldr r0, =__iramend
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT ;設置FIQ模式及堆棧
ldr r8, =AT91C_BASE_AIC ;初始化FIQ寄存器
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT ;設置IRQ模式及堆棧
mov r13, r0 ;初始化FIQ堆棧
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #ARM_MODE_SVC ;允許中斷,設置管理模式及堆棧
mov r13, r0
;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
EXTERN __segment_init
EXTERN main
ldr r0,=__segment_init ;段初始化。
mov lr, pc
bx r0
PUBLIC __main
?jump_to_main:
ldr lr,=?call_exit
ldr r0,=main
__main:
bx r0
;------------------------------------------------------------------------------
;無窮循環
;
;應用結束,通常不會發生。也可以跳轉到復位地址( B 0x0 ).
;------------------------------------------------------------------------------
?call_exit:
End
b End
;------------------------------------------------------------------------------
;異常管理
;
;該模塊中必須保證異常為ARM模式。
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;函數:IRQ_Handler_Entry
;說明:IRQ控制器中斷句柄。
;調用函數:AIC_IVR[interrupt]
;------------------------------------------------------------------------------
IRQ_Handler_Entry:
sub lr, lr, #4 ;異常管理入口,調整并將LR_irq保存到IRQ堆棧
stmfd sp!, {lr}
mrs r14, SPSR ;為嵌套中斷保存SPSR
stmfd sp!, {r14}
stmfd sp!, {r0} ;保存R0到IRQ堆棧
ldr r14, =AT91C_BASE_AIC
ldr r0 , [r14, #AIC_IVR]
str r14, [r14, #AIC_IVR]
msr CPSR_c, #ARM_MODE_SVC ;開中斷并切換到管理模式
stmfd sp!, { r1-r3, r12, r14} ;保存暫存寄存器和鏈接寄存器LR到用戶堆棧
mov r14, pc ;跳轉到由AIC_IVR指向的子程序
bx r0
ldmia sp!, { r1-r3, r12, r14} ;從用戶堆棧恢復暫存寄存器和鏈接寄存器LR
msr CPSR_c, #I_BIT | ARM_MODE_IRQ ;關中斷并切換到IRQ模式
ldr r14, =AT91C_BASE_AIC ;在AIC中標志中斷結束
str r14, [r14, #AIC_EOICR]
ldmia sp!, {r0} ;恢復R0
ldmia sp!, {r14} ;從IRQ堆棧恢復SPSR_irq和R0
msr SPSR_cxsf, r14
ldmia sp!, {pc}^ ;從IRQ堆棧中直接將調整過的LR_irq恢復到PC
;-----------------------------------------------------------------------------------------------
;?EXEPTION_VECTOR
;該模塊僅在需要關閉文件時才被連接。
;-----------------------------------------------------------------------------------------------
PUBLIC AT91F_Default_FIQ_handler
PUBLIC AT91F_Default_IRQ_handler
PUBLIC AT91F_Spurious_handler
CODE32 ; Always ARM mode after exeption
AT91F_Default_FIQ_handler
b AT91F_Default_FIQ_handler
AT91F_Default_IRQ_handler
b AT91F_Default_IRQ_handler
AT91F_Spurious_handler
b AT91F_Spurious_handler
ENDMOD
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -