Make newlib use heap_5 for non-contiguous memory regions

Hi all, I have encountered a need that I’m not sure how to handle. Essentially, I have a set of non-adjacent memory regions that I would like to use and so it kind of made sense to me to attempt to make newlib use heap_5.c. To note, I have started with Dave Nadler’s heap_useNewLib solution and has been used successfully so far. I would like to keep only one memory management system as it is now, and not a separate memory management system for FreeRTOS and one for newlib.

I started going down the path of replacing the _sbrk_r implementation to simply forward calls to heap_5’s pvPortMalloc implementation. Then also wrapped the free function to simply forward the call to heap_5’s vPortFree. I verified my application does not use realloc, which is something that FreeRTOS doesn’t have equivalent port version as already pointed out by Dave in his article. I kept the __malloc_lock and __malloc_unlock functions intact but not sure it’s actually needed since heap_5’s pvPortMalloc implementation already calls vTaskSuspendAll/vTaskSuspendResume.

Initial testing shows that it works properly for allocating memory (calling new and malloc) and it uses the non-contiguous memory regions appropriately. However, I seem to have an issue when calling delete or free. a configASSERT gets hit because pxLink->pxNextFreeBlock != NULL. I haven’t figured out why this is happening.

Overall, am I going about this the right way, which bubbles up to attempting to make newlib use FreeRTOS memory management? Has anyone already solved this and/or have any suggestions to recommend? Thanks in advance.

vPortFree should only be given memory pointers that vPortMalloc has returned, and since in your case, those are from calls to _sbrk_r, which is divided into sub-regions by malloc, so it hands out other addresses that vPortMalloc doesn’t give, that won’t work.

If you want newLib to just use the FreeRTOS Heap, then wrap BOTH malloc and free (and the _r version) to forward them to vPortMalloc and vPortFree (and maybe realloc to trap on calls to it that aren’t supported).

Thanks Richard. I did go down this route you suggested and it is working. Much appreciated.