Neil
Neil

Reputation: 2147

Why does malloc only work immediately after flashing cortex-m3?

I'm trying to dynamically allocate memory using newlib's malloc running on a cortex-m3 (bare-metal) and I've run into a perplexing problem. Immediately after flashing the device, malloc and free both work as expected. However, once I reset the device malloc only returns NULL. Everything else works except for malloc. Any hints on what could cause this kind of behaviour?

Here is my linker script:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
    SRAM (rwx) : ORIGIN = 0x10000000, LENGTH = 32K
}

/* Section Definitions */
SECTIONS
{
   .text :
  {
    KEEP(*(.isr_vector .isr_vector.*))
    *(.text .text.*)
    *(.gnu.linkonce.t.*)
    *(.glue_7)
    *(.glue_7t)
    *(.gcc_except_table)
    *(.rodata .rodata*)
    *(.gnu.linkonce.r.*)
    _etext = .;
  } > FLASH

  __exidx_start = .;
  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > FLASH
  __exidx_end = .;

  /*.data : AT (_etext)*/
  .data : AT (__exidx_end)
  {
    _data = .;
    *(vtable vtable.*)
    *(.data .data.*)
    *(.gnu.linkonce.d*)
    . = ALIGN(4);
    _edata = . ;
  } > SRAM

  /* .bss section which is used for uninitialized data */
  .bss (NOLOAD) :
  {
    _bss = . ;
    *(.bss .bss.*)
    *(.gnu.linkonce.b*)
    *(COMMON)
    . = ALIGN(4);
    _ebss = . ;
  } > SRAM

  .stackarea (NOLOAD) :
  {
    . = ALIGN(8);
    *(.stackarea .stackarea.*)
    . = ALIGN(8);
  } > SRAM

  . = ALIGN(4);
  _end = . ;
  PROVIDE (end = .);

}

And this is from my memory map:

.stackarea      0x10000d3c        0x4
                0x10000d40                . = ALIGN (0x8)
 *fill*         0x10000d3c        0x4 00
 *(.stackarea .stackarea.*)
                0x10000d40                . = ALIGN (0x8)
                0x10000d40                . = ALIGN (0x4)
                0x10000d40                _end = .
                0x10000d40                PROVIDE (end, .)

When malloc succeeds, it starts allocating at 0x10000d48.

Upvotes: 3

Views: 1240

Answers (2)

Frank
Frank

Reputation: 11

The stack must be on a higher address than the heap.

The stack grow downwards and the heap upwards. So put the stack top on the last address in SRAM The heap starts at the "_end" label and end at the bottom of the stack, so try put the "_end" label right after the "_ebss" label.

eg.

  /* .bss section which is used for uninitialized data */  
  .bss (NOLOAD) :  
  {  
    _bss = . ;  
    *(.bss .bss.*)  
    *(.gnu.linkonce.b*)  
    *(COMMON)  
    . = ALIGN(4);  
    _ebss = . ;  
    **_end = . ;**  
  } > SRAM  

Upvotes: 1

Vern
Vern

Reputation: 2413

I'm not quite sure how it works on your Cortext-M3, but I did have some memory management issues on a RX62N awhile back. In the end, I decided to do my own memory management by creating a large heap and then allocate the memory through my own API functions. I used a simple linked list to do the memory management. This way, I can guarantee that it'll work every time on my board and code :)

Hope it helps :) Cheers!

Upvotes: 1

Related Questions