📄 crt.s
字号:
/* ****************************************************************************************************** */
/* crt.s */
/* */
/* Assembly Language Startup Code for Atmel AT91SAM7S256 */
/* */
/* */
/* */
/* */
/* Author: James P Lynch May 12, 2007 */
/* ****************************************************************************************************** */
/* Stack Sizes */
.set UND_STACK_SIZE, 0x00000010 /* stack for "undefined instruction" interrupts is 16 bytes */
.set ABT_STACK_SIZE, 0x00000010 /* stack for "abort" interrupts is 16 bytes */
.set FIQ_STACK_SIZE, 0x00000080 /* stack for "FIQ" interrupts is 128 bytes */
.set IRQ_STACK_SIZE, 0X00000080 /* stack for "IRQ" normal interrupts is 128 bytes */
.set SVC_STACK_SIZE, 0x00000080 /* stack for "SVC" supervisor mode is 128 bytes */
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set ARM_MODE_USR, 0x10 /* Normal User Mode */
.set ARM_MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set ARM_MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set ARM_MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
.set ARM_MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
.set ARM_MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
.set ARM_MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
/* Addresses and offsets of AIC and PIO */
.set AT91C_BASE_AIC, 0xFFFFF000 /* (AIC) Base Address */
.set AT91C_PIOA_CODR, 0xFFFFF434 /* (PIO) Clear Output Data Register */
.set AT91C_AIC_IVR, 0xFFFFF100 /* (AIC) IRQ Interrupt Vector Register */
.set AT91C_AIC_FVR, 0xFFFFF104 /* (AIC) FIQ Interrupt Vector Register */
.set AIC_IVR, 256 /* IRQ Vector Register offset from base above */
.set AIC_FVR, 260 /* FIQ Vector Register offset from base above */
.set AIC_EOICR, 304 /* End of Interrupt Command Register */
/* identify all GLOBAL symbols */
.global _vec_reset
.global _vec_undef
.global _vec_swi
.global _vec_pabt
.global _vec_dabt
.global _vec_rsv
.global _vec_irq
.global _vec_fiq
.global AT91F_Irq_Handler
.global AT91F_Fiq_Handler
.global AT91F_Default_FIQ_handler
.global AT91F_Default_IRQ_handler
.global AT91F_Spurious_handler
.global AT91F_Dabt_Handler
.global AT91F_Pabt_Handler
.global AT91F_Undef_Handler
/* GNU assembler controls */
.text /* all assembler code that follows will go into .text section */
.arm /* compile for 32-bit ARM instruction set */
.align /* align section on 32-bit boundary */
/* ============================================================ */
/* VECTOR TABLE */
/* */
/* Must be located in FLASH at address 0x00000000 */
/* */
/* Easy to do if this file crt.s is first in the list */
/* for the linker step in the makefile, e.g. */
/* */
/* $(LD) $(LFLAGS) -o main.out crt.o main.o */
/* */
/* ============================================================ */
_vec_reset: b _init_reset /* RESET vector - must be at 0x00000000 */
_vec_undef: b AT91F_Undef_Handler /* Undefined Instruction vector */
_vec_swi: b _vec_swi /* Software Interrupt vector */
_vec_pabt: b AT91F_Pabt_Handler /* Prefetch abort vector */
_vec_dabt: b AT91F_Dabt_Handler /* Data abort vector */
_vec_rsv: nop /* Reserved vector */
_vec_irq: b AT91F_Irq_Handler /* Interrupt Request (IRQ) vector */
_vec_fiq: /* Fast interrupt request (FIQ) vector */
/* ======================================================================== */
/* Function: AT91F_Fiq_Handler */
/* */
/* The FIQ interrupt asserts when switch SW1 is pressed. */
/* */
/* This simple FIQ handler turns on LED3 (Port PA2). The LED3 will be */
/* turned off by the background loop in main() thus giving a visual */
/* indication that the interrupt has occurred. */
/* */
/* This FIQ_Handler supports non-nested FIQ interrupts (a FIQ interrupt */
/* cannot itself be interrupted). */
/* */
/* The Fast Interrupt Vector Register (AIC_FVR) is read to clear the */
/* interrupt. */
/* */
/* A global variable FiqCount is also incremented. */
/* */
/* Remember that switch SW1 is not debounced, so the FIQ interrupt may */
/* occur more than once for a single button push. */
/* */
/* Programmer: James P Lynch */
/* ======================================================================== */
AT91F_Fiq_Handler:
/* Adjust LR_irq */
sub lr, lr, #4
/* Read the AIC Fast Interrupt Vector register to clear the interrupt */
ldr r12, =AT91C_AIC_FVR
ldr r11, [r12]
/* Turn on LED3 (write 0x0008 to PIOA_CODR at 0xFFFFF434) */
ldr r12, =AT91C_PIOA_CODR
mov r11, #0x04
str r11, [r12]
/* Increment the _FiqCount variable */
ldr r12, =FiqCount
ldr r11, [r12]
add r11, r11, #1
str r11, [r12]
/* Return from Fiq interrupt */
movs pc, lr
/* ======================================================================== */
/* _init_reset Handler */
/* */
/* RESET vector 0x00000000 branches to here. */
/* */
/* ARM microprocessor begins execution after RESET at address 0x00000000 */
/* in Supervisor mode with interrupts disabled! */
/* */
/* _init_reset handler: creates a stack for each ARM mode. */
/* sets up a stack pointer for each ARM mode. */
/* turns off interrupts in each mode. */
/* leaves CPU in SYS (System) mode. */
/* */
/* block copies the initializers to .data section */
/* clears the .bss section to zero */
/* */
/* branches to main( ) */
/* ======================================================================== */
.text /* all assembler code that follows will go into .text section */
.align /* align section on 32-bit boundary */
_init_reset:
/* Setup a stack for each mode with interrupts initially disabled. */
ldr r0, =_stack_end /* r0 = top-of-stack */
msr CPSR_c, #ARM_MODE_UND|I_BIT|F_BIT /* switch to Undefined Instruction Mode */
mov sp, r0 /* set stack pointer for UND mode */
sub r0, r0, #UND_STACK_SIZE /* adjust r0 past UND stack */
msr CPSR_c, #ARM_MODE_ABT|I_BIT|F_BIT /* switch to Abort Mode */
mov sp, r0 /* set stack pointer for ABT mode */
sub r0, r0, #ABT_STACK_SIZE /* adjust r0 past ABT stack */
msr CPSR_c, #ARM_MODE_FIQ|I_BIT|F_BIT /* switch to FIQ Mode */
mov sp, r0 /* set stack pointer for FIQ mode */
sub r0, r0, #FIQ_STACK_SIZE /* adjust r0 past FIQ stack */
msr CPSR_c, #ARM_MODE_IRQ|I_BIT|F_BIT /* switch to IRQ Mode */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -