I’m working on a rather large Arduino Project and want to make sure, that my Sketch does not run out of Memory. There are some examples on the Arduino Playground. The free Memory method will be called in the loop() call.
Environment:
- Arduino v1.0.1
- IBoardfrom iteadstudio
Here are the methods I tested.
Free Memory Test #1:
1 2 3 4 5 | int freeRam() { extern int __heap_start, *__brkval; int v; return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); } |
Result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Free Mem: 650 //setup() start //setup Free Mem: 550 //setup() end OSC Ping //loop() start Free Mem: 595 OSC Ping ... Free Mem: 581 OSC Ping ... Free Mem: 317 OSC Ping Test stopped after 1404s |
Free Memory Test #2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | int freeRam() { int byteCounter = 0; // initialize a counter byte *byteArray; // create a pointer to a byte array // More on pointers here: http://en.wikipedia.org/wiki/Pointer#C_pointers // use the malloc function to repeatedly attempt allocating a certain number of bytes to memory // More on malloc here: http://en.wikipedia.org/wiki/Malloc while ( (byteArray = (byte*) malloc (byteCounter * sizeof(byte))) != NULL ) { byteCounter++; // if allocation was successful, then up the count for the next try free(byteArray); // free memory after allocating it } free(byteArray); // also free memory after the function finishes return byteCounter; // send back the highest number of bytes successfully allocated } |
Result:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Free Mem: 318 //setup() start //setup Free Mem: 219 //setup() end Free Mem: 219 //loop() start OSC Ping Free Mem: 255 //after 154s OSC Ping Free Mem: 256 //after 180s OSC Ping Free Mem: 292 //after 292s OSC Ping Free Mem: 293 //after 334s OSC Ping Free Mem: 329 OSC Ping Free Mem: FREEZE! //after 1043s (OR earlier) |
After some more research I found Arduino Bug #857, long story short, malloc/free are buggy in Arduino v1.0.1!
More details can be found on Issue 468.
After I added malloc.c to my Arduino folder and restarted the Arduino IDE the free memory was constant 491/619 bytes (depending on the used method):
1 2 | Free Mem: 619 (Free Memory Test #1) Free Mem: 491 (Free Memory Test #2) |
Note: In the loop() method I send some OSC Messages using the AndOSC Package. Inside the OSCClient::send method, malloc and free calls are used too.
I really hope this issue get’s fixed in the next Arduino release!
Conclusions:
Free Memory functions for Arduino are a little bit voodoo magic, don’t take the absolute value for granted!