This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

problems with the startup file

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

Parents
  • it seems that you're right....

    Reset_Addr      DCD     Reset_Handler
    Undef_Addr      DCD     Undef_Handler
    SWI_Addr        DCD     SWI_Handler
    PAbt_Addr       DCD     PAbt_Handler
    DAbt_Addr       DCD     DAbt_Handler
                    DCD     0               ; Reserved Address
    IRQ_Addr        DCD     IRQ_Handler
    FIQ_Addr        DCD     FIQ_Handler
    

    thank you very much for your fast help.

    best regards
    Scott

Reply
  • it seems that you're right....

    Reset_Addr      DCD     Reset_Handler
    Undef_Addr      DCD     Undef_Handler
    SWI_Addr        DCD     SWI_Handler
    PAbt_Addr       DCD     PAbt_Handler
    DAbt_Addr       DCD     DAbt_Handler
                    DCD     0               ; Reserved Address
    IRQ_Addr        DCD     IRQ_Handler
    FIQ_Addr        DCD     FIQ_Handler
    

    thank you very much for your fast help.

    best regards
    Scott

Children
  • the next problem is that I can not debug the programm (stored in the external nor flash device).

    I use the same debug init configuration file as in the lowlevelinit function (within the startup file).

    When I start the debug session, the processor is always starting in the supervisor mode (not the user mode) and there are no information about the c-code in the disassembly...

    DEFINE INT  Entry;
    Entry = 0x10000000;
    
    
    
     _WDWORD(0xFFFFFD08, 0xA5000301);     // user reset enable
     _WDWORD(0xFFFFFD44, 0x00008000);     // disable watchdog
    
    
     // turn on the main oscillator and wait 50ms (~400
     // slow clocks).
     _WDWORD(0xFFFFFC20, 0x00002001);   // CKGR_MOR: Enable main oscillator
     _sleep_(100);                      // Wait for stable Main Oscillator
    
     // enable PLLA for 198.656Mhz
     //[18.432 Main / DIVA x MULA + 1] = 18.432 Main/9 x 97
     // MULA = 96, OUTA = 0x10 (190-240MHz), PLLACOUNT = 63, DIVA = 9.
     _WDWORD(0xFFFFFC28, 0x2060BF09);
     _sleep_(100);
    
    
     // Enable the clocks to all the on-chip peripherals
     _WDWORD(0xFFFFFC10, 0xed2fff9f);     // PMC_PCER
    
    
     //nor flash config
    
     // Configure EBI
     //   AT91C_BASE_CCFG->CCFG_EBI0CSA |= AT91C_EBI_CS3A_SM;
     _WDWORD (0xFFFFED20, 0x00000000);
    
     //Setup register for CS0 0xFFFFE400
     _WDWORD(0xFFFFE400, 0x05050505);
    
     //pulse register for CS0 OxFFFFE404
     _WDWORD(0xFFFFE404, 0x0f0f0f0f);
    
     //cycle register for CS0 0xFFFFE408
     _WDWORD(0xFFFFE408, 0x002f002f);
    
     //mode register for CS0 0xFFFFE40C
     _WDWORD(0xFFFFE40C, 0x00041003);
    
    
     // set Master Clock divide by 2.
     _WDWORD(0xFFFFFC30, 0x00000000);
     _sleep_(100);
    
     //PLLA MDIV_2
     _WDWORD(0xFFFFFC30, 0x00000102);
     _sleep_(100);
    
     PC = Entry;
    exec("g,main");
    

    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");
    

    best regards
    Scott

  • 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.

  • Hi Andrew,

    Thanks for your help.


    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".

    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.