[Как определить, сколько осталось свободной оперативной памяти (RAM)]
Это может оказаться полезным, когда скетч работает некорректно, и трудно определить причину ошибки. Ниже на примере показано, как определить количество свободной памяти RAM вызовом функции memoryFree.
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(memoryFree()); // печать количества свободной оперативной памяти
Serial.print(' '); // печать пробела
delay(1000);
}
// Переменные, создаваемые процессом сборки,
// когда компилируется скетч
extern int __bss_end;
extern void *__brkval;
// Функция, возвращающая количество свободного ОЗУ (RAM)
int memoryFree()
{
int freeValue;
if((int)__brkval == 0)
freeValue = ((int)&freeValue) - ((int)&__bss_end);
else
freeValue = ((int)&freeValue) - ((int)__brkval);
return freeValue;
}
Пользовательская функция memoryFree использует системные переменные для вычисления количества свободной оперативной памяти RAM. Обычно системные переменные невидимы - они создаются компилятором для собственного использования (для управления внутренними ресурсами).
Количество свободной памяти может меняться с течением времени, пока работает Ваша программа. Очень важно удостовериться, что Вы не тратите больше памяти, чем имеется в наличии у системы.
Вот несколько основных причин потребления памяти RAM:
• Когда Вы инициализируете константы:
#define ERROR_MESSAGE "Произошла ошибка"
• Когда Вы декларируете глобальные переменные:
char myMessage[] = "Hello World";
• Когда делаете вызов функции:
void myFunction(int value)
{
int result;
result = value * 2;
return result;
}
• Когда динамически выделяете память:
String stringOne = "Arduino String";
Объект String системы Arduino использует динамическое выделение памяти для строк. Вы можете проверить это, если добавите в начало кода примера определение строки String s = "\n";, и затем добавите в код loop перед задержкой строки:
s = s + "Hello I am Arduino \n";
Serial.println(s);
После запуска этого варианта скетча Вы увидите, что количество памяти уменьшается, потому что каждая прокрутка цикла loop увеличивает размер строки. В какой-то момент память переполнится, и программа перестанет работать. Поэтому не увеличивайте размер строк сверх необходимого, и следите за их размером. Также будьте особенно внимательны с кодом, который использует динамическое выделение памяти. Не пишите код, который динамически создает разное количество переменных в зависимости от некоторых параметров во время своей работы, потому что очень сложно бывает найти ошибки во время выполнения кода, связанные с переполнением памяти.
Также в библиотеках часто объявляются константы и глобальные переменные, о которых Вы можете не знать, но они также расходуют RAM. У библиотеки Serial, например, есть глобальный массив из 128 байт, который используется как буфер для приходящих последовательных данных. Только это использует одну восьмую от общего объема памяти старого Arduino на микроконтроллере ATmega168.
Подробнее про использование памяти AVR см. [1].
[Ссылки]
1. AVR GCC: области памяти и использование malloc(). |