Gio
Gio

Reputation: 71

STM32 - Dynamic Memory Allocation Implementation, how to correctly implement the _sbrk function?

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?

Upvotes: 2

Views: 6411

Answers (3)

nielsen
nielsen

Reputation: 7594

Using STM32CubeMX (e.g. integrated in STM32CubeIDE), the generated code will include an implementation of _sbrk() as needed for dynamic memory allocation. This is found in the file sysmem.c.

Upvotes: 1

Clifford
Clifford

Reputation: 93456

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.

Upvotes: 3

Marcus Müller
Marcus Müller

Reputation: 36337

sbrk is a function that makes sense on a system having an MMU running an operating system that guarantees separate memory spaces for separate process.

You don't seem to have any of that. So, asking for sbrk's functionality makes absolutely no sense.

What you need to do to implement that is to first implement an operating system that makes use of the MMU that your hardware doesn't have – it has an MPU.

So, all in all, no, this won't work out. sbrk is not something you get without an OS and without an MMU.

If you actually want to have dynamic memory allocation on your STM32, you will have to use a library (or write one yourself) that implements a memory pool, and then you can do malloc/free (or however you want to call them) yourself.

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.

Uh-oh; bare metal, and dynamic memory allocations?

Realistically: You have a nice microcontroller, and you'll want to run an RTOS on it. No excuses, really – it doesn't make anything slower, and uses negligibly little memory, but makes your programming much safer and easier.

Most modern RTOSes have Memory Heaps and allocators. ChibiOS definitely does, maybe you'll want to read FreeRTOS documentation on memory management before starting anything yourself.

Upvotes: 3

Related Questions