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;
}
I am guessing, but it looks like STM32GENERIC uses gcc’s builtin_malloc() which must free more aggressively.
// add to top
#include <malloc.h>
// add to dump free memory available inside libc
struct mallinfo mi;
mi = mallinfo();
Serial.println(mi.fordblks);
[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.
[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 )
[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 )
Interesting – that one extra option (-u _printf_float) made the resulting binary 2kB bigger than the standard build options…
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
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
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…


