memory usage "dos and don'ts"

As you have noticed yourself, this can be somewhat platform-dependent. Since you are working on a Nano, my answer will be for the AVR architecture, when compiled with gcc, the avr-libc, and the Arduino core library.

First, let me reassure you: this weird behavior you saw of the Wixel doesn't happen on this platform. Local variables get allocated mostly in CPU registers, then on the stack.

Now, the first general rule may sound obvious: think twice about what your program really needs to remember. Also, use each time the smallest possible data type. The C99 types int8_t, uint16_t and co. are useful for this.

Another rule you will often hear on this platform: avoid dynamic allocation, i.e. malloc() and new, as quite often you cannot afford heap fragmentation. Avoid also the String class, as it relies on dynamic allocation. Prefer when possible static allocation, or stack allocation for small things.

Don't forget to use const for constants: with this qualifier the compiler can often optimize the constants out as immediate operands. For arrays of constants, use PROGMEM. Yes, it's not comfortable to use, but it can save you lots of RAM. The F() macro for printing constant messages is a special case of PROGMEM.

Lastly, be very careful with recursion.


Edgar's got some great tips, and I'll reiterate one before giving a few more:

avoid dynamic memory allocation

Don't use malloc. When you're designing a system, budget out your RAM like you do your monthly budget. Make sure you're able to do everything at once.

And a couple other tips:

global statics

Make full use of the BSS block; try to block out space for as much as possible in global static arrays. You may shudder or scoff at the idea of putting everything at a global level, but embedded is a paradigm shift, with its own set of rules.

Since you'll have so many variables at a global level, static helps you to avoid polluting your namespace too much.

avoid fancy C++ features

In fact, try to not use C++ at all. C++ takes you "farther from the metal," with its RAII and its constructors and its implicit type conversion... It's much harder to keep a tight inventory of all of your resources when your language does so much behind the scenes. If you really want to use a certain C++ language feature, try to keep the tone of your code more like "C with bits of C++" rather than "C++ shoehorned into an embedded system." That never goes well.

Especially avoid generics/templates, which will eat up lots of your memory. Every time you use a new type with a template in your code, another copy of the template class is compiled into your program, just for that one type. Ever wonder why C++ binaries can balloon to 20, 50, even 100 MB? Templates, man. Templates.

const

This keyword should go on as many variables as it can. Keeping this habit will save on both execution time and space consumption. Learn the difference between const T* foo, T* const foo, and const T* const foo.

Tags:

Memory Usage