📄 cstartup.s
字号:
#------------------------------------------------------------------------------
#- ATMEL Microcontroller Software Support - ROUSSET -
#------------------------------------------------------------------------------
# The software is delivered "AS IS" without warranty or condition of any
# kind, either express, implied or statutory. This includes without
# limitation any warranty or condition with respect to merchantability or
# fitness for any particular purpose, or against the infringements of
# intellectual property rights of others.
#-----------------------------------------------------------------------------
#- File source : Cstartup.s79
#- Object : Generic CStartup for IAR No Use REMAP
#- Compilation flag : None
#-
#- 1.0 15/Jun/04 JPP : Creation
#------------------------------------------------------------------------------
.equ RamEnd, 0x00204000
.include "AT91SAM7S64.inc"
#------------------------------------------------------------------------------
#- Area Definition
#------------------------------------------------------------------------------
#---------------------------------------------------------------
# ?RESET
# Reset Vector.
# Normally, segment INTVEC is linked at address 0.
# For debugging purposes, INTVEC may be placed at other
# addresses.
# A debugger that honors the entry point will start the
# program in a normal way even if INTVEC is not at address 0.
#-------------------------------------------------------------
.text
# PROGRAM ?RESET
# RSEG INTRAMSTART_REMAP
# RSEG INTRAMEND_REMAP
# RSEG ICODE:CODE:ROOT(2)
.CODE 32 /*; Always ARM mode after reset*/
# org 0
entry:
#------------------------------------------------------------------------------
#- Exception vectors
#--------------------
#- These vectors can be read at address 0 or at RAM address
#- They ABSOLUTELY requires to be in relative addresssing mode in order to
#- guarantee a valid jump. For the moment, all are just looping.
#- If an exception occurs before remap, this would result in an infinite loop.
#- To ensure if a exeption occurs before start application to infinite loop.
#------------------------------------------------------------------------------
B InitReset /* 0x00 Reset handler*/
undefvec:
B undefvec /* 0x04 Undefined Instruction */
swivec:
B swivec /* 0x08 Software Interrupt*/
pabtvec:
B pabtvec /* 0x0C Prefetch Abort*/
dabtvec:
B dabtvec /* 0x10 Data Abort*/
rsvdvec:
B rsvdvec /* 0x14 reserved*/
irqvec:
B IRQ_Handler_Entry /* 0x18 IRQ*/
fiqvec: /* 0x1c FIQ*/
#------------------------------------------------------------------------------
#- Function : FIQ_Handler_Entry
#- Treatments : FIQ Controller Interrupt Handler.
#- Called Functions : AIC_FVR[interrupt]
#------------------------------------------------------------------------------
FIQ_Handler_Entry:
#- Switch in SVC/User Mode to allow User Stack access for C code
# because the FIQ is not yet acknowledged
#- Save and r0 in FIQ_Register
mov r9, r0
ldr r0, [r8, #AIC_FVR]
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_SVC
#- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, lr}
#- Branch to the routine pointed by the AIC_FVR
mov r14, pc
bx r0
#- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, lr}
#- Leave Interrupts disabled and switch back in FIQ mode
msr CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ
#- Restore the R0 ARM_MODE_SVC register
mov r0,r9
#- Restore the Program Counter using the LR_fiq directly in the PC
subs pc,lr,#4
InitReset:
#------------------------------------------------------------------------------
#- configure the reset mode register . user reset enable
#------------------------------------------------------------------------------
ldr r0,=0xFFFFFD08
ldr r1,=0xa5000001
str r1,[r0]
#------------------------------------------------------------------------------
#- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit
#------------------------------------------------------------------------------
.EXTERN AT91F_LowLevelInit
#define __iramend SFB(INTRAMEND_REMAP)
#- minumum C initialization
#- call AT91F_LowLevelInit( void)
ldr r13,=RamEnd /*; temporary stack in internal RAM*/
#--Call Low level init function in ABSOLUTE through the Interworking
ldr r0,=AT91F_LowLevelInit
mov lr, pc
bx r0
#------------------------------------------------------------------------------
#- Stack Sizes Definition
#------------------------
#- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using
#- the vectoring. This assume that the IRQ management.
#- 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 definehere.
#- The System stack size is not defined and is limited by the free internal
#- SRAM.
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#- Top of Stack Definition
#-------------------------
#- Interrupt and Supervisor Stack are located at the top of internal memory in
#- order to speed the exception handling context saving and restoring.
#- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory.
#------------------------------------------------------------------------------
.equ IRQ_STACK_SIZE, (2*8*4) /*; 2 words per interrupt priority level*/
.equ ARM_MODE_FIQ, 0x11
.equ ARM_MODE_IRQ, 0x12
.equ ARM_MODE_SVC, 0x13
.equ I_BIT , 0x80
.equ F_BIT , 0x40
#------------------------------------------------------------------------------
#- Setup the stack for each mode
#-------------------------------
ldr r0, =RamEnd
#- Set up Fast Interrupt Mode and set FIQ Mode Stack
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
#- Init the FIQ register
ldr r8, =AT91C_BASE_AIC
#- Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
mov r13, r0 /*; Init stack IRQ*/
sub r0, r0, #IRQ_STACK_SIZE
#- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack
msr CPSR_c, #ARM_MODE_SVC
mov r13, r0
#---------------------------------------------------------------
# ?CSTARTUP
#---------------------------------------------------------------
# .EXTERN __segment_init
# Initialize segments.
# __segment_init is assumed to use
# instruction set and to be reachable by BL from the ICODE segment
# (it is safest to link them in segment ICODE).
# ldr r0,=__segment_init
# mov lr, pc
# bx r0
#------------------------------------------------------------------------------
#- Initialise C variables
#------------------------
#- Following labels are automatically generated by the linker.
#- RO: Read-only = the code
#- RW: Read Write = the data pre-initialized and zero-initialized.
#- ZI: Zero-Initialized.
#- Pre-initialization values are located after the code area in the image.
#- Zero-initialized datas are mapped after the pre-initialized.
#- Note on the Data position :
#- If using the ARMSDT, when no -rw-base option is used for the linker, the
#- data area is mapped after the code. You can map the data either in internal
#- SRAM ( -rw-base=0x40 or 0x34) or in external SRAM ( -rw-base=0x2000000 ).
#- Note also that to improve the code density, the pre_initialized data must
#- be limited to a minimum.
#------------------------------------------------------------------------------
.extern Image_RO_Limit /* End of ROM code (=start of ROM data) */
.extern Image_RW_Base /* Base of RAM to initialise */
.extern Image_ZI_Base /* Base and limit of area */
.extern Image_ZI_Limit /* to zero initialise */
ldr r0, =Image_RO_Limit /* Get pointer to ROM data */
ldr r1, =Image_RW_Base /* and RAM copy */
ldr r3, =Image_ZI_Base /* Zero init base => top of initialised data */
cmp r0, r1 /* Check that they are different */
beq NoRW
LoopRw: cmp r1, r3 /* Copy init data */
ldrcc r2, [r0], #4
strcc r2, [r1], #4
bcc LoopRw
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
.EXTERN Main
.global __main
jump_to_main:
ldr lr,=call_exit
ldr r0,=Main
__main:
bx r0
#------------------------------------------------------------------------------
#- Loop for ever
#---------------
#- End of application. Normally, never occur.
#- Could jump on Software Reset ( B 0x0 ).
#------------------------------------------------------------------------------
call_exit:
End:
b End
#------------------------------------------------------------------------------
#- Manage exception
#---------------
#- This module The exception must be ensure in ARM mode
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
#- Function : IRQ_Handler_Entry
#- Treatments : IRQ Controller Interrupt Handler.
#- Called Functions : AIC_IVR[interrupt]
#------------------------------------------------------------------------------
IRQ_Handler_Entry:
#- Manage Exception Entry
#- Adjust and save LR_irq in IRQ stack
sub lr, lr, #4
stmfd sp!, {lr}
#- Save and r0 in IRQ stack
stmfd sp!, {r0}
#- Write in the IVR to support Protect Mode
#- No effect in Normal Mode
#- De-assert the NIRQ and clear the source in Protect Mode
ldr r14, =AT91C_BASE_AIC
ldr r0 , [r14, #AIC_IVR]
str r14, [r14, #AIC_IVR]
#- Enable Interrupt and Switch in Supervisor Mode
msr CPSR_c, #ARM_MODE_SVC
#- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, r14}
#- Branch to the routine pointed by the AIC_IVR
mov r14, pc
bx r0
#- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, r14}
#- Disable Interrupt and switch back in IRQ mode
msr CPSR_c, #I_BIT | ARM_MODE_IRQ
#- Mark the End of Interrupt on the AIC
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AIC_EOICR]
#- Restore SPSR_irq and r0 from IRQ stack
ldmia sp!, {r0}
#- Restore adjusted LR_irq from IRQ stack directly in the PC
ldmia sp!, {pc}^
#---------------------------------------------------------------
# ?EXEPTION_VECTOR
# This module is only linked if needed for closing files.
#---------------------------------------------------------------
.global AT91F_Default_FIQ_handler
.global AT91F_Default_IRQ_handler
.global AT91F_Spurious_handler
.CODE 32 /*; 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 + -