ArduinoCore-API icon indicating copy to clipboard operation
ArduinoCore-API copied to clipboard

Official freeRam() command

Open Testato opened this issue 9 years ago • 16 comments

All mcu project may pay attention on Ram use, and have an official command for print freeRam at runtime it is very important. For avr there is a well know freeram function, but it do not work on other architecture, like Zero, Due, etc.

So i think that an official freeRam() function is actually very needed inside the Arduino core, and this also would push third-party core authors to work on their implementation of freeRam().

Testato avatar Aug 25 '16 18:08 Testato

+1

vbextreme avatar Aug 25 '16 18:08 vbextreme

+1

gpb01 avatar Aug 25 '16 18:08 gpb01

+1

max00xam avatar Aug 25 '16 19:08 max00xam

hey guys we now have this +1 function on github, so why not use it instead of spamming? (might not be useable on phones i've heard)

NicoHood avatar Aug 25 '16 20:08 NicoHood

yes, the big rpoblem is that on Phone there is not the way for using it. So the people on the phone always write +1 We may open an issue on the github project :-)

Testato avatar Aug 25 '16 20:08 Testato

+1

Victor795 avatar Aug 25 '16 22:08 Victor795

Ha, +1

PaulStoffregen avatar Aug 26 '16 01:08 PaulStoffregen

+1

connornishijima avatar Aug 26 '16 07:08 connornishijima

Can someone post the function for AVR? Does anyone has the equivalent for the other architectures?

cmaglie avatar Aug 26 '16 07:08 cmaglie

AVR

int freeRam () 
{
extern int __heap_start, *__brkval; 
int v; 
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); 
}

Testato avatar Aug 26 '16 07:08 Testato

Note that the concept of "free RAM" might not be as straightforward as it seems, in particular in the face of dynamic memory allocation and fragmentation, which the above does not consider. This also gives a momentary measurement of the free RAM, with the current stack usage, which people might not understand intuitively. It might still be useful to have such a function, but documentation should be clear on its limitations.

matthijskooijman avatar Aug 26 '16 10:08 matthijskooijman

Here's another version: https://github.com/McNeight/MemoryFree I find it useful for detecting memory leaks.

per1234 avatar Aug 26 '16 11:08 per1234

@matthijskooijman yes, this avr freeRam() version return only the free space beetwen the heap and the stack, but this is the most important value to check, because the other free space that can be inside the heap, caused by memory heap frammentation, collaborates to reduce the space between heap/stack.

So if we can add this second info also it is good, but not essential. In this case we may return two value from freeRam() call

  • the ram value remaining between Heap and Stack
  • the fragmented free heap ram value

Testato avatar Aug 26 '16 12:08 Testato

I think the name is misleading function. taking a cue from the posted code would be nice to something like:

unsigned int stackAvailable() 
{
    extern int __heap_start, *__brkval; 
    unsigned int v; 
    return (unsigned int)&v - (__brkval == 0 ? (unsigned int)&__heap_start : (unsigned int)__brkval); 
}

unsigned int heapAvailable()
{
    unsigned int total = stackAvailable();

    struct __freelist* current;
    extern struct __freelist *__flp;
    for (current = __flp; current; current = current->nx)
    {
        total += 2; /* Add two bytes for the memory block's header  */
        total += (unsigned int) current->sz;
    }

    return total;
}

vbextreme avatar Aug 26 '16 15:08 vbextreme

+1. Ran into out of memory issue quite a few times..

hanabanana avatar Sep 09 '16 18:09 hanabanana

Being pedantic, none of these examples get the types correct. According to the standard, ptrdiff_t should be used to store the result of subtracting pointers, so the function ought to be something like:

#include <stddef.h>

inline ptrdiff_t getAvailableStackSpace(void)
{
	extern int __heap_start;
	extern int * __brkval; 
	
	const int stackTop;
	
	return static_cast<ptrdiff_t>(&stackTop - ((__brkval == 0) ? &__heap_start : __brkval));
}

ptrdiff_t still has the disadvantage of being signed, but it's the correct type for an expression where one pointer is subtracted from another.

I don't know whether it would be semantically wise to try to cast ptrdiff_t, but if that's possible then it might be worth casting to size_t afterwards, as in:

#include <stddef.h>

inline size_t getAvailableStackSpace(void)
{
	extern int __heap_start;
	extern int * __brkval; 
	
	const int stackTop;
	
	return static_cast<size_t>(static_cast<ptrdiff_t>(&stackTop - ((__brkval == 0) ? &__heap_start : __brkval)));
}

Pharap avatar Aug 16 '18 17:08 Pharap