How Does Memory Work On The Arduino, Anyways?

After reading an interesting article on memory (and having finished the printf code I posted yesterday), I realized that memory can be one of the more odd aspects of programming the Arduino. Take for example:

  • In most computers, a pointer is a pointer is a pointer – but on the Arduino, there are actually three locations: the eeprom, the program memory, and the RAM. Each can have the same pointer value, making things quite confusing!
  • Program memory is where everything starts; however, global values are normally copied over to RAM on startup, effectively doubling the space they use (one copy in program memory, one in RAM).
  • Your RAM gets chopped up quickly: the bottom is system variables and those globals, then the ‘heap’ grows up, while the ‘stack’ grows down. If the two meet, your program is likely over – whether you want it or not!

What to do then?

  • Watch globals. They take up space right from the start, and never let it go.
  • Minimize variables. Unsigned longs are twice the size of ints – use a lot of them and you’ll see your free space shrink twice as fast. Variables that never stray from 1 may be perfect for byte values, and so on.
  • Watch strings. They are ‘double dippers’ – first copy in the program, then a second copy in RAM. And while an int only takes 2 bytes, strings grow much bigger very easily.
  • Avoid recursion, or deep subroutine calls. Every subroutine call uses memory – and while it’s rarely a problem, if you use recursion, it can eat up space fast.
  • Keep info out of RAM. This page explains how to use PROGMEM to keep data in the program side of things, and not in the RAM. Since the ATMega328 has about 32k of program versus 2k of RAM space, it can be a real benefit.
  • Monitor the memory. Use the freemem() function and display it from time to time in your program, to get an idea of how much space you have left:
    #include <avr/pgmspace.h>
    int freeRam () {
      extern int __heap_start, *__brkval;
      int v;
      return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
    }

Of course, sometimes you just can’t save enough space; however, with an eye on the memory size, you can often be ready for when memory gets too close to the bone.

2 thoughts on “How Does Memory Work On The Arduino, Anyways?

  1. Great use ‘PROGMEM’ and then find out that the memory is only good for several thousand writes.
    The ‘issue’ with all these systems is that there is no way to checksum the data written to this memory.
    normally in a professional system there would be a ‘magic’ and a ‘checksum’.
    Sounds like a really fast way to allow a program to go AWOL.

  2. PROGMEM doesn’t write the data into computer memory, it simply packs it with the program when compiling, so it adds no more wear and tear to the memory chips than uploading the program itself does. As for checksums and writes to the memory, only a program in the bootloader area could allow this, and as you mention, with the limited number of writes available, using it for a scratchpad makes less sense than using the EEPROM