📄 cstartup_rom.s
字号:
INCLUDE AT91R40008.inc
;--------------------------------
;- ARM Core Mode and Status Bits
;--------------------------------
ARM_MODE_USER EQU 0x10
ARM_MODE_FIQ EQU 0x11
ARM_MODE_IRQ EQU 0x12
ARM_MODE_SVC EQU 0x13
ARM_MODE_ABORT EQU 0x17
ARM_MODE_UNDEF EQU 0x1B
ARM_MODE_SYS EQU 0x1F
I_BIT EQU 0x80
F_BIT EQU 0x40
T_BIT EQU 0x20
TOP_INTERNAL_MEMORY EQU AT91C_SRAM_BEFORE_REMAP ; 定义Ram的起始地址
TOP_EXCEPTION_STACK EQU (TOP_INTERNAL_MEMORY+AT91C_SRAM_BEFORE_REMAP_SIZE)
IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
IMPORT |Image$$ZI$$Base| ; Base and limit of area
IMPORT |Image$$ZI$$Limit| ; to zero initialise
;------------------------------------------------------------------------------
;- Low level Init (APMC, AIC, EBI, ....) by C function AT91F_LowLevelInit
;------------------------------------------------------------------------------
IMPORT AT91F_LowLevelInit
;------------------------------------------------------------------------------
;- Area Definition
;------------------------------------------------------------------------------
AREA reset, CODE, READONLY
ENTRY
EXPORT entry
entry
;------------------------------------------------------------------------------
;- 中断向量表 ( Remap 之前 )
;------------------------------------------------------------------------------
B InitReset ; Reset handler
undefvec
B undefvec ; Undefined Instruction
swivec
B swivec ; Software Interrupt
pabtvec
B pabtvec ; Prefetch Abort
dabtvec
B dabtvec ; Data Abort
rsvdvec
B rsvdvec ; reserved
irqvec
ldr pc, [pc,#-0xF20] ; IRQ : read the AIC
fiqvec
ldr pc, [pc,#-0xF20] ; FIQ : read the AIC
InitReset
;------------------------------------------------------------------------------
;- 设置临时堆栈,临时堆栈位于REMAP前RAM的最高端
;------------------------------------------------------------------------------
ldr r13,=TOP_EXCEPTION_STACK ; temporary stack in internal Ram
;------------------------------------------------------------------------------
;- 将FLASH中的程序全部搬移到内部RAM中
;- 下面的程序将FLASH中的程序搬移到RAM中
;- 搬移的内容包括:RO-AREA,RW-AREA和ZI-AREA
;------------------------------------------------------------------------------
;- Get the Area Base and Limit
mov r0, #0 ; r0 = 0
ldr r1, =|Image$$ZI$$Limit| ; r1 = End Of ZI AREA
ldr r2, =0x300000 ; r2 = 0x300000,RAM 的基地址
CopyLoop
ldr r10, [r0], #4 ; 将FLASH中的内容拷贝到RAM中
str r10, [r2], #4
cmp r0, r1
blo CopyLoop
;------------------------------------------------------------------------------
;- 将ZI-AREA中的内容清0
;- 下面的程序将FLASH中的程序搬移到RAM中
;- 搬移的内容包括:RO-AREA,RW-AREA和ZI-AREA
;------------------------------------------------------------------------------
ldr r3, =|Image$$ZI$$Base| ; Zero init base => top of initialised data
NoRW ldr r1, =|Image$$ZI$$Limit| ; Top of zero init segment
mov r2, #0
LoopZI cmp r3, r1 ; Zero init
strcc r2, [r3], #4
bcc LoopZI
;------------------------------------------------------------------------------
;- 调用AT91_LowLevevInit初始化填充REMAP寄存器,初始化AIC
;------------------------------------------------------------------------------
; 此时地址位于0x340000
ldr r1,=TOP_INTERNAL_MEMORY ; 传递给AT91F_LowLeverInit的参数2
; 为REMAP前内部RAM的地址
ldr r0,=0x0 ; add r0, pc,#-(8+.-VectorTable)
; @ where to read values (relative)
; 传递给AT91F_lowLevelInit的参数1
; 指示中断向量表的地址
bl AT91F_LowLevelInit ; 填充REMAP寄存器和初始化AIC
; 函数返回值为EBI_RCB寄存器的地址
;--------------------------------------------
;- 完成地址的重新映射,跳转到RAM中指定的位置执行
;- Remap Command and jump on ABSOLUTE address
;--------------------------------------------
ldr r12, PtInitRemap ; Get the real jump address ( after remap )
mov r1,#AT91C_EBI_RCB ; Get the REMAP value
str r1, [r0] ; Store the complete image with the remap command
;- Jump to LINK address at its absolute address
mov pc, r12 ; Jump and break the pipeline
PtInitRemap
DCD InitRemap ; Address where to jump after REMAP
;------------------------------------------------------------------------------
;- 完成REMAP后转此处执行
;- The Reset Handler after Remap
;-------------------------------
;- From here, the code is executed from its link address, ie. 0x100 0000.
;------------------------------------------------------------------------------
InitRemap
;------------------------------------------------------------------------------
;- 初始化堆栈,建立各种模式下的堆栈指针
;- Stack Sizes Definition
;------------------------
;- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using
;- the vectoring. This assume that the IRQ_ENTRY/IRQ_EXIT macro are used.
;- The Interrupt Stack must be adjusted depending on the interrupt handlers.
;- Fast Interrupt not requires stack If in your application it required you must
;- be define here.
;- Other stacks are defined by default to save one word each.
;- The System stack size is not defined and is limited by the free internal
;- SRAM.
;- User stack size is not defined and is limited by the free external SRAM.
;------------------------------------------------------------------------------
IRQ_STACK_SIZE EQU (2*8*4) ; 2 words per interrupt priority level
FIQ_STACK_SIZE EQU (0*4) ; 0 words
ABT_STACK_SIZE EQU (1*4) ; 1 word
UND_STACK_SIZE EQU (1*4) ; 1 word
;------------------------------------------------------------------------------
;- Setup the stack for each mode
;-------------------------------
ldr r0, =AT91C_SRAM_AFTER_REMAP_SIZE
;- Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack FIQ
sub r0, r0, #FIQ_STACK_SIZE
;- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack IRQ
sub r0, r0, #IRQ_STACK_SIZE
;- Set up Abort Mode and set Abort Mode Stack
msr CPSR_c, #ARM_MODE_ABORT:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack Abort
sub r0, r0, #ABT_STACK_SIZE
;- Set up Undefined Instruction Mode and set Undef Mode Stack
msr CPSR_c, #ARM_MODE_UNDEF:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack Undef
sub r0, r0, #UND_STACK_SIZE
;- Set up Supervisor Mode and set Supervisor Mode Stack
msr CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT
mov r13, r0 ; Init stack Sup
;------------------------------------------------------------------------------
;- Before Init C Initialize C variables you can copy the from FLASH to RAM
;------------------------------------------------------------------------------
;Enable interrupt
msr CPSR_c, #ARM_MODE_SVC :OR: F_BIT
;------------------------------------------------------------------------------
;- 跳转到C语言的主程序中执行
;- 跳转之前将堆设置到外部存储区
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;- Branch on C code Main function (with interworking)
;----------------------------------------------------
;- Branch must be performed by an interworking call as either an ARM or Thumb
;- main C function must be supported. This makes the code not position-
;- independent. A Branch with link would generate errors
;------------------------------------------------------------------------------
; IMPORT __use_two_region_memory
; IMPORT __main
; ldr r0, =__main
; mov lr, pc
; bx r0
IMPORT __rt_stackheap_init
IMPORT __rt_lib_init
IMPORT main
BL __rt_stackheap_init
LDR R1, =0x00480000
BL __rt_lib_init
B main
;------------------------------------------------------------------------------
;- Loop for ever
;---------------
;- End of application. Normally, never occur.
;- Could jump on Software Reset ( B 0x0 ).
;------------------------------------------------------------------------------
End
b End
;------------------------------------------------------------------------------
;- Manage exception
;---------------
;- The exception must be ensure in ARM mode
;------------------------------------------------------------------------------
EXPORT AT91F_Default_FIQ_handler
AT91F_Default_FIQ_handler
b AT91F_Default_FIQ_handler
EXPORT AT91F_Default_IRQ_handler
AT91F_Default_IRQ_handler
b AT91F_Default_IRQ_handler
EXPORT AT91F_Spurious_handler
AT91F_Spurious_handler
b AT91F_Spurious_handler
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR r0,=0x00400000 ; Heap start,位于外部RAM
; LDR R2,=0x1007FFFF
MOV pc,lr
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -