Infinite loop in vPortGetHeapStats when using heap_5.c


I’m using FreeRTOS V11.0.1 on a LPC55S69 with heap_5 and multiple regions.

I’m trying to get the vPortGetHeapStats function to return heap usage but the code is getting stuck in the while loop.

Here are the important bits. The code is compiled as c++ but it shouldn’t change anything.

Global variables

__attribute__((section(".SRAMX_FreeRTOSHeap"))) static std::array<uint8_t, 0x0'8000> heapSRAMX;
__attribute__((section(".SRAM_FreeRTOSHeap"))) static std::array<uint8_t, 0x3'D000> heapSRAM;
__attribute__((section(".SRAM4_FreeRTOSHeap"))) static std::array<uint8_t, 0x0'4000> heapSRAM4;
__attribute__((section(".USB_RAM_FreeRTOSHeap"))) static std::array<uint8_t, 0x0'4000> heapUSB_RAM;

const HeapRegion_t xHeapRegions[] = {
    {, heapSRAMX.size()},     // SRAMX
    {, heapSRAM.size()},       // SRAM
    {, heapSRAM4.size()},     // SRAM4
    {, heapUSB_RAM.size()}, // USB_RAM
    {nullptr, 0}                              // Array termination

The main function

int main()

The task function

    HeapStats_t heapStats;
    volatile auto debugHeapStats = heapStats; // For debug purposes

Now when I run the program with a debugger, I have verified that the xHeapRegion structure look correct.

When I call the vPortGetHeapStats function, it gets stuck in this while loop at lines 666 to 691 in portable/MemMang/heap_5.c.

Now if I change the source code of heap_5.c that way, it now works and returns the expected values:

@@ -663,7 +663,7 @@ void vPortGetHeapStats( HeapStats_t * pxHeapStats )
          * is initialised automatically when the first allocation is made. */
         if( pxBlock != NULL )
-            while( pxBlock != pxEnd )
+            while( pxBlock != pxEnd && pxBlock != NULL )
                 /* Increment the number of blocks and record the largest block seen
                  * so far. */

From the debugger, here are the values of pxEnd and pxBlock at the beginning of the while loop:
Note that some allocations have been done already.

pxBlock looks all right, up until the last block which should be equal to pxEnd but isn’t.

Is this a bug in FreeRTOS or a mistake on my end? What can I do to fix the problem without modifying FreeRTOS ?

After removing the heapUSB_RAM element from the xHeapRegions array, the function doesn’t get stuck anymore and returns correct values.

Could it be a problem specific with the USB RAM region?
It’s on a different bus from the other regions on this MCU but the datasheet says it should be usable “for general purpose use”.

Is it AFTER the other memories in physical address? I think that is a restriction on the heap5 segments.

It is after, here are the addresses and sizes from the debugger:

That should be ok. I presume USB is disabled so it isn’t using that same ram itself.

I was able to solve my issue thanks to your last message.

It turns out, the USB peripheral clock need to be enabled to access the USB RAM.
It makes sense since the USB RAM is tightly coupled to the USB peripheral but I haven’t found a clear mention of that in the user manual.

Anyways, here’s the line of code that solved my problem:

CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFroHfFreq());

Thanks again!