Согласно документации Arduino, ATmega328 имеет 32 КБ флэш-памяти для загрузчика + загруженный эскиз и только 2 КБ SRAM для данных времени выполнения. ATmega2560 имеет немного больше, общий объем 256 КБ и 8 КБ соответственно.
В любом случае эти ограничения кажутся довольно небольшими, особенно по сравнению с потребительскими устройствами аналогичного размера, такими как смартфоны.
Что вы можете сделать, если у вас кончились? Например, если ваш эскиз слишком большой или вам нужно обрабатывать много данных (например, строк) во время выполнения? Есть ли способ расширить Flash или SRAM?
flash
sketch-size
Питер Блумфилд
источник
источник
Ответы:
Оптимизация
Низкоуровневое программирование для встроенных систем весьма отличается от программирования для устройств общего назначения, таких как компьютеры и мобильные телефоны. Эффективность (с точки зрения скорости и пространства) гораздо важнее, потому что ресурсы стоят на первом месте. Это означает, что самое первое, что нужно сделать, если вам не хватает места, это посмотреть, какие части вашего кода вы можете оптимизировать.
С точки зрения сокращения использования программного пространства (Flash) размер кода может быть довольно трудно оптимизировать, если вы неопытны или более привыкли к программированию для настольных компьютеров, которые не склонны к этим навыкам. К сожалению, не существует подхода «волшебной пули», который будет работать во всех ситуациях, хотя он помогает, если вы серьезно задумаетесь над тем, что в действительности должен иметь ваш эскиз . Если функция не нужна, уберите ее.
Иногда также полезно определить, где несколько частей вашего кода одинаковы (или очень похожи). Вы можете сжать их в многократно используемые функции, которые можно вызывать из нескольких мест. Однако имейте в виду, что иногда попытка сделать код слишком многократно используемым на самом деле делает его более многословным. Это сложный баланс для забастовки, который имеет тенденцию приходить с практикой. Можно потратить некоторое время на изучение того, как изменения кода влияют на вывод компилятора.
Оптимизация данных времени выполнения (SRAM) имеет тенденцию быть немного легче, когда вы к этому привыкли. Очень распространенная ловушка для начинающих программистов - использование слишком большого количества глобальных данных. Все, что объявлено в глобальном масштабе, будет существовать в течение всего времени существования эскиза, и это не всегда необходимо. Если переменная используется только внутри одной функции, и она не должна сохраняться между вызовами, то сделайте ее локальной переменной. Если значение должно быть разделено между функциями, подумайте, можете ли вы передать его как параметр вместо того, чтобы делать его глобальным. Таким образом, вы будете использовать SRAM только для тех переменных, которые вам действительно нужны.
Еще одним убийцей использования SRAM является обработка текста (например, использование
String
класса). Вообще говоря, вам следует избегать выполнения операций со строками, если это возможно. Они огромные боровы памяти. Например, если вы выводите много текста в последовательный порт, используйте несколько вызововSerial.print()
вместо вместо конкатенации строк. Также попытайтесь сократить количество строковых литералов в вашем коде, если это возможно.Избегайте рекурсии, если это возможно. Каждый раз, когда выполняется рекурсивный вызов, стек поднимается на уровень глубже. Перефразируйте ваши рекурсивные функции, чтобы они стали итеративными.
Использование EEPROM
EEPROM используется для долговременного хранения вещей, которые изменяются только изредка. Если вам нужно использовать большие списки или справочные таблицы с фиксированными данными, подумайте о том, чтобы заранее сохранить их в EEPROM и извлекать только то, что вам нужно, когда это необходимо.
Очевидно, что EEPROM довольно ограничен по размеру и скорости и имеет ограниченное количество циклов записи. Это не лучшее решение для ограничения данных, но этого может быть достаточно, чтобы облегчить нагрузку на Flash или SRAM. Также возможно взаимодействие с аналогичным внешним хранилищем, таким как SD-карта.
Расширение
Если вы исчерпали все остальные варианты, возможно, расширение возможно. К сожалению, расширение флэш-памяти для увеличения места в программе невозможно. Тем не менее, есть возможность расширить SRAM. Это означает, что вы сможете реорганизовать свой эскиз, чтобы уменьшить размер кода за счет увеличения размера данных.
Получить больше SRAM на самом деле довольно просто. Один из вариантов - использовать один или несколько чипов 23K256 . Доступ к ним осуществляется через SPI, и есть библиотека SpiRAM, которая поможет вам их использовать. Просто знайте, что они работают при 3,3 В, а не 5 В!
Если вы используете Mega, вы также можете получить щиты расширения SRAM от Lagrangian Point или Rugged Circuits .
источник
Когда вы загружаете свой код в Arduino, например, в Uno, он сообщит вам, сколько байтов он использует из доступных 32K. Вот сколько у вас флеш-памяти (вспомните жесткий диск компьютера). Пока ваша программа работает, она использует то, что называется SRAM, и этого гораздо меньше.
Иногда вы замечаете, что ваша программа ведет себя странно в тот момент, которого вы даже не трогали некоторое время. Может случиться так, что ваши последние изменения приводят к нехватке памяти (SRAM). Вот несколько советов о том, как освободить SRAM.
Хранение строк во Flash вместо SRAM.
Одна из самых распространенных вещей, которые я видел, - это нехватка памяти в чипе, потому что слишком много длинных строк.
Используйте эту
F()
функцию при использовании строк, чтобы они сохранялись во Flash, а не в SRAM, поскольку у вас их гораздо больше.Используйте правильные типы данных
Вы можете сохранить байт, переключившись с
int
(2 байта) наbyte
(1 байт). Байт без знака даст вам 0-255, поэтому, если у вас есть числа, которые не превышают 255, сохраните байт!Как я узнаю, что у меня заканчивается память?
Обычно вы наблюдаете, как ваша программа ведет себя странно, и удивляетесь, что пошло не так ... Вы ничего не изменили в коде рядом с точкой, в которой происходит сбой, так что дает? Недостаточно памяти.
Есть пара функций, чтобы сказать вам, сколько свободной памяти у вас есть.
Доступная память
источник
F()
, является ли эта функция специфичной для Arduino, или это в библиотеках AVR? Вы могли бы также упомянутьPROGMEM const ...
.В дополнение к тому, что сказали другие (с чем я полностью согласен), я бы посоветовал прочитать эту статью о памяти; он хорошо написан, объясняет много вещей о памяти и дает советы о том, как ее оптимизировать.
В конце чтения, я думаю, вы получите довольно полный ответ на свой вопрос.
Подводя итог, у вас есть 2 возможных цели оптимизации (в зависимости от того, где у вас проблемы с памятью):
F()
макрос)Также описан дополнительный подход к сокращению использования SRAM (но он используется редко, поскольку он немного тяжел при кодировании и не очень эффективен), он заключается в использовании EEPROM для хранения данных, созданных вашей программой, но не используется до тех пор, пока в некоторых условиях происходят, когда данные могут быть загружены обратно из EEPROM.
источник
Есть две вещи, которые нужно сделать, если у вас не хватает памяти:
В Интернете есть множество советов о том, как сделать первое (и для подавляющего большинства вещей, которые люди делают с Arduino, встроенной памяти более чем достаточно после «оптимизации»). Поэтому я сосредоточусь на втором:
Есть 3 вещи, которые используют флэш или SRAM; каждому нужен немного другой подход к добавлению хранилища:
хранилище переменных: можно расширить SRAM, как уже указывало sachleen. SRAM, FRAM и NVSRAM подходят для быстро меняющихся переменных. (Хотя в принципе вы можете использовать флэш-память для хранения переменных, вам придется беспокоиться о ее износе). SPI (последовательный протокол) проще всего подключить к Arduino. Библиотека SpiRAM работает с последовательным чипом SRAM Microchip 23K256 . Серийный чип FRAM Ramtron FM25W256 (теперь принадлежащий Cypress) также использует SPI. Cypress CY14B101 NVSRAM также использует SPI. И т.п.
постоянные данные, которые должны все еще быть в следующий раз при включении питания: это почти так же просто, как расширение SRAM. Существует много внешних устройств хранения EEPROM, FRAM, NVSRAM и FLASH . В настоящее время самая низкая стоимость за МБ - это флэш-карты SD (доступ к которым можно получить через SPI). Ramtron FM25W256 (см. Выше), Cypress CY14B101 (см. Выше) и т. Д. Также могут хранить постоянные данные. Многие экраны расширения включают в себя слот для SD-карт, а несколько библиотек и учебных пособий поддерживают чтение и запись на (флэш) SD-карты. (Мы не можем использовать SRAM для этого, потому что SRAM забывает все, когда отключается питание).
исполняемый код: К сожалению, расширение флэш-памяти Arduino для увеличения места в программе невозможно. Тем не менее, программист всегда может выполнить рефакторинг эскиза, чтобы уменьшить размер кода за счет увеличения размера данных и замедления его выполнения. (Теоретически, вы можете зайти так далеко, чтобы перевести весь ваш набросок на какой-то интерпретируемый язык, сохранить эту версию вашего наброска на SD-карте, а затем написать интерпретатор для этого языка, который работает на Arduino, для извлечения и выполнения инструкций из SD-карта - Forth on Arduino , BASIC-переводчик, переводчик Tom Napier Picaro, некоторые специфические для приложения языки и т. Д.).
источник