If you dig microcontrollers, and you like to dig into how they work, Elecia White wants to help you navigate their innermost secrets with the help of memory map files. In this refreshingly funny, but very deep keynote talk from the 2021 Hackaday Remoticon, Elecia guides us through one of the most intimidating artifacts of compilation — a file that lists where everything is being put in the microcontroller’s memory — and points out landmarks that help to make it more navigable.
And when you need to look into the map file, you probably really need to look into the map file. When your embedded widget mysteriously stops working, memory problems are some of the usual suspects. Maybe you ran out of RAM or flash storage space, maybe you have some odd hard fault and you want to know what part of the program is causing the trouble, or maybe you need to do some speed profiling to make it all run faster. In all of these cases, you get an absolute memory address. What lives there? Look it up in the memory map!
Charting a Course
Elecia starts out with the map file from a “hello world” program, but it’s a hello world running on an RTOS, so already there’s enough meat to dig into. She starts out with the top-level overview: flash for the code and RAM for the program to use. In flash, the code lives in
.const, and RAM has sections that should be familiar to you like
.stack, but also
.bss. The memory map file also follows this structure: first an overview, then the section markers, and then the details of what’s inside each section.
If you get a crash, for instance, and you know where the numerical value of program counter when it went all pear-shaped, the
.text section lists the function name where that happened. The section with global variable definitions, listed alphabetically? You can probably just scroll on by that — there’s a lot of redundancy in the map file, sometimes sorted by memory address, sometimes sorted alphabetically. You don’t want to read a map file, you just want to dip in, get what you need, and get out. Got a variable that you think is getting overwritten? Find it in the section listed by address, and look at its neighbors — one of them might be overrunning.
But the real star of the show is the beautiful map Elecia made in the style of a role-playing game. Across the River of Initialization from the Static Shores, you’ll find RAMlandia, the high planes of the Stacks, the low boggy Heap Hallows, and the Port of (memory mapped) Peripheral Registers. There are actually dragons in the Ocean of Unused Address Space. By switching back and forth between this fun, but useful, map and the actual text memory map file, Elecia ties a memorable view of memory with the dense text of the map file as it lives in your project folder.
And no talk about memory in microcontrollers is complete without noting the dangers of what happens when the RAM’s heap, which grows downwards, kisses the RAM’s stack, which grows upwards. What happens then? One more function call and the functions start overwriting your data. “This is fine. Like a dog sitting in a cafe on fire.” The problem is, this is the part of memory management that’s dynamic, functions call other functions and memory is allocated and cleared. User input changes which parts of the program run, and thus where data is stored. Here is the one place where the memory map won’t help you, except to find out what’s nearby where the crash happened. But the true answer to “How much RAM do I have now?” truly is ineffably “I dunno.”
If you’re new to embedded design, perhaps the first twenty minutes of the talk is for you, and even if you’re a hardened veteran, you’ll learn something from the later sections. I thoroughly enjoyed Elecia’s talk, and so will you. You can watch it embedded just below. Bring a copy of the slides along too.