EmbDev.net

Forum: ARM programming with GCC/GNU tools Trying to get C++ projct running on AT91SAM9G20-EK on SDRAM


Author: Robin Mueller (Guest)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Hi there,

I've been trying for some days to get a C++ project running. 
Unfortunately, there appears to be a problem with the board startup 
script and the linker script which were provided and are propably 
generated. These files we initially not intended to incorporate C++ code 
so now we're trying to adapt them to do just that. We are also using 
freeRTOS. I attached the code of the two files
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support
 * ----------------------------------------------------------------------------
 * Copyright (c) 2008, Atmel Corporation

 * ----------------------------------------------------------------------------
 */

/*------------------------------------------------------------------------------
 *      Linker script for running in external SDRAM on the AT91SAM9G20
 *----------------------------------------------------------------------------*/
 
_Min_Heap_Size = 0x400;      /* required amount of heap. Added manually  */
_Min_Stack_Size = 0x800;    /* required amount of stack. Added manually */

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(entry)

MEMORY
{
    sram0 (W!RX) : ORIGIN = 0x200000, LENGTH = 16K
    sram1 (W!RX) : ORIGIN = 0x300000, LENGTH = 16K
    sdram (W!RX) : ORIGIN = 0x20000000, LENGTH = 32M /* this board provided 64M, but we are just using  32M to model another device which only has 32M external SDRAM */
 }

SECTIONS
{
    .fixed :
  {
        . = ALIGN(4);      /* tells the linker that these section ought to be word aligned */
        _sfixed = .;
    KEEP(*(.startup));
        *(.text*)        /* Code is placed in .text */
        *(.rodata*)        /* global variables marked as const. are placed in .rodata */
        *(.glue_7)        /* glue arm to thumb code */
        *(.glue_7t)        /* glue thumb to arm code */
        *(.eh_frame)
        *(.data)
        *(.data*)        /* contains all initialized global and static variables */
        *(.CP15_*)  /* required for system control coprocessor? */
        KEEP (*(.init))
      KEEP (*(.fini))
        . = ALIGN(4);
    /* preinit data */
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP(*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
    
    . = ALIGN(4);
    /* init data, the constructors are placed in this sections */
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP(*(SORT(.init_array.)))
    KEEP(*(.init_array))
    PROVIDE_HIDDEN (__init_array_end = .);
    
    . = ALIGN(4);
    /* finit data, destructors are placed in this section */
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP(*(SORT(.fini_array.)))
    KEEP(*(.fini_array))
    PROVIDE_HIDDEN (__fini_array_end = .);
  } >sdram

  .ARM.extab (NOLOAD) : {
    *(.ARM.extab* .gnu.linkonce.armextab.*)
  } >sdram 
    
  __exidx_start = .;
    .ARM.exidx (NOLOAD) : {
    *(.ARM.exidx* .gnu.linkonce.armexidx.*)
  } > sdram
    __exidx_end = .;
    _efixed = .;

    .prerelocate : AT (_efixed) /* all relocation stuff is pretty much taken from atmel */
    {
        . = ALIGN(4);
        _sprerelocate = .;
        . = ALIGN(4);
        _eprerelocate = .;
    }

    .postrelocate : AT (_sprerelocate + SIZEOF(.prerelocate))
    {
        . = ALIGN(4);
        _spostrelocate = .;
        KEEP(*(.vectors));
    *(.sramfunc)
        *(.ramfunc)
        . = ALIGN(4);
        _epostrelocate = .;
    } >sram0
    

    /* this section holds uninitialized global and static data  */
   . = ALIGN(4);
  .bss :
    {
      /* This is used by the startup in order to initialize the .bss secion */
      _sbss = .;         /* define a global symbol at bss start */
      __bss_start__ = _sbss;
      *(.bss)
      *(.bss*)
      *(COMMON)
  
      . = ALIGN(4);
      _ebss = .;         /* define a global symbol at bss end */
      __bss_end__ = _ebss;
    } >sdram

    /* User_heap_stack section, used to check that there is enough RAM left */
    ._user_heap_stack :
    {
      . = ALIGN(4);
      PROVIDE ( end = . );
      PROVIDE ( _end = . );
      . = . + _Min_Heap_Size;
      . = . + _Min_Stack_Size;
      . = ALIGN(4);
    } >sdram

  /* top of stack */
    _sstack = 0x22000000 - 1024;
}


And the start up script:
/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * --------------------------------------------------------------------------
  * Copyright (c) 2008, Atmel Corporation
* ----------------------------------------------------------------------------
 */

//------------------------------------------------------------------------------
//         Headers
//------------------------------------------------------------------------------

#include "board.h"

//------------------------------------------------------------------------------
//         Definitions
//------------------------------------------------------------------------------

#define IRQ_STACK_SIZE   8*3*4

#define ARM_MODE_ABT     0x17
#define ARM_MODE_FIQ     0x11
#define ARM_MODE_IRQ     0x12
#define ARM_MODE_SVC     0x13

#define I_BIT            0x80
#define F_BIT            0x40

//------------------------------------------------------------------------------
//         Startup routine
//------------------------------------------------------------------------------

            .align      4
            .arm
        
/* Exception vectors
 *******************/
            .section    .vectors, "a", %progbits

resetVector:
        ldr     pc, =resetHandler       /* Reset */
undefVector:
        b       undefVector             /* Undefined instruction */
swiVector:
    ldr     pc, =vPortYieldProcessor /* 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, lr}

/* Write in the IVR to support Protect Mode */
        ldr     lr, =AT91C_BASE_AIC
        ldr     r0, [lr, #AIC_IVR]
        str     lr, [lr, #AIC_IVR]

/* Branch to interrupt handler in Supervisor mode */
        msr     CPSR_c, #ARM_MODE_SVC
        stmfd   sp!, {r1-r3, r4, r12, lr}
        blx     r0
        
/* Restore scratch/used registers and LR from User Stack */
/* Disable Interrupt and switch back in IRQ mode */      
        ldmia   sp!, {r1-r3, r4, r12, lr}
        msr     CPSR_c, #ARM_MODE_IRQ | I_BIT

/* Acknowledge interrupt */
        ldr     lr, =AT91C_BASE_AIC
        str     lr, [lr, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
        ldmia   sp!, {r0, lr}
        msr     SPSR_cxsf, lr
        ldmia   sp!, {pc}^

//------------------------------------------------------------------------------
/// Initializes the chip and branches to the main() function.
//------------------------------------------------------------------------------
            .section    .text
            .global     entry

entry:
resetHandler:

/* Useless instruction for referencing the .vectors section */
        ldr     r0, =resetVector

/* Set pc to actual code location (i.e. not in remap zone) */
      ldr     pc, =1f

/* Initialize the prerelocate segment */
1:
        ldr     r0, =_efixed
        ldr     r1, =_sprerelocate
        ldr     r2, =_eprerelocate
1:
        cmp     r1, r2
        ldrcc   r3, [r0], #4
        strcc   r3, [r1], #4
        bcc     1b

/* Perform low-level initialization of the chip using LowLevelInit() */
        ldr     sp, =_sstack
        stmfd   sp!, {r0}
      ldr     r0, =LowLevelInit
        blx     r0

/* Initialize the postrelocate segment */

        ldmfd   sp!, {r0}
        ldr     r1, =_spostrelocate
        ldr     r2, =_epostrelocate
1:
        cmp     r1, r2
        ldrcc   r3, [r0], #4
        strcc   r3, [r1], #4
        bcc     1b

/* Clear the zero segment */
      ldr     r0, =__bss_start__
        ldr     r1, =__bss_end__
        mov     r2, #0
1:
        cmp     r0, r1
        strcc   r2, [r0], #4
        bcc     1b

/* Setup stacks
 **************/
/* IRQ mode */
        msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
        ldr     sp, =_sstack
        sub     r4, sp, #IRQ_STACK_SIZE

/* Supervisor mode (interrupts enabled) */
        msr     CPSR_c, #ARM_MODE_SVC | F_BIT
        mov     sp, r4

/* Call static constructors */
      ldr r0,=__libc_init_array
    mov lr,pc /* set the return address */
    bx r0 /* the target code can be ARM or THUMB */
/* Branch to main()
 ******************/
        ldr     r0, =main
        blx     r0

/* Loop indefinitely when program is finished */
1:
        b       1b


Do you have any idea why are program is crashing randomly? Right now it 
always crashes and jumps to an adress it is not intended to be. I 
attached the dissassembly when  this happends while debugging.
My guess is that this relates to the two files shown above. Maybe 
something is missing so that C++ is working properly? The program 
crashes when the freeRTOS task scheduler has already started. I hope 
someone has a clue how  to get this working. Especially someone who 
managed to get C++ working on ARM processors. Thanks a lot in advance !

Kind Regards,
Robin

Author: Robin M. (spacefish)
Posted on:

Rate this post
0 useful
not useful
The program does not crash anymore when I comment out code related to 
hardware drivers. The program does not crash when performing these 
functions but crashes at the adresses I have shown in the 2 pictures. 
This is really confusing.
I use the AT91SAM9G20-EK board and provided drivers. This is inside a 
function which is called by performOperation() which crashed
//ATMEL
AT91S_USART * rs232; // do not initialize this register handle, causes problems !
USART_Configure(rs232, AT91C_US_USMODE_NORMAL,9600,BOARD_MCK);
USART_SetReceiverEnabled(rs232, true);
USART_SetTransmitterEnabled(rs232,true);
result = USART_IsDataAvailable(rs232);
if(result==1) {
  info << "Data available !" << std::endl;
}


: Edited by User

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig