Martin Allard
Martin Allard

Reputation: 293

Implementing malloc with gcc in an arm7 problems : malloc return NULL

I am adding malloc support in my firmware and I think I'm missing something!

I use code sourcery g++ lite library for an arm7tdmi processor and my code is based on the example found in this link : http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/473/t/44452.aspx#539503

I added my version of _sbrk :

char * _sbrk(int incr)
{
    //extern char _end; /* Defined by the linker */
    static char *heap_end;
    char *prev_heap_end;
    register char* stackPtr;

    if (heap_end == 0)
    {
        // first allocation
        heap_end =HEAP_END;
    }

    prev_heap_end = heap_end;

    // get current stack pointer
    asm ("mov %0, sp\n\t" : "=r" (stackPtr) );



    if (heap_end + incr > stackPtr) {
        return NULL;// error - no more memory
        //write (1, "Heap and stack collision\n", 25);
        //abort ();
    }
    heap_end += incr;
    return (char*) prev_heap_end;
}

Some defines used by sbrk :

#define SDRAM_SIZE 16*1024*1024        
#define HEAP_BASE  _ebss
#define HEAP_END ((_stext + SDRAM_SIZE) -1)
#define HEAP_SIZE HEAP_END - HEAP_BASE

(_ebss and _stext come from my linker file)

Here's my main where I did a simple malloc/free call :

void C_main ( void)
{
  char * testmalloc=0;
  /* Initialize "Heap Descriptor" pointer */
  pHeapDescriptor =  __rt_embeddedalloc_init ((void*)HEAP_BASE,HEAP_SIZE);
  testmalloc = malloc(2048);
  free(testmalloc);
}

I run this program in step mode. When I call malloc, it eventually call my _sbrk implementation, the return value (prev_heap_end) have an expected value, but when the program return to the main, the testmalloc value is NULL (somewhere in the gcc library, the prev_heap_end is lost).

Does someone have an idea of what I'm doing wrong?

Don't know if that will help, but this is my gcc compilation parameter :

arm-none-eabi-gcc  -march=armv4t -mcpu=arm7tdmi -dp -c 
-Wa,-adhlns="../../Base/Lib/Pa/main.o.lst" -fmessage-length=0 
-fno-zero-initialized-in-bss -MMD -MP -MF"../../Base/Lib/Pa/main.d" 
-MT"../../Base/Lib/Pa/main.d" -fpic -mlittle-endian -Wall -g3 -gdwarf-2  
../../Base/Hardintrf/Mezzanine/main.c -o"../../Base/Lib/Pa/main.o"

Thanks in advance for any help!

Upvotes: 2

Views: 1590

Answers (1)

Pete Fordham
Pete Fordham

Reputation: 2343

if (heap_end == 0)
{
    // first allocation
    heap_end = HEAP_END;
}

This should read:

if (heap_end == 0)
{
    // first allocation
    heap_end = HEAP_BASE;
}

So you don't start your heap at the end of your heap... You might want to think up a better name for that variable then heap_end to avoid this confusion in the first place.

Also you don't need to use the register modifier to make your inline assembly work correctly. The compiler is smart enough to do that for you.

Upvotes: 1

Related Questions