[Solved] Why the freeRam results are not changing continuously?

human890209
Fri Aug 17, 2018 3:22 pm
Hi,
I made a get freeRam test with Bluepill and Roger’s core. The results are not changing continuously! Why did that happen?
The result doesn’t change for about hundreds of instances, then decrease 4kb suddenly.
And I tried STM32GENERIC core, the result decreased by increase instance number continuously.
Could I get the continuously result by roger’s core?

And ARM’s getFreeRam’ s result won’t recover by delete() or free(). I remember using Arduino Due this happened. And STM32DUINO seems same.
Is there a way to make getFreeRam result recovered by delete() or free()?

#define LEDPIN PC13

bool isOn = true;

// TestClass
class myClass2
{
public:
myClass2(){};
~myClass2(){};
uint8_t content = 0;
//uint16_t content = 0;
//uint32_t content = 0;
};

class myClass
{
public:
myClass(){};
~myClass(){};
//uint8_t content = 0;
//uint16_t content = 0;
//uint32_t content = 0;
myClass2 content;
};

// GetFreeRAM
#ifdef __arm__
// should use uinstd.h to define sbrk but Due causes a conflict
extern "C" char* sbrk(int incr);
#else // __ARM__
extern char *__brkval;
#endif // __arm__

int getFreeRam()
{
char top;
#ifdef __arm__
return (int)(&top - reinterpret_cast<char*>(sbrk(0)));
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
return &top - __brkval;
#else // __arm__
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#endif // __arm__

}

uint32_t count;
uint32_t count_max = 2000;
myClass **classArray;

void setup()
{
Serial.begin(115200);
pinMode(LEDPIN,OUTPUT);
Serial.println(F("Setup"));
count = 1;
delay(2000);
}

void loop()
{
// Check count max
if (count >= count_max)
{
count = 0;
// SoftwareReset Test
#ifdef _LIBMAPLE_NVIC_H_
nvic_sys_reset();
#endif
#ifdef __CORE_CM3_H_GENERIC
NVIC_SystemReset();
#endif
return;
}

// Report count
Serial.print("Count: ");
Serial.println(count);

// Report Basic Size
Serial.print("sizeof(myClass*): ");
Serial.println(sizeof(myClass*));
Serial.print("sizeof(myClass): ");
Serial.println(sizeof(myClass));

// Create the class array
classArray = (myClass**)malloc(count * sizeof(myClass*));
for (uint32_t i = 0; i < count; i++)
{
classArray[i] = new myClass();
}

// Report FreeRam
Serial.print("CreateFreeRam: ");
Serial.println(getFreeRam());
digitalWrite(LEDPIN, isOn);
isOn = !isOn;

// Clear the class array
for (uint32_t i = 0; i < count; i++)
{
delete(classArray[i]);
}
free(classArray);

// Report FreeRam
Serial.print("ResetFreeRam: ");
Serial.println(getFreeRam());

// Loop Delay
delay(50);
count+=10;
}


heisan
Fri Aug 17, 2018 4:07 pm
Roger’s core uses libc malloc/free. free() just returns memory to libc’s allocation pool. It is only actually released to the OS when libc does tail trimming.

I am guessing, but it looks like STM32GENERIC uses gcc’s builtin_malloc() which must free more aggressively.


heisan
Fri Aug 17, 2018 5:16 pm
You can add this to retrieve the amount of free ram which is held by libc (new memory will be allocated from this pool first, before getting more heap with brk()).

// add to top
#include <malloc.h>

// add to dump free memory available inside libc
struct mallinfo mi;
mi = mallinfo();
Serial.println(mi.fordblks);


fpiSTM
Fri Aug 17, 2018 6:10 pm
FYI, You can use this example to display some infos:

https://github.com/stm32duino/STM32Exam … istics.ino


heisan
Fri Aug 17, 2018 6:44 pm
I have been scratching around in STM32GENERIC to try and figure out how they turn off the libc malloc, but can’t figure it out… Does anybody else know?

Rick Kimball
Fri Aug 17, 2018 8:56 pm
STM32GENERIC seems to use nano.specs which will give you a newlib with size optimized functions.

heisan
Fri Aug 17, 2018 9:18 pm
[Rick Kimball – Fri Aug 17, 2018 8:56 pm] –
STM32GENERIC seems to use nano.specs which will give you a newlib with size optimized functions.

Thanks – that little tweak takes 7kB off the flash, and 2.5kB off the RAM usage. Nothing broken (yet), and no obvious performance loss.

EDIT: This also ‘fixes’ human890209’s original problem of RAM not freeing. All RAM is free()ed immediately with this option.


Rick Kimball
Fri Aug 17, 2018 9:33 pm
[heisan – Fri Aug 17, 2018 9:18 pm] –
Thanks – that little tweak takes 7kB off the flash, and 2.5kB off the RAM usage. Nothing broken (yet), and no obvious performance loss.

Try printing some float stuff (dtostrf() printf(), sprintf(), etc )

viewtopic.php?t=1241&start=20#p38392


heisan
Fri Aug 17, 2018 9:43 pm
[Rick Kimball – Fri Aug 17, 2018 9:33 pm] –

[heisan – Fri Aug 17, 2018 9:18 pm] –
Thanks – that little tweak takes 7kB off the flash, and 2.5kB off the RAM usage. Nothing broken (yet), and no obvious performance loss.

Try printing some float stuff (dtostrf() printf(), sprintf(), etc )

viewtopic.php?t=1241&start=20#p38392

Interesting – that one extra option (-u _printf_float) made the resulting binary 2kB bigger than the standard build options…


human890209
Sat Aug 18, 2018 3:04 am
Hi,
Thanks for the advice.
I fix only the platform.txt’s [## Combine gc-sections, archives, and objects] part.
I search the ‘specs=nano.specs’ words in STM32GENERIC core’s platfrom.txt and boards.txt. It only adds this to platform.txt
So I add ‘-specs=nosys.specs -specs=nano.specs -u _printf_float’ there.

The sketch’s Serial print is now continuously changing!
But the freeRAM after delete() and free() still same as the created one. The recycled ram is put in libc.
I don’t understand this.
All RAM is free()ed immediately with this option.

Count: 991
sizeof(myClass*): 4
sizeof(myClass): 1
CreateFreeRam: 2271
mallinfo mi.fordblks: 0
ResetFreeRam: 2271
mallinfo mi.fordblks: 15864
Count: 992
sizeof(myClass*): 4
sizeof(myClass): 1
CreateFreeRam: 2247
mallinfo mi.fordblks: 0
ResetFreeRam: 2247
mallinfo mi.fordblks: 15888


human890209
Sat Aug 18, 2018 5:11 am
To get the real total amount of free ram
I need to sum{(int)(&top – reinterpret_cast<char*>(sbrk(0)));} and {mi.fordblks}.

I canceled the ‘–specs=nano.specs’
Count: 80
sizeof(myClass*): 4
sizeof(myClass): 1
CreateFreeRam: 12199
mallinfo mi.fordblks: 2360
ResetFreeRam: 12199
mallinfo mi.fordblks: 3968
Count: 81
sizeof(myClass*): 4
sizeof(myClass): 1
CreateFreeRam: 12199
mallinfo mi.fordblks: 2344
ResetFreeRam: 12199
mallinfo mi.fordblks: 3968


heisan
Sat Aug 18, 2018 8:39 am
1) You don’t have to use ‘-u _printf_float’ unless you use printf AND you want it to correctly display floats.

2) There may be something wrong with the specs.nano implementation of mallinfo(), as it should not be showing an increasing number of blocks when free RAM is also increasing…


Leave a Reply

Your email address will not be published. Required fields are marked *