Querying free heap memory

incrediball wrote on Wednesday, April 16, 2008:

Now that we’ve got functions like uxTaskGetStackHighWaterMark for helping us to fine tune the stack sizes, it would be nice to have a function that returns the available heap memory as well. It’s presently just guess work unless we patch heap_1.c (or whatever) to find out how much memory has actually been allocated.

davedoors wrote on Wednesday, April 16, 2008:

This could be done through some more hook macros that allow you to track the amount of heap taken and returned. I think this was suggested on this forum before. It would not tell you anything about heap fragmentation though.

jorick23 wrote on Wednesday, April 16, 2008:

Use this function to walk the heap.  It also shows free ROM and RAM.  It’s written for the STR750 with a version 4 IAR compiler.

#pragma segment = "ROM0_START"
#pragma segment = "ROM0_TOP"
#pragma segment = "ROM0_END"
#pragma segment = "RAM_START"
#pragma segment = "RAM_TOP"
#pragma segment = "RAM_END"
#pragma segment = "HEAP"

typedef struct FREE FREE;

struct FREE {                          // Heap free block list structure:
   uint32_t sulSize;                   //    Free block size
   FREE *spsNext;                      //    Pointer to the next free block
};

extern FREE __data_Aldata;             // Heap information structure

void ShowHeap (void) {
   FREE *xpsFree;                      // Free heap block
   long *xplStack;                     // Stack pointer
   long xlRomSize;                     // ROM size
   long xlRamSize;                     // RAM size
   long xlMemory;
   long xlHeapTotal;
   long xlHeapFree;
   long xlHeapUsed;

// The heap is walked to find the amount of free memory available.

   xlHeapFree = 0;
   xpsFree = &__data_Aldata;
   while (xpsFree->spsNext) {
      xpsFree = xpsFree->spsNext;
      xlHeapFree += xpsFree->sulSize;
   }
   xlHeapTotal = (long) __sfe ("HEAP") - (long) __sfb ("HEAP");
   xlHeapUsed = xlHeapTotal - xlHeapFree;

// Header

   printf ("Heap             | Free stack         | Free memory\r\n");
   xlRomSize = (long) __sfb ("ROM0_END") - (long) __sfb ("ROM0_START") + 1;
   xlRamSize = (long) __sfb ("RAM_END") - (long) __sfb ("RAM_START") + 1;

// Used heap, FIQ stack, and free flash

   for (xplStack = (long *) &Stack_FIQ;
         xplStack < (long *) &StackTop_FIQ && *xplStack == RAM_TEST;
         ++xplStack);
   xlMemory = (long) __sfb ("ROM0_END") - (long) __sfb ("ROM0_TOP") + 1;
   printf ("   Used:  %5d  |    FIQ: %5d      |    Flash:    %6d (%d%%)\r\n",
         xlHeapUsed, 4 * (xplStack - (long *) &Stack_FIQ), xlMemory,
         100 * xlMemory / xlRomSize);

// Free heap, IRQ stack, and free RAM

   for (xplStack = (long *) &Stack_IRQ;
         xplStack < (long *) &StackTop_IRQ && *xplStack == RAM_TEST;
         ++xplStack);
   xlMemory = (int) __sfe ("RAM_END") - (int) __sfb ("RAM_TOP") + 1;
   printf ("   Free:  %5d  |    IRQ: %5d      |    RAM:      %6d (%d%%)\r\n",
         xlHeapFree, 4 * (xplStack - (long *) &Stack_IRQ), xlMemory,
         100 * xlMemory / xlRamSize);

// Total heap, SVC stack, and free heap + RAM

   for (xplStack = (long *) &Stack_SVC;
         xplStack < (long *) &StackTop_SVC && *xplStack == RAM_TEST;
         ++xplStack);
   printf ("   TOTAL: %5d  |    SVC: %5d      |    Heap+RAM: %6d (%d%%)\r\n",
         xlHeapTotal, 4 * (xplStack - (long *) &Stack_SVC),
         xlMemory + xlHeapFree, 100 * (xlMemory + xlHeapFree) / xlRamSize);
}