Stack trace & heap available..

jim lee

Well-known member
Back in the Teensy 3.2 days..

There was this RamMonitor library that you could use to get some sort of idea how much RAM you had left. I used this to create a stack tracing tool I used for tracking down bugs and to search for memory leaks. Great tool for memory leaks.

Example of the serial monitor doing a stack trace.
Code:
void navigation::loop()    out RAM : 7472
void navigation::loop()    in  RAM : 7472
  void NMEA2kBase::loop()    in  RAM : 7432
    void valueBox::idle()    in  RAM : 7392
4
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
1
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
0
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
3
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
2
    void valueBox::idle()    out RAM : 7392
    void viewMgr::idle()    in  RAM : 7392
    void viewMgr::idle()    out RAM : 7392
    void numStreamIn::idle()    in  RAM : 7392
      lookForSynk
      exitStates numStreamIn::findSynkChar()    in  RAM : 7352
      exitStates numStreamIn::findSynkChar()    out RAM : 7352
    void numStreamIn::idle()    out RAM : 7392
    void netObj::idle()    in  RAM : 7392
      void netObj::checkIncoming()    in  RAM : 7360
        ITEMS ON ourMsgQ IN  : 0
        ITEMS ON ourMsgQ OUT  : 0
      void netObj::checkIncoming()    out RAM : 7360
    void netObj::idle()    out RAM : 7392
    void xferList::idle()    in  RAM : 7392
      void xferList::listCleanup()    in  RAM : 7352
        ITEMS ON xferList IN  : 0
        ITEMS ON xferList OUT : 0
      void xferList::listCleanup()    out RAM : 7352
    void xferList::idle()    out RAM : 7392
    void NMEA2kBase::checkDeviceList()    in  RAM : 7392
    void NMEA2kBase::checkDeviceList()    out RAM : 7392
  void NMEA2kBase::loop()    out RAM : 7432
void navigation::loop()    out RAM : 7472
void navigation::loop()    in  RAM : 7472
  void NMEA2kBase::loop()    in  RAM : 7432
    void valueBox::idle()    in  RAM : 7392
4
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
1
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
0
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
3
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
2
    void valueBox::idle()    out RAM : 7392
    void viewMgr::idle()    in  RAM : 7392
    void viewMgr::idle()    out RAM : 7392
    void numStreamIn::idle()    in  RAM : 7392
      lookForSynk
      exitStates numStreamIn::findSynkChar()    in  RAM : 7352
      exitStates numStreamIn::findSynkChar()    out RAM : 7352
    void numStreamIn::idle()    out RAM : 7392
    void netObj::idle()    in  RAM : 7392
      void netObj::checkIncoming()    in  RAM : 7360
        ITEMS ON ourMsgQ IN  : 0
        ITEMS ON ourMsgQ OUT  : 0
      void netObj::checkIncoming()    out RAM : 7360
    void netObj::idle()    out RAM : 7392
    void xferList::idle()    in  RAM : 7392
      void xferList::listCleanup()    in  RAM : 7352
        ITEMS ON xferList IN  : 0
        ITEMS ON xferList OUT : 0
      void xferList::listCleanup()    out RAM : 7352
    void xferList::idle()    out RAM : 7392
    void NMEA2kBase::checkDeviceList()    in  RAM : 7392
    void NMEA2kBase::checkDeviceList()    out RAM : 7392
  void NMEA2kBase::loop()    out RAM : 7432
void navigation::loop()    out RAM : 7472
void navigation::loop()    in  RAM : 7472
  void NMEA2kBase::loop()    in  RAM : 7432
    void valueBox::idle()    in  RAM : 7392
4
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
1
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
0
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
3
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
2
    void valueBox::idle()    out RAM : 7392
    void viewMgr::idle()    in  RAM : 7392
    void viewMgr::idle()    out RAM : 7392
    void numStreamIn::idle()    in  RAM : 7392
      lookForSynk
      exitStates numStreamIn::findSynkChar()    in  RAM : 7352
      exitStates numStreamIn::findSynkChar()    out RAM : 7352
    void numStreamIn::idle()    out RAM : 7392
    void netObj::idle()    in  RAM : 7392
      void netObj::checkIncoming()    in  RAM : 7360
        ITEMS ON ourMsgQ IN  : 0
        ITEMS ON ourMsgQ OUT  : 0
      void netObj::checkIncoming()    out RAM : 7360
    void netObj::idle()    out RAM : 7392
    void xferList::idle()    in  RAM : 7392
      void xferList::listCleanup()    in  RAM : 7352
        ITEMS ON xferList IN  : 0
        ITEMS ON xferList OUT : 0
      void xferList::listCleanup()    out RAM : 7352
    void xferList::idle()    out RAM : 7392
    void NMEA2kBase::checkDeviceList()    in  RAM : 7392
    void NMEA2kBase::checkDeviceList()    out RAM : 7392
  void NMEA2kBase::loop()    out RAM : 7432
void navigation::loop()    out RAM : 7472
void navigation::loop()    in  RAM : 7472
  void NMEA2kBase::loop()    in  RAM : 7432
    void valueBox::idle()    in  RAM : 7392
4
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
1
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
0
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
3
    void valueBox::idle()    out RAM : 7392
    void valueBox::idle()    in  RAM : 7392
2
    void valueBox::idle()    out RAM : 7392
    void viewMgr::idle()    in  RAM : 7392
    void viewMgr::idle()    out RAM : 7392
    void numStreamIn::idle()    in  RAM : 7392
      lookForSynk
      exitStates numStreamIn::findSynkChar()    in  RAM : 7352
      exitStates numStreamIn::findSynkChar()    out RAM : 7352
    void numStreamIn::idle()    out RAM : 7392
    void netObj::idle()    in  RAM : 7392
      void netObj::checkIncoming()    in  RAM : 7360
        ITEMS ON ourMsgQ IN  : 0
        ITEMS ON ourMsgQ OUT  : 0
      void netObj::checkIncoming()    out RAM : 7360
    void netObj::idle()    out RAM : 7392
    void xferList::idle()    in  RAM : 7392

My question is : Is there something like RamMonitor for the teensy 4.0? I'd like to get this working for the new stuff.

Thanks!
 
Here's what I use for total free RAM. Maybe that can get you started.

C++:
extern "C" void* _sbrk(int incr);

// Returns the amount of free RAM.
// See: https://forum.pjrc.com/threads/57269-I-can-t-seem-to-use-all-of-the-Teensy-4-0-s-memory
// See: https://github.com/arduino/ArduinoCore-API/issues/73
// See: https://forum.pjrc.com/threads/69980-RAM-amp-CPU-Usage-on-Teensy-4-1?highlight=sbrk
// See: https://forum.pjrc.com/threads/33443-How-to-display-free-ram?p=275013&viewfull=1#post275013
int freeRAM() {
#if defined(__IMXRT1052__) || defined(__IMXRT1062__)
  const extern unsigned long _heap_end;
  const ptrdiff_t end = reinterpret_cast<ptrdiff_t>(&_heap_end);
#else
  const int v;
  const ptrdiff_t end = reinterpret_cast<ptrdiff_t>(&v);
#endif  // __IMXRT1062__ || __IMXRT1052__
  return end - reinterpret_cast<ptrdiff_t>(_sbrk(0));
}
 
It has been a while since I have used it, but there was some memory stuff in the ST77t3 library example:


Which prints out memory stuff. If I remember correctly a lot of it came from FrankBoesing, don't remember if he had a library for some of the
stuff or not?

It prints out (or at least used to) a when DEBUG_MEMORY was enabled. It also tried to fill memory with some known values and then at times would scan it to get an idea on how far down in the stack you went...
 
Which prints out memory stuff. If I remember correctly a lot of it came from FrankBoesing, don't remember if he had a library for some of the
stuff or not?
Yep Frank had a library for that but sure its still available. I have used a modified version of it since his original version was working after changes to the original core. Anyways I am attaching for reference:

After including the library I call the memory functions
Code:
flexRamInfo();
 

Attachments

  • T4_PowerButton.zip
    17.3 KB · Views: 17
Thanks for all the responses!

This is about 4.x Teensys. I already have the 3.x stuff, kinda' working.

From reading a bunch of the linked stuff here.. It seems that, just hopping in and writing code, I get 512K to play about in. There is other "special flavors" of RAM, but I can't access them with malloc()? I have to do something special to use them? Am I getting a somewhat accurate picture here?

Also I found this from Paul..
Code:
extern unsigned long _heap_start;
extern unsigned long _heap_end;
extern char *__brkval;

int freeram() {
  return (char *)&_heap_end - __brkval;
}


void setup() {
  while (!Serial) ;
  Serial.print("freeram = ");
  Serial.println(freeram());
  volatile char *p = (char *)malloc(152000);
  *p = 0;
  Serial.print("freeram = ");
  Serial.println(freeram());
}

void loop() {
}

Does this work?
I've not tried this yet, doing a 24hr test on my current project. Hopefully later tonight I can give this a go.

Thanks again!
 
Note that __brkval/_sbrk() isn't an accurate indicator of "free" memory - it's an indicator of the minimum unallocated memory, there may be more that is not currently in use but the allocator hasn't returned it to sbrk.
 
Minimum unallocated memory = any allocation smaller than or equal to that size will succeed, anything larger may fail (but can possibly succeed).
 
Back
Top