JeeLabs has a very informative post about memory usage on the ATMega, along with some Arduino sample code and an explanation of how bad memory management can cause sketches to fail. More from Jean-Claude:
Sometimes, it’s useful to find out how much memory a sketch uses.
Sometimes, it’s essential do so, i.e. when you’re reaching the limit. Because strange and totally unpredictable things happen once you run out of memory.
Running out of RAM space is the nasty one. Because it can happen at any time, not necessarily at startup, and not even predictably because interrupt routines can trigger the problem.
There are three areas in RAM:
static data, i.e. global variables and arrays … and strings !
the “heap”, which gets used if you call malloc() and free()
the “stack”, which is what gets consumed as one function calls another
The heap grows up, and is used in a fairly unpredictable manner. If you release areas, then they will be lead to unused gaps in the heap, which get re-used by new calls to malloc() if the requested block fits in those gaps.
At any point in time, there is a highest point in RAM occupied by the heap. This value can be found in a system variable called __brkval.
The stack is located at the end of RAM, and expands and contracts down towards the heap area. Stack space gets allocated and released as needed by functions calling other functions. That’s where local variables get stored.
Check out his post for the code and further explanation.
Stop breadboarding and soldering – start making immediately! Adafruit’s Circuit Playground is jam-packed with LEDs, sensors, buttons, alligator clip pads and more. Build projects with Circuit Playground in a few minutes with the drag-and-drop MakeCode programming site, learn computer science using the CS Discoveries class on code.org, jump into CircuitPython to learn Python and hardware together, or even use Arduino IDE. Circuit Playground Express is the newest and best Circuit Playground board, with support for MakeCode, CircuitPython, and Arduino. It has a powerful processor, 10 NeoPixels, mini speaker, InfraRed receive and transmit, two buttons, a switch, 14 alligator clip pads, and lots of sensors: capacitive touch, IR proximity, temperature, light, motion and sound. A whole wide world of electronics and coding is waiting for you, and it fits in the palm of your hand.
Python for Microcontrollers — CircuitPython takes flight! All aboard with datum, Bluefruit CPX, and more! #Python #Adafruit #CircuitPython #PythonHardware @circuitpython @micropython @ThePSF @Adafruit
Get the only spam-free daily newsletter about wearables, running a "maker business", electronic tips and more! Subscribe at AdafruitDaily.com !
Just use PROGMEM for const strings.
“I would hope that… but it probably doesn’t.”
Well, actually, it does. This optimization is called “constant folding”, and all decent compilers/linkers do it. I knew that pcc-based compilers had been doing this for decades, but wasn’t able to confirm that GCC did in a quick once-over of the documentation, but it certainly appears to.
Many “real” embedded systems don’t use a garden-variety libc-style heap, but do their own memory-management themselves with custom memory pools that take all of the non-determinism out of heap usage. They do this for the simple reason is that’s generally impossible to guarantee that your system will not fail otherwise, assuming that you care about that sort of thing.