If you create FreeRTOS objects using dynamically allocated memory (for example, if you call xTaskCreate() rather than xTaskCreateStatic()) then FreeRTOS needs to allocate memory. It does that by calling pvPortMalloc() rather than a direct call to malloc(). You can implement pvPortMalloc() to do whatever you want. FreeRTOS comes with five different implementations you can opt to use. If you opt to use heap_3, then pvPortMalloc() basically maps to the standard C library malloc() function (with a bit of housekeeping to ensure it is thread safe). If you use any other of the provided heap implementations then FreeRTOS does not use the standard C library malloc(). If nothing else in your application uses the standard C library malloc() - then you can set to heap defined by your linker script to be 0 bytes long. If anything else in your application does use the standard C library malloc() then you have two options - either ensure the heap defined by your linker script is large enough for anything in your application that calls malloc() directly (FreeRTOS calls portMalloc(), so doesn’t call malloc() unless you use heap_3), or map the C library’s malloc() to pvPortMalloc() (and likewise free() to vPortFree()). In your case it looks like you can do the latter by #define’ing s_malloc to pvPortMalloc.