Is there a bug in the Newlib heap on the 32F417 Cube IDE library?
I posted details here
https://www.eevblog.com/forum/programming/help-needed-with-some-heap-test-code/
It works if you allocate the same size block each time, or if you start big and allocate progressively smaller ones. But if you start small and allocate progressively bigger ones, it fails at around half the available heap area.
Each block is freed right after allocation.
I was suspecting a bug in _sbrk but the one I use also came from ST and is actually identical to every other one I've seen for embedded. Some look different in the way they pick up the heap base address and top (using symbols defined in the linkfile) and some stupidly limit the heap at the current value of SP, but all are basically the same as mine:
// This is used by malloc().
// The original Newlib version of this, on which the ST code was based
// https://github.com/zephyrproject-rtos/zephyr/blob/main/lib/libc/newlib/libc-hooks.c
// allowed the heap to go all the way up to the current SP value, which is stupid.
// This one sets the limit at the base (lowest memory address) of the stack area.
caddr_t _sbrk(int incr)
{
// These two are defined in the linkfile
extern char end asm("_end"); // end of BSS
extern char top asm("_top"); // base of the general stack
static char *heap_end; // this gets initialised to NULL by C convention
char *prev_heap_end; // this gets initialised on 1st call here
// This sets heap_end to end of BSS, on the first call to _sbrk
if (heap_end == NULL)
heap_end = &end;
prev_heap_end = heap_end;
// top = top of RAM minus size of stack
if ( (heap_end + incr) > &top )
{
errno = ENOMEM; // not apparently used by anything
return (caddr_t) -1;
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
My malloc() and free() functions are mutexed to make them thread safe. The original ST libc.a had empty stubs for mutex functions but since the whole libc.a was not "weak" it had to be weakened with objcopy and then proper calls to FreeRTOS mutexes could be implemented. Accordingly, the _sbrk is also mutex protected. However I am running this test single threaded.
ST do not supply the source for libc.a (and there are many libc.a libs to choose from according to the CPU and whether newlib-nano etc) but I found various candidate sources. Unfortunately all heap sources are massive, 10k lines plus.
