I'm working on a bare-metal programming project written in C++ on a STM32F401RE board, and I need to implement malloc()
and free()
functions.
I know that dynamic memory allocation on embedded systems is not a good idea, but I need it.
Up to know I understood that in order to use malloc
and free
functions of the C standard library I need to manually implement a function named _sbkr()
, and in order to do so I created a library with this single function and added it to the includes of the main.cpp source code.
The problem is that it doesn't work, when I try to dynamically allocate a variable it returns a NULL pointer.
Generating with gcc the assembly code of the main, it seems that the _sbrk
function is not implemented in the final object which will be uploaded on the board.
How can I Correctly implement this function?
Assuming that you are using Newlib (the usual C library used with GCC on stand-alone systems), then the target specific porting layer ("syscalls") for the C library is defined at https://sourceware.org/newlib/libc.html#Syscalls.
A minimal implementation suitable for standalone (no OS) environments is given there as an example:
caddr_t sbrk(int incr) {
extern char _end; /* Defined by the linker */
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &_end;
}
prev_heap_end = heap_end;
if (heap_end + incr > stack_ptr) {
write (1, "Heap and stack collision\n", 25);
abort ();
}
heap_end += incr;
return (caddr_t) prev_heap_end;
}
Note also that if you are using an RTOS or threading library you will also need to implement __malloc_lock()
and __malloc_unlock()
using your RTOS/thread libraries mutex
call.
Note also that if you use ST's STM32CubeIDE that uses GCC and Newlib and has the syscalls layer implemented already.