Re: Sanity checking
2009-02-23 by Don Kinzer
--- In AVR-Chat@yahoogroups.com, David VanHorn <microbrix@...> wrote:
> In C, is there a simple way to test wether the system has
> run out of memory while the program is running?
Simple? No. But there is a way. The issues involved depend on
which resources you're using in your C program. It also depends on
whether you're using external RAM or not. For the sake of
simplicity, the discussion below assumes no external RAM.
To review, RAM is divided into three areas: 1) statically allocated
data items (whether initialized or not), 2) the heap (from which
malloc() allocates space) and 3) the stack. The statically
allocated data items are assigned addresses in low RAM, beginning
with the first available RAM address (which value depends on which
AVR you're using). The heap begins just above the statically
allocated data items and grows toward the high end of RAM. The
stack begins at the high end of RAM and grows toward the low end of
RAM. Naturally, bad thing tend to happen if the stack grows into
the heap and/or the statically allocated data items.
You can exploit these facts to help determine when the RAM areas are
colliding. The basic idea is to "seed" the RAM used by the heap and
stack and then examine the contents from time to time to see how
much of the seeded area remain untouched. If you're not using the
heap, you can determine programmatically how much unused space is
left by scanning upward from the end of the statically allocated
data until you find the first location with content different from
the seed value. If you are using the stack, the problem is
complicated by the fact that you have two dynamic areas whose ends
can be higher or lower at any time.
The code below can be used to seed the heap/stack RAM space. It
will be inserted into the startup initialization sequence fairly
early, just after the stack pointer has been initialized. It could
be placed in one of the other initialization sections but .init2
should be suitable for most applications. If you examine the .lss
file after compiling/linking with this code added, you'll see that
the resulting code appears several instructions after the initial
startup instruction.
Don Kinzer
ZBasic Microcontrollers
http://www.zbasic.net
#define USED __attribute__((used))
#define NAKED __attribute__((naked))
#define INIT2 __attribute__((section(".init2")))
extern uint8_t *_end; // the end of statically allocated data
extern uint8_t *__stack; // the end of internal RAM
static void seedRAM(void) NAKED USED INIT2;
static void seedRAM(void)
{
#define SEED_VAL 0xcc
uint16_t addr;
for (addr = (uint16_t)&_end; addr < (uint16_t)&__stack; addr++)
*(uint8_t *)addr = SEED_VAL;
#undef SEED_VAL
}