EmbDev.net

Forum: ARM programming with GCC/GNU tools Need a help with malloc on AT91SAM7S


von Martin N. (bajzic)


Rate this post
useful
not useful
Hi everybody,

I have a problem with MALLOC using SAM7S256, gnu arm-elf and newlib.

sometimes it works, sometimes it returns zero, sometimes it returns even
negative value, sometimes it doesn't return at all...!!

Has anybody ever had a similar problem? Any advices before I start to
write my own malloc..?

This is my linkerscript:

MEMORY {   /* memory map of AT91SAM7S256 */
    ROM : ORIGIN = 0x00100000, LENGTH = 256k
    RAM : ORIGIN = 0x00200000, LENGTH = 64k
}

_stack_end = 0x20FFFC;

SECTIONS {

    .reset : {
        *startup.o (.text)  /* startup code (ARM vectors and reset
handler) */
        . = ALIGN(0x4);
     } >ROM

    .ramvect : {             /* used for vectors remapped to RAM */
        __ram_start = .;
        . = 0x40;
    } >RAM

    .fastcode : {
        __fastcode_load = LOADADDR (.fastcode);
        __fastcode_start = .;

        *(.glue_7t) *(.glue_7)
        *isr.o (.text.*)
        *(.text.fastcode)
        *(.text.Blinky_dispatch)
        /* add other modules here ... */

        . = ALIGN (4);
        __fastcode_end = .;
    } >RAM AT>ROM

    .text : {
        CREATE_OBJECT_SYMBOLS
        *(.text .text.* .gnu.linkonce.t.*)
        *(.plt)
        *(.gnu.warning)
        *(.glue_7t) *(.glue_7)   /* NOTE: placed already in .fastcode */

        . = ALIGN (4);
        *(.rodata .rodata.* .gnu.linkonce.r.*)

        *(.ARM.extab* .gnu.linkonce.armextab.*)
        *(.gcc_except_table)
        *(.eh_frame_hdr)
        *(.eh_frame)

        *(.init)
        *(.fini)

        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP (*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        PROVIDE_HIDDEN (__fini_array_end = .);
    } >ROM

    _etext = .;

    .data : {
        __data_load = LOADADDR (.data);
        __data_start = .;
        KEEP(*(.jcr))
        *(.got.plt) *(.got)
        *(.shdata)
        *(.data .data.* .gnu.linkonce.d.*)
        . = ALIGN (4);
        _edata = .;
    } >RAM AT>ROM

    .bss SIZEOF(.data) + ADDR(.data): {
  __bss_start = ALIGN(8);
  _bss_start_ = ALIGN(8);
        *(.shbss)
        *(.bss .bss.* .gnu.linkonce.b.*)
        *(COMMON)
        _bss_end_ = ALIGN (8);
    _end = ALIGN(0x8);
     __end = ALIGN(0x8);

    } >RAM
    PROVIDE(end = .);

    .stab 0 (NOLOAD) : {
        *(.stab)
    }

    .stabstr 0 (NOLOAD) : {
        *(.stabstr)
    }

    /* DWARF debug sections.
    * Symbols in the DWARF debugging sections are relative to the
beginning
    * of the section so we begin them at 0.
    */
    /* DWARF 1 */
    .debug          0 : { *(.debug) }
    .line           0 : { *(.line) }
    /* GNU DWARF 1 extensions */
    .debug_srcinfo  0 : { *(.debug_srcinfo) }
    .debug_sfnames  0 : { *(.debug_sfnames) }
    /* DWARF 1.1 and DWARF 2 */
    .debug_aranges  0 : { *(.debug_aranges) }
    .debug_pubnames 0 : { *(.debug_pubnames) }
    /* DWARF 2 */
    .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
    .debug_abbrev   0 : { *(.debug_abbrev) }
    .debug_line     0 : { *(.debug_line) }
    .debug_frame    0 : { *(.debug_frame) }
    .debug_str      0 : { *(.debug_str) }
    .debug_loc      0 : { *(.debug_loc) }
    .debug_macinfo  0 : { *(.debug_macinfo) }
    /* SGI/MIPS DWARF 2 extensions */
    .debug_weaknames 0 : { *(.debug_weaknames) }
    .debug_funcnames 0 : { *(.debug_funcnames) }
    .debug_typenames 0 : { *(.debug_typenames) }
    .debug_varnames  0 : { *(.debug_varnames) }
    .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
    .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
    DISCARD : { *(.note.GNU-stack)  }
}


Thank you!!!

von Clifford S. (clifford)


Rate this post
useful
not useful
Martin Novak wrote:
> Has anybody ever had a similar problem? Any advices before I start to
> write my own malloc..?

I doubt that there is anything wrong with malloc() itself. malloc() (and
in C++ the new and new[] operators) are dependent on the sbrk ans sbrk_r
syscall implementations to work correctly. These are functions that you
must provide (or use examples provided) to glue the C library to your
specific target.

It seems likely that either sbrk() is incorrectly implemented, or that
whatever it is using as the initial heap address or upper limit is
incorrect.

Of course it is also possible that it is working correctly but you are
using it incorrectly. If it returns zero, it implies that no memory is
available. This can happen if you have allocated all available memory,
or if you have allocated and deallocated memory in such a way as to end
up with severe memory fragmentation so so sufficiently large contiguous
block is available to satisfy the request. You may just have a plain
ordinary memory leak!


Martin Novak wrote:
> sometimes it returns even negative value

It returns a pointer not an integer - a pointer cannot be negative. If
you are attempting to use say printf() to display a pointer value use:

printf( "%p", ptr ) ;

which will display ptr as a hexadecimal address. If you used %d any
address >= 0x80000000 will be displayed as a negative value.


> sometimes it doesn't return at all...!!
May happen if sbrk() is flawed, but may also happen if you have
corrupted the heap (by a buffer overrun, or a stack overflow for
example).


Clifford

von Stephen (Guest)


Rate this post
useful
not useful
I'm also having trouble with malloc on the AT91SAM7S-EK.  I'm fairly 
inexperienced, so I could very easily be making some obvious mistake. 
The problem I'm having is pretty blatant; I suspect that I may be 
allocating too much memory, so when I test malloc by intentionally 
allocating too much memory, I can't get it to return a null pointer. 
I'm running this code:

int *rowsptr;
char malloc_error=0;
rowsptr =(int *) malloc(256000*sizeof(int));
if (rowsptr==(void *)0) malloc_error=1;
return(malloc_error);

This is trying to allocate 1MB, and the the chip only has 256k RAM, so 
it should be returning an error.  It does not.  I've really looked 
around the web a lot and I'm not finding anything to help me, so any 
suggestions would be greatly appreciated!

von Clifford S. (clifford)


Rate this post
useful
not useful
You rather hijacked someone else's thread, which is bad form. If you 
thought this thread was relevant you could have started a new thread 
with a link to this one. It is entirely possible (in fact probable) that 
your problem is not the same at all, and that the OP may not have 
finished his discussion - we could then end up having two different 
conversations in one thread.

Stephen wrote:
> I'm also having trouble with malloc on the AT91SAM7S-EK.


Since you have added no more information than the OP, I can only offer 
the same advice. Implementation of sbrk() is your responsibility. If it 
does not correctly return an error condition when an attempt to extend 
the heap out-of-bounds occurs, then malloc() will not return NULL 
either.

von Stephen (Guest)


Rate this post
useful
not useful
ok, right.  got it.  this mistake was just a result of ignorance on my 
part.  if you (or someone else) has the authority to my posts from this 
thread, please feel free to do so.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.