Reentrancy is an attribute of a piece of code and basically means it can re-entered by another execution flow, for example by an interrupt or by another task or thread. This is an important concept and still a lot of code ‘in the wild’ does violate reentrancy. As a result the application crashes immediately in the best case. Worse it crashes randomly or even worse it behaves incorrectly 😦 .
Reentrancy is always a concern if using standard library functions, including printf() or malloc(). FreeRTOS offers a reentrant wrapper to the standard malloc() and free() (Memory Scheme 3)
In this article I show you how you can enable in FreeRTOS a reentrant newlib malloc wrapper, both for FreeRTOS and the rest of the application.
💡 The ‘heap scheme 6’ has been contributed by Dave Nadler. For technical details about how it works I highly recommend that you read his material on http://www.nadler.com/embedded/newlibAndFreeRTOS.html
In this article I’m using the NXP i.MX RT1064 EVK with the MCUXpresso IDE 11.2.1 and MCUXpresso SDK. I’m using FreeRTOS 10.4.1. But in general the steps apply to any IDE, FreeRTOS version and board. The project used in this article is on GitHub.
Enable the Heap Scheme
First, enable the heap scheme 6 (reentrant newlib). One way is to change the following define:
#define configUSE_HEAP_SCHEME (6) /* either 1 (only alloc), 2 (alloc/free), 3 (malloc), 4 (coalesc blocks), 5 (multiple blocks), 6 (newlib) */
If using a different FreeRTOS port, make sure that heap 1 – 5 are either excluded or removed from the the project. The port used here automatically switches to the correct heap implementation using the above macro.
As we are going to use the standard library free and malloc with the reentrancy hooks, need make sure either newlib or newlib-nano is used. So check your linker settings for this. In MCUXpresso IDE I can easily set the library here:
You might check as well the setting in the linker:
Now as we are using the standard library heap, the usual FreeRTOS configTOTAL_HEAP_SIZE has no meaning: I have to configure the heap size in the linker file. The MCUXpresso IDE uses a smart linker files, so the only thing I have to do is to set the heap size for the linker in the project properties:
That’s it. Build the application and use the debugger to verify your application. In case FreeRTOS barks about running out of heap memory, increase the heap size depending on your tasks and task stack sizes.
Note that heap_useNewlib.c comes with a custom sbrk() implementation: so make sure this and the linker symbols matches the comments in the source. As for FreeRTOS port used, the symbols are automatically detected and assigned :-).
Happy mallocing 🙂
- FreeRTOS Memory schemes: https://www.freertos.org/a00111.html
- Using FreeRTOS with newlib: https://mcuoneclipse.com/2017/07/02/using-freertos-with-newlib-and-newlib-nano/
- Article by Dave Nadler: http://www.nadler.com/embedded/newlibAndFreeRTOS.html
- Project used in this article: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/i.MX%20RT1064_EVK/MIMXRT1064_FreeRTOS