Программируем Arduino. Основы работы со скетчами
Шрифт:
Рекурсивный алгоритм вычисления факториала определяется так.
• Если n = 0, факториал числа n равен 1.
• Иначе факториал числа n равен произведению n на факториал (n – 1).
Далее показана реализация этого алгоритма на языке Arduino C:
long factorial(long n)
{
if (n == 0)
{
return 1;
}
else
{
return n* factorial(n — 1);
}
}
Полную
long factorial(long n)
{
long result = 1;
while (n > 0)
{
result = result * n;
n--;
}
return result;
}
С точки зрения удобочитаемости этот код, возможно, выглядит понятнее, а кроме того, он расходует меньше памяти и работает быстрее. Вообще старайтесь избегать рекурсии или хотя бы ограничивайтесь высокоэффективными рекурсивными алгоритмами, такими как Quicksort , который очень эффективно упорядочивает массив чисел.
Сохраняйте строковые константы во флеш-памяти
По умолчанию строковые константы, как в следующем примере, сохраняются в ОЗУ и во флеш-памяти — один экземпляр хранится в коде программы, а второй экземпляр создается в ОЗУ во время выполнения скетча:
Serial.println("Program Started");
Но если использовать код, как показано далее, строковая константа будет храниться только во флеш-памяти:
Serial.println(F("Program Started"));
В разделе «Использование флеш-памяти» далее в этой главе вы познакомитесь с другими способами использования флеш-памяти.
Типичные заблуждения
Многие заблуждаются, полагая, что использование более коротких имен переменных позволяет экономить память. В действительности это не так. Компилятор сам заботится об этом и не включает имена переменных в скомпилированный скетч. Другое распространенное заблуждение: комментарии увеличивают размер программы или объем потребляемой ею оперативной памяти. Это не так.
Некоторые также считают, что организация программного кода в виде множества маленьких функций увеличивает размер скомпилированного кода. Обычно этого не происходит, потому что компилятор достаточно сообразителен для того, чтобы в ходе оптимизации кода заменить вызовы функций их фактическими реализациями. Это обстоятельство помогает писать более удобочитаемый код.
Измерение объема свободной памяти
Узнать, какой объем ОЗУ занимает скетч во время выполнения, можно с помощью библиотеки MemoryFree, доступной по адресу http://playground.arduino.cc/Code/AvailableMemory.
Пользоваться этой библиотекой совсем не сложно: в ней имеется функция freeMemory, возвращающая число доступных байтов. Следующий скетч иллюстрирует ее использование:
#include <MemoryFree.h>
void setup
{
Serial.begin(115200);
}
void loop
{
Serial.print("freeMemory=");
Serial.println(freeMemory);
delay(1000);
}
Эта библиотека может пригодиться при диагностике неожиданных проблем, которые, по вашему мнению, могут быть вызваны нехваткой памяти. Конечно же, использование библиотеки ведет к небольшому увеличению потребления памяти.
Уменьшение используемого объема флеш-памяти
По окончании процедуры компиляции скетча в нижней части окна Arduino IDE появится примерно такое сообщение:
Скетч использует 1344 байт (4%) памяти устройства. Всего доступно 32 256 байт.
Эта строка сообщает точный объем флеш-памяти в Arduino, который будет занят скетчем, благодаря чему вы всегда будете знать, насколько близко подошли к пределу в 32 Кбайт. Оказавшись близко к предельному значению, нужно позаботиться об оптимизации использования флеш-памяти. В этом вам помогут рассматриваемые далее рекомендации.
Используйте константы
Многие, стараясь дать имена контактам, определяют для этого переменные, как показано ниже:
int ledPin = 13;
Если вы не собираетесь изменять номер контакта с именем ledPin в процессе выполнения скетча, то вместо переменной можно использовать константу. Просто добавьте слово const в начало объявления:
const int ledPin = 13;
Это поможет сэкономить 2 байта ОЗУ плюс 2 байта флеш-памяти при каждом использовании константы. Для часто используемых переменных экономия может достигать нескольких десятков байтов.
Удалите ненужные трассировочные вызовы
В процессе отладки скетчей для Arduino принято вставлять в код команды Serial.println, помогающие увидеть значения переменных в разных точках программы и определить источники ошибок. Эти команды потребляют значительный объем флеш-памяти. Любое использование Serial.println требует включения в скетч примерно 500 байт библиотечного кода. Поэтому, убедившись в безупречной работе скетча, удалите или закомментируйте все такие команды.
Откажитесь от использования загрузчика