Tool for static analysis of memory usage

  • Mod

    The Arduino IDE tells me how much ram will be used by global variables, like this:

    Global variables use 2,412 bytes (117%) of dynamic memory, leaving -364 bytes for local variables. Maximum is 2,048 bytes.

    Is there a tool that can tell me which global variables use the most memory? Or just a list of all variables and their sizes? The tools I've been able to find (valgrind for example) focus on dynamic analysis.

    I want to find out which variables use a lot of memory, so I can see where I should spend effort to optimize. This is a large project, which uses several libraries, so looking through them by hand is cumbersome.

  • Contest Winner

    @mfalkvidd I'm interested too. Also I'm wondering what else goes into that memory space? I sometimes get the feeling that's some kind of heap space. It seems like the more functions I use the more memory is used as well.

    And I would love it if they just would add a decent refactor support in the IDE

  • Mod

    AdaFruit has a great guide on Arduino memory

    Good example on how to use PROGMEM:

    But to use these guides, I first need to find where to focus my effort.

    avr-size can display some information:

    avr-size.exe -A R:\Scratch\Tetris.ino.elf
    R:\Scratch\Tetris.ino.elf  :
    section            size      addr
    .data              1360   8388864
    .text             19020         0
    .bss               1124   8390224
    .comment             17         0
    .debug_aranges     2032         0
    .debug_info      176644         0
    .debug_abbrev     18445         0
    .debug_line       23110         0
    .debug_frame       9696         0
    .debug_str        27466         0
    .debug_loc       104530         0
    .debug_ranges      3480         0
    Total            386924

    But the best so far is readelf (header added manually for clarity):

    avr-readelf.exe -a 'r:\Scratch\Tetris.ino.elf' | less | grep OBJECT | sort -nk3 | head
       Num:    Value  Size Type    Bind   Vis      Ndx Name
        24: 0080038d   676 OBJECT  LOCAL  DEFAULT    1 _ZL15MatriseFontData
       282: 008008d2   445 OBJECT  GLOBAL DEFAULT    3 leds
       255: 00800752   144 OBJECT  GLOBAL DEFAULT    3 AttractMsg
       258: 008006fa    88 OBJECT  GLOBAL DEFAULT    3 GameOverMsg
       209: 00800875    72 OBJECT  GLOBAL DEFAULT    3 PlayfieldData
        45: 0080035d    48 OBJECT  LOCAL  DEFAULT    1 _ZL11TetrisIData
        43: 0080031d    48 OBJECT  LOCAL  DEFAULT    1 _ZL11TetrisJData
        41: 008002dd    48 OBJECT  LOCAL  DEFAULT    1 _ZL11TetrisLData
        39: 0080029d    48 OBJECT  LOCAL  DEFAULT    1 _ZL11TetrisOData
        37: 0080025d    48 OBJECT  LOCAL  DEFAULT    1 _ZL11TetrisSData

    So the real memory hogs in my case seems to be Font Data and the 144 pixel led array, which can be expected to be large. After that comes three long strings. I'll see if I can move the font and the strings to PROGMEM or apply some other tweak.

  • Contest Winner

    @mfalkvidd that's an interesting project your working on...!

  • Mod

    @TheoL yes, I think it might come out pretty cool. I have built a 22" 12x12 led matrix screen out of 5m ws2811 led strip, on which I plan to play Tetris.

    22" 12x12 RGB led matrix screen for Arduino based on 5m ws2811 led strip – 00:29
    — Mikael Falkvidd

  • Contest Winner

    @mfalkvidd I don't know what I like the most about that video. The matrix or the music. You've go a new subscriber.

    I'm almost done with my first i2c tinyAt 85 slave project. Was a p@1n in the butt. Will be an i2c remote receiver that you can add to your MySensors projects. It's hard to do the first time. But I'll be adding an tinyAT 85 i2c slave to all my Arduino projects where I need more memory.

    You could let the tinyAT 85 monitor the controls. Saves memory..

  • Mod

    @TheoL thanks for the tip on AtTiny85. I happen to have 2 of them in my stash of mcu:s.

    For now I will probably just use a nodemcu/esp8266 esp-12. It has lots of ram:

    Sketch uses 235,469 bytes (22%) of program storage space. Maximum is 1,044,464 bytes.
    Global variables use 34,412 bytes (42%) of dynamic memory, leaving 47,508 bytes for local variables. Maximum is 81,920 bytes.

    I might use a separate node for the controller, communicating using the nrf.

  • Contest Winner

    @mfalkvidd lots of ram is what we like. In case you're interested. This is a good i2c slave tutorial and this is a great explanation of the i2c protocol

    How I2C Communication Works and How To Use It with Arduino – 09:58
    — How To Mechatronics