We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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
I add the Download-Section in the debug init file - and now I'm able to debug the programm - but it is very very slow... I checked the registers for the pll and main oscillator and both are correct.
FUNC void Download (void) { // if (Setup & 0x20) { // <s0.80> Command for Loading exec("LOAD test2.axf INCREMENTAL"); // } } Download(); PC = Entry; exec("g,main");
I don't know much about this, and I don't know anything about AT91SAM9263.
Is that "storing the program in the external nor flash device" a standard/general way to use AT91SAM9263?
If it is not, then you will need some extra handling for both run-time and debug-time. And personally, I think that the extra handling for debug-time is annoying.
For NXP LPC2378, the program always starts at 0x00000000, and the processor always goes to 0x00000000 through 0x0000001C looking for its exception handlers. (I guess it is the standard of ARM7 core.)
Though I am not very sure, but I don't think that, "b exception_vector" is an valid exception handler. I think an valid exception handler should be "LDR PC, exception_vector".
So, if your program is not at 0x00000000, your will need an Loader, which runs at RESET, then pass the control to you program. The Loader could be another program, or maybe your Debugger.
If your own exception handlers are not at 0x00000000, you will have to copy them to 0x00000000, or remap them to 0x00000000.
Though I am not very sure, but I think that, when you start to debug, the disassembly window shows the machine code from 0x00000000, if the machine code belongs to your program, you should see some source code with it. If you only see the machine code, you can either trace it to see what will it do, or you should erase it.
(Please kindly correct me.)
I am curious about your KEIL environment.
Is the "debug init config file" a tool from KEIL?
Your "startup file" and "debug init config file" look very strange to me.
See 'Initialization File' here: http://www.keil.com/support/man/docs/uv3/uv3_dg_debug.htm
And an example of its use here: http://www.keil.com/support/man/docs/uv3/uv3_df_createfunct.htm
Hi Andrew,
Thanks for your help.
I did a simple test to make sure that, if "b exception_vector" could be a valid exception handler/vector. And I found that, it is not; but why?
BL will overwrite R14, But B will not.
In my test case, my SWI_handler is at 0x0000057C; so B from 0x00000008 to 0x0000057C is still within 2K Bytes.
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.