free memory program stopped working with 13

The way to find the amount of free ram as stopped working with 13.

int availableMemory() {
int size = 1024;
byte *buf;
while ((buf = (byte *) malloc(--size)) == NULL);
free(buf);
return size;
}

I get the same result despite of whatever I add.

int test[250][25]; and still get 769 bytes free .

Did you add that 2D array as a local variable (i.e. inside a function, on the stack) or as a global?

That has never been a particularly robust way of estimating free memory. It only finds the largest contiguous heap block that malloc() can allocate.

The ATmega168 RAM which your sketch uses can be organized into four different purposes:

  • variable initializer constants
  • declared global variable instances
  • heap space allocatable by malloc()
  • call stack (including auto variable instances)

(Ooh, I found this nice site: avr-libc: Memory Areas and Using malloc() )

The first one is really a quirk of the Atmel architecture; the compiler doesn't know how to initialize from PROGMEM directly. It could be improved, however, if the memory for initializers are reused after the sketch has entered main().

The variables that you declare globally take up space for the whole time the program is running. You can use avr-objdump or other elf tools to determine this size.

The heap that malloc() uses has an overhead for every allocation, and if you allocate a bunch of small amounts, then free them, you may not be able to allocate a large chunk anymore. This is called heap fragmentation, and I doubt the Atmel gcc library is particularly careful to reduce this problem.

Lastly, whenever you call a function, the new variables on the stack cause the stack to grow. If you call a function that calls a function, that is cumulative. The available heap is reduced when the stack grows, since they're both using the same RAM space. When the function returns, the stack shrinks and the available heap grows.

The stack and the heap will collide if you call too deeply after allocating enough memory, causing a crash or other unpredictable behavior. However, I've not yet seen a true repeatable test that shows how close the stack and the heap are to colliding. (A good test would be to ask the heap library where a 1-byte allocation would be returned without actually allocating it, and comparing it to a fresh new stack variable.)

After looking at avr libc malloc's implementation, I am guessing this is a suitable free heap measurement (assuming no heap fragmentation). I have not tested this:

int available()
{
    byte stack = 1;
    extern char *__brkval;
    extern char *__malloc_heap_end;
    extern size_t __malloc_margin;
    if (__malloc_heap_end)
        return __malloc_heap_end - __brkval;
    return (&stack - __brkval) - __malloc_margin;
}

This is what I've been using. Malloc doesn't seem to work on every platform (why the platform cares I don't know, but it alarms me)?!?

And that first algorithm is somewhat expensive as it loops. This one takes the address of a local variable and compares it to the address of the bottom of the stack. I lost track of where I first saw the technique, but it made sense to me.

// this function will return the number of bytes currently free in RAM
extern int __bss_end;
extern int *__brkval;
int freemem(){
int free_memory;
if((int)__brkval == 0)
free_memory = ((int)&free_memory) - ((int)&__bss_end);
else
free_memory = ((int)&free_memory) - ((int)__brkval);
return free_memory;
}

It in the first couple of statments "global"

and tested the ram in setup() and the end of the loop()

works o.k in 12 , but 13 gives the same.

thinks for more reading halley

I relatively new to embedded micros, so it`s all learning.
That program looked to be a nice and simple way to keep myself in check and give to a clue of memory use.

The latest version of the compiler/linker seems to be more aggressive about optimizing away functions and data that are not actually used.
I can take the "Blink" example and add an array:int foo[100]; and my final sketch size doesn't actually increase unless I also add a statement like foo[0] = 0; to the sketch.

This first example is the build of the unmodified Blink file. The important bits are the size of the "data" and "bss" sections, which are both part of (but not all of) RAM usage. Temp*.o is the sketch itself (which in the case of Blink has only the two bytes of ledPin.) Blink.elf is the complete (fully optimized) sketch as will be uploaded into the arduino, including the Arduino core (and in particular 128 bytes of serial buffer. (hmm. Even though it's not used!))

/Downloads/Arduino-0013/hardware/tools/avr/bin/avr-size Blink.elf Temporary_*.o            
   text         data          bss          dec          hex filename
     72            2            0           74           4a Temporary_7099_8569.cpp.o
   1218            8          148         1374          55e Blink.elf

This second example is after adding "int foo[100];" to the sketch. As you might expect, the RAM used in the Temp*.o file goes up by 200 bytes. However, notice that the RAM usage by the final sketch does NOT go up. Something (the linker, I guess) has noticed that nothing accesses the new array, so it leaves it out!

/Downloads/Arduino-0013/hardware/tools/avr/bin/avr-size Blink.elf Temporary_*.o
   text         data          bss          dec          hex filename
     72            2          200          274          112 Temporary_670_2817.cpp.o
   1218            8          148         1374          55e Blink.elf

The last example is after adding "foo[0] = 0;" to the setup() function in Blink. Now, the array IS accessed and cannot be optimized away, and the final sketch size did indeed get bigger.

 /Downloads/Arduino-0013/hardware/tools/avr/bin/avr-size Blink.elf Temporary_*.o
   text         data          bss          dec          hex filename
     80            2          200          282          11a Temporary_3391_8020.cpp.o
   1226            8          348         1582          62e Blink.elf

Sorta neat, actually.

I know someone hacked the IDE to show "size of sketch" summary in the colored bar between editor and terminal. It would be great if there were multiple capacity bars (like progress bars) that showed the sizes of PROGMEM used vs PROM, DATA and BSS vs RAM, and in the future, EEMEM used vs EEPROM.

One other little gotcha that I noticed in the malloc code: if you use any malloc() in your sketch, and you have an ISR in your sketch, be even more careful about how close you fill the heap. There is a safety buffer size so malloc tries not to smash the stack, but it's really quite small. Your C-coded ISR might smash a malloc'd object accidentally, since it must save so many general registers on the stack.