How to display free ram.

Does anyone happen to have this code still?
...

Try this - may be the code based on p#23 output - had to HACK edits to get it to compile with Beta TD 1.58 changes:
Code:
// https://forum.pjrc.com/threads/33443-How-to-display-free-ram

void   getFreeITCM();//  { // end of CODE ITCM, skip full 32 bits
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial);
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  if ( CrashReport ) Serial.print ( CrashReport );
  memInfo();
  getFreeITCM();
}


void loop() {
  // put your main code here, to run repeatedly:

}


#define printf Serial.printf

void memInfo () {
  constexpr auto RAM_BASE   = 0x2020'0000;
                              constexpr auto RAM_SIZE   = 512 << 10;
                              constexpr auto FLASH_BASE = 0x6000'0000;
#if ARDUINO_TEENSY40
  constexpr auto FLASH_SIZE = 2 << 20;
#elif ARDUINO_TEENSY41
  constexpr auto FLASH_SIZE = 8 << 20;
#endif

  // note: these values are defined by the linker, they are not valid memory
  // locations in all cases - by defining them as arrays, the C++ compiler
  // will use the address of these definitions - it's a big hack, but there's
  // really no clean way to get at linker-defined symbols from the .ld file

  extern char _stext[], _etext[], _sbss[], _ebss[], _sdata[], _edata[],
         _estack[], _heap_start[], _heap_end[], _itcm_block_count[], *__brkval;

  auto sp = (char*) __builtin_frame_address(0);

  printf("_stext        %08x\n",      _stext);
  printf("_etext        %08x +%db\n", _etext, _etext - _stext);
  printf("_sdata        %08x\n",      _sdata);
  printf("_edata        %08x +%db\n", _edata, _edata - _sdata);
  printf("_sbss         %08x\n",      _sbss);
  printf("_ebss         %08x +%db\n", _ebss, _ebss - _sbss);
  printf("curr stack    %08x +%db\n", sp, sp - _ebss);
  printf("_estack       %08x +%db\n", _estack, _estack - sp);
  printf("_heap_start   %08x\n",      _heap_start);
  printf("__brkval      %08x +%db\n", __brkval, __brkval - _heap_start);
  printf("_heap_end     %08x +%db\n", _heap_end, _heap_end - __brkval);
#if ARDUINO_TEENSY41
  extern char _extram_start[], _extram_end[], *__brkval;
  printf("_extram_start %08x\n",      _extram_start);
  printf("_extram_end   %08x +%db\n", _extram_end,
         _extram_end - _extram_start);
#endif
  printf("\n");

  printf("<ITCM>  %08x .. %08x\n",
         _stext, _stext + ((int) _itcm_block_count << 15) - 1);
  printf("<DTCM>  %08x .. %08x\n",
         _sdata, _estack - 1);
  printf("<RAM>   %08x .. %08x\n",
         RAM_BASE, RAM_BASE + RAM_SIZE - 1);
  printf("<FLASH> %08x .. %08x\n",
         FLASH_BASE, FLASH_BASE + FLASH_SIZE - 1);
#if ARDUINO_TEENSY41
  extern uint8_t external_psram_size;
  if (external_psram_size > 0)
    printf("<PSRAM> %08x .. %08x\n",
           _extram_start, _extram_start + (external_psram_size << 20) - 1);
#endif
  printf("\n");

  auto stack = sp - _ebss;
  printf("avail STACK %8d b %5d kb\n", stack, stack >> 10);

  auto heap = _heap_end - __brkval;
  printf("avail HEAP  %8d b %5d kb\n", heap, heap >> 10);

#if ARDUINO_TEENSY41
  auto psram = _extram_start + (external_psram_size << 20) - _extram_end;
  printf("avail PSRAM %8d b %5d kb\n", psram, psram >> 10);
#endif
}


uint32_t *ptrFreeITCM;  // Set to Usable ITCM free RAM
uint32_t  sizeofFreeITCM; // sizeof free RAM in uint32_t units.
uint32_t  SizeLeft_etext;
//extern uint32_t _stext;
// extern uint32_t _etext;
extern char _stext[], _etext[];
FLASHMEM void   getFreeITCM() { // end of CODE ITCM, skip full 32 bits
  Serial.println("\n\n++++++++++++++++++++++");
  SizeLeft_etext = (32 * 1024) - (((uint32_t)&_etext - (uint32_t)&_stext) % (32 * 1024));
  sizeofFreeITCM = SizeLeft_etext - 4;
  sizeofFreeITCM /= sizeof(ptrFreeITCM[0]);
  ptrFreeITCM = (uint32_t *) ( (uint32_t)&_stext + (uint32_t)&_etext + 4 );
  printf( "Size of Free ITCM in Bytes = %u\n", sizeofFreeITCM * sizeof(ptrFreeITCM[0]) );
  printf( "Start of Free ITCM = %u [%X] \n", ptrFreeITCM, ptrFreeITCM);
  printf( "End of Free ITCM = %u [%X] \n", ptrFreeITCM + sizeofFreeITCM, ptrFreeITCM + sizeofFreeITCM);
  for ( uint32_t ii = 0; ii < sizeofFreeITCM; ii++) ptrFreeITCM[ii] = 1;
  uint32_t jj = 0;
  for ( uint32_t ii = 0; ii < sizeofFreeITCM; ii++) jj += ptrFreeITCM[ii];
  printf( "ITCM DWORD cnt = %u [#bytes=%u] \n", jj, jj*4);
}
 
Awesome! I'll probably have to test it out tomorrow, but thanks! I expect it'll work with TD 1.57?

I'll let you know how it goes. Thanks so much for your fast response!
 
that's pretty neat, but it provides info about the max ram used instead of the available free ram, am I correct?
 
I know that the example sketch uncannyEyes_async_st7789_240x240 of st7735_t3 has code in it to detect memory info
There are functions DumpMemoryInfo and EstimateStackUsage.
that's pretty neat, but it provides info about the max ram used instead of the available free ram, am I correct?

What do you mean by available free Ram? On What... Note, I am not trying to give you a trick question.

But this could mean something different between T3.x and T4.x, and also what types of memory.

For example, how much space can you still use on the stack? Or Heap? or on T4.1 with external memory, how much of that has not been used.

On T3.x, the stack area and heap area grow into each other. That is the stack grows down from the end of memory down to how much it is going to use...
Where the heap grows up from the top of the main memory used and if you allocate too much in either direction they can collide.

On T4.x they are in different memory sections as you can see in the memory section on the product pages:
https://www.pjrc.com/store/teensy41.html#memory

But for example if you wanted to know how much stack space you have free at some point, you can guestimate it by:
take an address to a simple variable on the stack, and by knowing the start address of the DTCM region of memory and the size of DTCM, how much is left.

The example sketch I mention shows how to figure out the size of DTCM. That is the first region of memory is made of 32K chunks of memory that are either DTCM (Data) or ITCM (Instruction i.e. code). So the code walks the controlling register IOMUXC_GPR_GPR17, and see which parts are which...

We know that DTCM is in the range of: 0x20000000 - 0x2007FFFF - DTCM (512KB)
Note the actual high end of the valid DTCM memory is most often less than 0x2007FFFF, as at least one area will most likely be ITCM...
 
thanks for answering @KurtE
well, I was wrong but is because I am getting some weird results, looks like it does not always show the correct value
Code:
#include <Arduino.h>
#include "memory.h"
void setup()
{
    Serial.begin(9600);
    Serial.println("\n init--------------");
    memInfo();
    getFreeITCM();

    int* array1 = new int[16384];
    Serial.println("\n 1--------------");
    memInfo();
    getFreeITCM();

    int* array2 = new int[16384];
    Serial.println("\n 2--------------");
    memInfo();
    getFreeITCM();

    delete array2;
    Serial.println("\n delete 2--------------");
    memInfo();
    getFreeITCM();

    delete array1;
    Serial.println("\n delete 1--------------");
    memInfo();
    getFreeITCM();
}
void loop()
{
}

and the output is (i have pasted only part of the output )
Code:
 init--------------


avail HEAP    518016 b   505 kb


 1--------------

avail HEAP    450560 b   440 kb


 2--------------


avail HEAP    380928 b   372 kb


 delete 2--------------

avail HEAP    380928 b   372 kb


 delete 1--------------


avail HEAP    516096 b   504 kb

shouldn't the output be like 505, 440, 372, 440, 505?
 
Sorry, I don't use these methods and code much at all.

So for example avail HEAP I don't know what it is doing or not doing. That is what is avail mean.

That is, some of the simple functions, simply find out how much memory has been allocated to the heap. Or more explicitly
what _sbrk(0) returns.
This method is used by allocators to allocate chunks of memory starting at _heap_start.

But this does not tell you is how much space is currently allready allocated into the heap (malloc new) that may have subsequently been freed.

Also the getFreeITCM() code
was stuff that I believe @defragster played with earlier. It should never exceed 32K-1. That is when your program is loaded, it will allocate enough ITCM chunks for the stuff that is copied down to ITCM to fit. The chunks are again in 32K blocks. So if your program code (not marked FLASHMEM) requires only portion of a block, the rest of it is not used. He has/had functions to allow you try to allocate that area for data. Likewise if your ITCM area is 448K bytes (ITCM 2 chunks), and you only defined 10k of static data and maybe static wise, you only need something like 20K, then that leaves something like 448-30 or 418K of fast memory that is never used. So I know some of setup to have a heap in this area of memory as well.
...
 
Sidenote: anything allocated with new[] should be cleaned up with delete[], not plain delete. You might get away with it for ints but not for class objects.
 
Back
Top