In embedded systems, it is common to write code that runs on "bare metal", i.e. without an operating system. On one hand, it is very empowering. When you write your
main
function (assuming it's C, of course, but that's a safe assumption for 95% of embedded code), you know it has the full control of the processor. Your program is the brains of the chip - whatever you write, the chip performs, without any external code getting in your way.
On the other hand, code running this way misses many of the benefits operating systems provide. Process control, memory management, file system, and so on.
When writing code to run on bare metal, there are some special precautions one must take. One important point to consider is the heap - dynamic memory allocation. An embedded system (think of the safety controller of a Boeing plane) can't just fail because the heap runs out. When
malloc
returns 0 to your desktop-application code, in most cases you will just bail out, because most probably it's the system's fault, and you don't have much choice. In an embedded controller, this is not an option. There is nowhere to bail out to, and in any case, that heap memory ran out is
your fault, a bug in your design or code.
To help managing these complications, embedded programmers often avoid heap allocation altogether, and only use static allocation (i.e. arrays allocated at compile (or more accurately - link/load) time). However, sometimes this is less than optimal, because:
- Dynamic allocation helps write code in a more convenient and reusable way.
- You may be using some 3rd party code that uses dynamic allocation
The solutions to this problem are numerous, but as any self-respecting embedded programmer, I wrote my own fixed-pool memory allocator. It provides a pair of functions:
// 'malloc' clone
//
void* memmgr_alloc(ulong nbytes);
// 'free' clone
//
void memmgr_free(void* ap);
That can be used as a drop-in replacement for
malloc
and
free
, but with a twist. There is no heap involved. All the memory is allocated from, and returned to, a fixed pool of memory that's allocated at link time (in simpler terms: a static array). This way, you know the maximal amount of space your heap will take even before running the program, and can use these functions to test that your program indeed doesn't allocate more than you assumed.
Moreover, the library allows a printout of allocation statistics (which you can enhance, the code is open) that will help diagnose allocation problems and memory leaks.
The library (350 LOC of ANSI C) can be downloaded
from here. Let me know if you've found it useful.