Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 32

Thread: Memory Status and Monitoring

  1. #1

    Memory Status and Monitoring

    Hi all,

    I am developing a project using a Teensy 3.1; using a lot of dynamic memory allocations. With this in mind, I've written a small class that provides memory information simply. Using the initialize() and run() functions, the class monitors stack usage, simulates stack allocation and provides a low memory warning.

    I'm wondering if this class would be of use to anyone else projects...

    Cheers,
    Adrian

    Update: Now on SourceForge -
    https://sourceforge.net/projects/teensy-3-x-rammonitor

    class RamMonitor {
    int32_t unallocated() const; // space between heap and stack (current): negitive if heap/stack crash
    uint32_t stack_used() const; // stack size (current): grows into unallocated
    uint32_t heap_total() const; // heap (dynamic mem) size: can grow into unallocated
    uint32_t heap_used() const; // heap allocated
    uint32_t heap_free() const; // free heap

    int32_t free() const; // free ram: unallocated and unused heap
    uint32_t total() const; // physical ram

    // these functions (along with initialize and run)
    // create the ellusion of stack allocation.
    uint32_t stack_total() const; // stack size (historical)
    int32_t stack_free() const; // calc stack usage before next stack growth
    int32_t adj_unallocd() const; // space between heap and "alloc'd" stack: negitive if heap/stack crash
    int32_t adj_free() const; // free ram: adjusted unallocated and unused heap

    bool warning_lowmem() const; // returns true if stack and heap get close
    bool warning_crash() const; // returns true if stack is in danger of overwriting heap

    void initialize(); // initializes stack monitoring
    void run(); // monitors stack and adjusted unallocated
    };
    Last edited by cyborgv2; 02-19-2016 at 01:43 PM. Reason: Source Published

  2. #2
    Senior Member Constantin's Avatar
    Join Date
    Nov 2012
    Location
    In the yard with a 17' Dia. Ferris Wheel
    Posts
    1,408
    Hey, that's awesome, so thanks for contributing it. I may have a use for it as I investigate why the LC running Roxanne, our humidifier, seems to get hung from time to time.

  3. #3
    Hi,

    That's cool Constantin (no pun intended! lol) Don't know the LC but I understand my code would work on a 3.0... so I see no reason it shouldn't work on the LC. Code still needs a tickle and better comments needed, if I'm to post it.

  4. #4
    Senior Member
    Join Date
    Feb 2015
    Posts
    162
    yes, I would love to check it out! I am running into memory problems and it would be great to have another tool to use.

  5. #5
    Senior Member
    Join Date
    Nov 2015
    Location
    Wales
    Posts
    579
    Quote Originally Posted by Constantin View Post
    seems to get hung from time to time.
    Watchdog

  6. #6
    Uploaded to SourceForge, hope it helps

    https://sourceforge.net/projects/teensy-3-x-rammonitor

  7. #7
    Senior Member Constantin's Avatar
    Join Date
    Nov 2012
    Location
    In the yard with a 17' Dia. Ferris Wheel
    Posts
    1,408
    It was the watchdog... Once I started kicking it every 10ms instead of every second, the system became stable.

  8. #8
    Added extensive help and information...

    https://sourceforge.net/p/teensy-3-x...tor/wiki/Home/

  9. #9
    Member
    Join Date
    Mar 2016
    Location
    Ireland
    Posts
    64
    I've tried to follow the wiki but I'm just learning...
    Do I just add this code to my sketch or should it be "included as a dot h file.
    Does initialize require the parameters StackAllocation and Lowmem and what sort of typical values?
    For raw memory information can I just ... Serial.print(free);

    Update
    I have included it in my main sketch but this has introduced an error referring to the use of "min" function elsewhere in my code:

    error: 'min' was not declared in this scope
    Last edited by muggins; 03-28-2016 at 03:39 PM.

  10. #10
    Hey muggins

    Quote Originally Posted by muggins View Post
    I've tried to follow the wiki but I'm just learning...
    Do I just add this code to my sketch or should it be "included as a dot h file.
    It's a c++ header, it is a .h file and as you say it's #include'd. Either copy to your project directory or may be in to a RamMonitor directory in your libraries. Using it as a library, means you don't have to copy it in to every project but (for older Arduino IDEs) you should (need) to add a #include <RamMonitor.h> to your .ino

    Quote Originally Posted by muggins View Post
    Does initialize require the parameters StackAllocation and Lowmem and what sort of typical values?
    Initialize method does not take any parameters!?. STACKALLOCATION and LOWMEM are static const within my code and are set with reasonable default values (for Teensy 3.1/3.2), the values I use.

    Quote Originally Posted by muggins View Post
    For raw memory information can I just ... Serial.print(free);
    Yes, raw memory info can be retrieved without init and run calls. Values returned by the extended functions tend to be more useful.
    Code:
    RamMonitor ram;
    
    void report_mem() {
      Serial.print("free RAM: ");
      Serial.print(ram.free() / 1024);
      Serial.println("Kb");
    };
    Quote Originally Posted by muggins View Post
    Update
    I have included it in my main sketch but this has introduced an error referring to the use of "min" function elsewhere in my code:

    error: 'min' was not declared in this scope
    ??? My code doesn't play around with namespaces ("scope") nor has anything to do with a min function... my guess, you're missing a close bracket ('}') somewhere in your code. Personally, so meny different implementations of the min and max functions, some not compatible, that I tend to use to avoid those and use high and low instead
    Last edited by cyborgv2; 03-28-2016 at 05:42 PM.

  11. #11
    Member
    Join Date
    Mar 2016
    Location
    Ireland
    Posts
    64
    I really appreciate your comprehensive response. I've got it now. As for the extended set do I use ram.initialize?
    Just for interest I still have the strange max/min error which only happens when I include the class. There are several items on the net referring to "broken" min/max. I have found a workaround. Thanks

    #include "RamMonitor.h"
    void setup() {
    }
    void loop() {
    }
    void CalcMax(){
    int m;
    m=max(5,7);
    }
    Hi

  12. #12
    Senior Member
    Join Date
    Jul 2014
    Posts
    139
    There is a conflict with the Audio library through <SD.h>

    Code:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD/utility/SdFatUtil.h:39:15: error: type mismatch with previous external decl of 'int* __brkval' [-fpermissive]
    extern int* __brkval;

  13. #13
    Senior Member
    Join Date
    Jul 2014
    Posts
    139
    Once I changed

    Code:
    extern char* __brkval;
    to

    Code:
    extern int* __brkval;
    and fixed all the subsequent type errors, it works well - thank you.

  14. #14
    Quote Originally Posted by muggins View Post
    I really appreciate your comprehensive response. I've got it now. As for the extended set do I use ram.initialize?
    Just for interest I still have the strange max/min error which only happens when I include the class. There are several items on the net referring to "broken" min/max. I have found a workaround. Thanks
    Thank you, try to be helpful.

    Yes, extended methods require initialization... calling run method regularly, speeds other extended methods and updates memory warnings.

    As for your max/min error; wonder if it has anything to do with malloc.h... no longer really supported but works on Teensy, Linux and Android!? Out for interest and may be nail this problem, what libraries are you using and how did you get around the min/max problem?

    Cheers

  15. #15
    Member
    Join Date
    Mar 2016
    Location
    Ireland
    Posts
    64
    The little bit of example code I uploaded breaks the min/max functionality ie no other libraries.
    I found a workaround on the web
    #define min(a,b) ((a)<(b)?(a)b))
    #define max(a,b) ((a)>(b)?(a)b))
    thanks

  16. #16
    Quote Originally Posted by macaba View Post
    Once I changed

    Code:
    extern char* __brkval;
    to

    Code:
    extern int* __brkval;
    and fixed all the subsequent type errors, it works well - thank you.
    Great, thanks for the compatibility mod... I'm using SdFat.h and didn't get this problem. Thanks to a failing power pack, my Teensy has been fried, they don't work at 9v! lol Ordering a 3.2 tomorrow; I'll check the int* compatiblity as soon as I can and update the header

  17. #17
    Quote Originally Posted by muggins View Post
    The little bit of example code I uploaded breaks the min/max functionality ie no other libraries.
    I found a workaround on the web
    #define min(a,b) ((a)<(b)?(a)b))
    #define max(a,b) ((a)>(b)?(a)b))
    thanks
    Thanks... that's basically the default def, old school.
    Last edited by cyborgv2; 03-28-2016 at 09:32 PM.

  18. #18
    Quote Originally Posted by macaba View Post
    There is a conflict with the Audio library through <SD.h>

    Code:
    C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\SD/utility/SdFatUtil.h:39:15: error: type mismatch with previous external decl of 'int* __brkval' [-fpermissive]
    extern int* __brkval;
    Could SD.h be using unallocated memory for buffers; would save allocation time but break RamMonitor once free memory got below the buffer size!

  19. #19
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,483
    Quote Originally Posted by muggins View Post
    The little bit of example code I uploaded breaks the min/max functionality ie no other libraries.
    Are you going to actually share the location of this code?

    I found a workaround on the web
    #define min(a,b) ((a)<(b)?(a):(b))
    #define max(a,b) ((a)>(b)?(a):(b))
    Originally we had this in Teensyduino. Arduino's core library still had it.

    The problem with this code is either "a" or "b" gets evaluated twice. If they're simple variables, that's fine. But when they're function calls, the function gets called twice. Likewise for volatile hardware registers.

    For example:

    int size = min(Serial.read(), 10);

    You'd expect this code to read 1 byte, and give you either the byte, or 10 if the byte is higher than 10. But instead, it actually reads 2 bytes!

    You might say "well don't do that", but indeed this problem has come up. That's why Teensyduino now uses this for min and max:

    Code:
    #define min(a, b) ({ \
      typeof(a) _a = (a); \
      typeof(b) _b = (b); \
      (_a < _b) ? _a : _b; \
    })
    #define max(a, b) ({ \
      typeof(a) _a = (a); \
      typeof(b) _b = (b); \
      (_a > _b) ? _a : _b; \
    })

  20. #20
    Very good point Paul

    My high/low is implemented as templated inlined functions; the beauty of that is you can overload them for complex types, ie vectors. Also allow lhs but I've never found a reason to do that!

    Code:
    template <typename TYPE>
    inline TYPE& low(TYPE& a0, TYPE& a1) { return (a0 < a1) ? a0 : a1; };
    template <typename TYPE>
    inline const TYPE& low(const TYPE& a0, const TYPE& a1) { return (a0 < a1) ? a0 : a1; };
    In my mapping code I have 2D and 3D vector overloads:

    Code:
    inline Vector2D& low(Vector2D& a0, Vector2D& a1) { return (a0.size2() < a1.size2()) ? a0 : a1; };
    Last edited by cyborgv2; 03-29-2016 at 12:28 PM.

  21. #21
    Member
    Join Date
    Mar 2016
    Location
    Ireland
    Posts
    64
    Paul forgive me if I'm being stupid, but since I am compiling in Teensyduino why do I get the error.

  22. #22
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,483
    Quote Originally Posted by muggins View Post
    but since I am compiling in Teensyduino why do I get the error.
    I don't know. But as you can see in this other thread:

    https://forum.pjrc.com/threads/33760...l=1#post100782

    I compiled all 6 of the SD library examples without any errors.

    So something must be different about what you're doing. If you want me to investigate, you have to post the complete code to reproduce the problem (the "Forum Rule" which appears in red at the top of every page). If you're using any other libs that don't come with Teensyduino, you have to post their code or give links to their downloads. Please, if you ask me to look into this, take an extra moment to make sure the info in your message really has *all* the necessary code and details. I'm crazy busy right now, and guessing what's missing is incredibly time consuming.

  23. #23
    Hey Paul,

    Know you're a busy man. Going to put some time in to this problem as soon as I can get to my desktop... nothing in my code would produce the results muggins is getting; best guess it's malloc.h

  24. #24
    Member
    Join Date
    Mar 2016
    Location
    Ireland
    Posts
    64
    Paul
    I am very grateful for help that you provide to all of us and really don't want to waste your valuable time.. I already posted a simple sketch in post #11 which throws up
    " 'max' was not declared in this scope"
    I was initially requesting help from "cyborgv2" who is the author of the RamMonitor class and instigator of this thread.
    I have a workaround now so no worries.
    thanks
    PS I'm not using any SD libraries.

  25. #25
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,483
    I just looked into this anyway.

    Seems the trouble is caused by this line in RamMonitor.h:

    Code:
    #include <cstdint>
    I'm not familiar with this file, or why it would interfere with the max() define from Arduino.h. But it does.

    Commenting out that include seems to have no harmful effects. Maybe RamMonitor doesn't actually use it?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •