Using stdlib function out of Freertos enviroment

Hi, i like to use a httpclient found on the internet. Basically its written for a PC, but its tiny enough to be used in an embedded platform like a stm32. It uses many stdlib function like malloc, calloc, free & realloc etc… There are also other libary on the system already running. All of them uses its kind of memory management themselves but are configureable to use stdlib function. So my idea is to let them all use stdlib. Any experience on that.

See FreeRTOS - Memory management options for the FreeRTOS small footprint, professional grade, real time kernel (scheduler)

Using heap_3 makes FreeRTOS use thread safe calls to the stdlib malloc and free, but the application’s use of malloc and free won’t be thread safe unless you use something like newlib and provide the lock implementations yourself.

An alternative is to map malloc and free to FreeRTOS’s pvPortMalloc and vPortFree, so all allocations and frees are thread safe. Best then to use heap_4. Mapping can be done using the compiler command line, or providing your own malloc and free functions that do nothing but call the kernel’s pvPortMalloc and vPortFree respectively.

If you are using GCC, you can also consider using --wrap linker option to replace symbols.

Hi, i have tried the last one you suggested. I build a small app on my stm32 and basically mapped all malloc and related functions to freertos and did a http request repeatatly. It worked for a while than it crushed in a hard fault. Any ideas where to look?

This page provides useful resources to debug hard faults on Cortex-M MCUs - Debugging and diagnosing hard faults on ARM Cortex-M CPUs

If it helps, I have had success for years with Richard’s first suggestion above – namely to use heap_3 when your application is already stuck with calls to malloc/free. Assuming you are using newlib, you can use heap_3.c, and then also add a file something like this:

// newlib_malloc_helpers.c

#include <stdint.h>
#include <reent.h>
#include <malloc.h>
#include <errno.h>
#include "FreeRTOS.h"
#include "task.h"

//      These values come from the linker file.
//
extern uint8_t _heapStart;  // located at the first byte of heap
extern uint8_t _heapEnd;    // located at the first byte after the heap

static uint8_t* currentHeapPos = &_heapStart;

size_t xPortGetFreeHeapSize( void )
{
   struct mallinfo info = mallinfo();
   return ( info.fordblks + (size_t)(&_heapEnd - currentHeapPos) );
}

//      The application may choose to override this function.  Note that
// after this function runs, the malloc-failed hook in FreeRTOS is likely
// to be called too.  It won't be called, however, if we're here due to a
// "direct" call to malloc(), not via pvPortMalloc(), such as a call made
// from inside newlib.
//
__weak void sbrkFailedHook( ptrdiff_t size )
{
   configASSERT(0);
}

//      The implementation of _sbrk_r() included in some builds of newlib
// doesn't enforce a limit in heap size.  This implementation does.
//
void* _sbrk_r(struct _reent *reent, ptrdiff_t size)
{
   void* returnValue;

   if (currentHeapPos + size > &_heapEnd)
   {
      sbrkFailedHook(size);

      reent->_errno = ENOMEM;
      returnValue = (void*)-1;
   }
   else
   {
      returnValue = (void*)currentHeapPos;
      currentHeapPos += size;
   }

   return (returnValue);
}

//      In the pre-emptive multitasking environment provided by FreeRTOS,
// it's possible (though unlikely) that a call from newlib code to the
// malloc family might be preempted by a higher priority task that then
// makes a call to the malloc family.  These implementations of newlib's
// hook functions protect against that.  Most calls to this function come
// via pvPortMalloc(), which has already suspended the scheduler, so the
// call here is redundant most of the time.  That's OK.
//
void __malloc_lock(struct _reent *r)
{
   vTaskSuspendAll();
}

void __malloc_unlock(struct _reent *r)
{
   xTaskResumeAll();
}

Jeff’s code really needs adding to an FAQ - or at least - the FAQ answer should link to that post.

1 Like