Hi,
I'm using this startup file for the AT91SAM9263 controller.
The main function will be executed - but the programm will only work for approximately a minute (led blinky and trasmitting information by the debug rs232 interface). After that minute everything stops working (at the same time).
Maybe a problem with the heap or stack management, configurated in the startup file?
The starting point in the startup file is (--entry resetHandler) - misc options:
; KEIL startup file for AT91SAM9263 . ARM_MODE_USR EQU 0x10 ARM_MODE_FIQ EQU 0x11 ARM_MODE_IRQ EQU 0x12 ARM_MODE_SVC EQU 0x13 ARM_MODE_ABT EQU 0x17 ARM_MODE_UND EQU 0x1B ARM_MODE_SYS EQU 0x1F I_BIT EQU 0x80 ; when I bit is set, IRQ is disabled F_BIT EQU 0x40 ; when F bit is set, FIQ is disabled AT91C_BASE_AIC EQU 0xFFFFF000 AIC_IVR EQU 0x100 AIC_EOICR EQU 0x130 UND_Stack_Size EQU 0x00000000 SVC_Stack_Size EQU 0x00000100 ABT_Stack_Size EQU 0x00000000 FIQ_Stack_Size EQU 0x00000000 IRQ_Stack_Size EQU 0x00000080 USR_Stack_Size EQU 0x00000400 PRESERVE8 ; Area Definition and Entry Point ; Startup Code must be linked first at Address at which it expects to run. AREA VECTOR, CODE ARM ; Exception Vectors Vectors LDR pc,=resetHandler undefVector b undefVector ; Undefined instruction swiVector b swiVector ; Software interrupt prefetchAbortVector b prefetchAbortVector ; Prefetch abort dataAbortVector b dataAbortVector ; Data abort reservedVector b reservedVector ; Reserved for future use irqVector b irqHandler ; Interrupt fiqVector ; Fast interrupt ;------------------------------------------------------------------------------ ; Handles a fast interrupt request by branching to the address defined in the ; AIC. ;------------------------------------------------------------------------------ fiqHandler b fiqHandler ;------------------------------------------------------------------------------ ; Handles incoming interrupt requests by branching to the corresponding ; handler, as defined in the AIC. Supports interrupt nesting. ;------------------------------------------------------------------------------ irqHandler ; Save interrupt context on the stack to allow nesting */ SUB lr, lr, #4 STMFD sp!, {lr} MRS lr, SPSR STMFD sp!, {r0,r1,lr} ; Write in the IVR to support Protect Mode */ LDR lr, =AT91C_BASE_AIC LDR r0, [r14, #AIC_IVR] STR lr, [r14, #AIC_IVR] ; Branch to interrupt handler in Supervisor mode */ MSR CPSR_c, #ARM_MODE_SVC STMFD sp!, {r1-r4, r12, lr} MOV lr, pc BX r0 LDMIA sp!, {r1-r4, r12, lr} MSR CPSR_c, #ARM_MODE_IRQ | I_BIT ; Acknowledge interrupt */ LDR lr, =AT91C_BASE_AIC STR lr, [r14, #AIC_EOICR] ; Restore interrupt context and branch back to calling code LDMIA sp!, {r0,r1,lr} MSR SPSR_cxsf, lr LDMIA sp!, {pc}^ ;------------------------------------------------------------------------------ ; After a reset, execution starts here, ;------------------------------------------------------------------------------ AREA cstartup, CODE ENTRY ; Entry point for the application ; Reset Handler EXPORT resetHandler IMPORT |Image$$Fixed_region$$Limit| IMPORT |Image$$Relocate_region$$Base| IMPORT |Image$$Relocate_region$$ZI$$Base| IMPORT |Image$$Relocate_region$$ZI$$Limit| IMPORT |Image$$ARM_LIB_STACK$$Base| IMPORT |Image$$ARM_LIB_STACK$$ZI$$Limit| ; Perform low-level initialization of the chip using LowLevelInit() IMPORT LowLevelInit resetHandler ; Set pc to actual code location (i.e. not in remap zone) LDR pc, =label label ; Set up temporary stack (Top of the SRAM) LDR r0, = |Image$$ARM_LIB_STACK$$ZI$$Limit| MOV sp, r0 ; Call Low level init LDR r0, =LowLevelInit MOV lr, pc BX r0 ;Initialize the Relocate_region segment LDR r0, = |Image$$Fixed_region$$Limit| LDR r1, = |Image$$Relocate_region$$Base| LDR r3, = |Image$$Relocate_region$$ZI$$Base| CMP r0, r1 BEQ %1 ; Copy init data 0 CMP r1, r3 LDRCC r2, [r0], #4 STRCC r2, [r1], #4 BCC %0 1 LDR r1, =|Image$$Relocate_region$$ZI$$Limit| MOV r2, #0 2 CMP r3, r1 STRCC r2, [r3], #4 BCC %2 ; Setup Stack for each mode LDR R0, = |Image$$ARM_LIB_STACK$$ZI$$Limit| ; Enter Undefined Instruction Mode and set its Stack Pointer MSR CPSR_c, #ARM_MODE_UND:OR:I_BIT:OR:F_BIT MOV SP, R0 SUB R0, R0, #UND_Stack_Size ; Enter Abort Mode and set its Stack Pointer MSR CPSR_c, #ARM_MODE_ABT:OR:I_BIT:OR:F_BIT MOV SP, R0 SUB R0, R0, #ABT_Stack_Size ; Enter FIQ Mode and set its Stack Pointer MSR CPSR_c, #ARM_MODE_FIQ:OR:I_BIT:OR:F_BIT MOV SP, R0 SUB R0, R0, #FIQ_Stack_Size ; Enter IRQ Mode and set its Stack Pointer MSR CPSR_c, #ARM_MODE_IRQ:OR:I_BIT:OR:F_BIT MOV SP, R0 ; SUB R4, SP, #IRQ_Stack_Size SUB R0, SP, #IRQ_Stack_Size ; Supervisor mode (interrupts enabled) MSR CPSR_c, #ARM_MODE_SVC:OR:I_BIT:OR:F_BIT ; MOV SP, R4 MOV SP, R0 ; SUB R4, SP, #SVC_Stack_Size SUB R0, SP, #SVC_Stack_Size ; Enter User Mode and set its Stack Pointer MSR CPSR_c, #ARM_MODE_USR MOV SP, R0 SUB SL, SP, #USR_Stack_Size ; Enter the C code IMPORT __main LDR R0, =__main BX R0 END
best regards Scott
Is this related to Compiler Behavior? Compiler give me the ASM/Machine code "B 0x00000028", not "B 0x0000057C"
The portion of memory that is re-mapped to allow interrupt processing in different modes includes the interrupt vector area (32 bytes) and an additional 32 bytes for a total of 64 bytes, that facilitates branching to interrupt handlers at distant physical addresses.
Looks like the additional 32 bytes must be used?
http://www.keil.com/forum/docs/thread13351.asp
The solution in ATMEL Bootstrap v1.9 (crt0_gnu.s) is:
It seems that, for GNU toolchain, "b exception_vector" is a valid exception vector.