Глобальные переменные занимают много места в динамической памяти.
Я использую две простые библиотеки (см. 1, 2) Я нашел в Интернете свой код на Arduino Uno, к сожалению, я также использую ROS, и все эти библиотеки занимают много места , когда я компилирую свой код, я получаю эту ошибку:
Global variables use 2,112 bytes (103%) of dynamic memory, leaving -64 bytes for local variables. Maximum is 2,048 bytes.
Я укоротил строки, но этого оказалось недостаточно. Как я могу изменить код в библиотеках, чтобы уменьшить использование памяти?
Кажется, я не совсем понимаю концепцию глобальных переменных. Например, я изменил все переменные double
в библиотеках на переменные float
, но это совсем не изменило использование динамической памяти. Как я могу использовать меньше памяти?
@Natjo, 👍2
Обсуждение3 ответа
Лучший ответ:
Когда вы пишете программу, часть памяти может быть определена во время компиляции из-за ее предопределения (float
и double
в Arduino — не модель Due — используйте 4 байтов каждый - в Due double
использует 8 байтов для 64-битной точности).
Но есть часть памяти, о которой можно узнать только во время выполнения; где мы говорим об объектах (или массивах, определяемых пользовательским вводом). В этих случаях программам необходимо динамически выделять память, для чего в язык C++ встроены операторы new
и delete
. Дополнительная информация: Динамическая память.
Вы должны управлять созданием объектов и массивов (они создаются с помощью new
, а затем удаляются с помощью delete
).
Если ваши требования превышают ресурсы любого Arduino (кроме Arduino Due), вам следует перейти на модель Due, которая имеет больше памяти и вычислительной мощности (но меняет 5 В на 3,3 В, будьте осторожны).
Существует также Mega 2560, который имеет ту же архитектуру, что и Uno (AVR), но в 4 раза больше оперативной памяти., @Edgar Bonet
@jonas У меня была похожая проблема, не совсем превышающая лимит. Одна вещь, которую вы можете сделать, это переместить строки во Flash.
<pgmspace.h>
есть определение PSTR, которое помещает литерал во flash
имя шаблона, которое мы обычно используем просто strcpy, нам нужно использовать strcpy_P.
strcpy_P указывает, что строка будет получена из флэш-памяти и скопирована в пространство SRAM. Как только он окажется в памяти SRAM, мы сможем манипулировать им, как захотим.
например:
setPatternName((char*)PSTR("My PatternName"));
void setPatternName(const char* text) {
memset(patternName, MAX_PATTERN_NAME_LEN + 1, 0 );
strcpy_P(patternName, text);
int length = strlen(patternName);
}
Это должно привести к значительному сокращению использования памяти.
char buf[50];
char* tm1Txt (byte num){
if (num == 0){strcpy_P(buf, (char*) F("t1 - Задepжka koмaнды xoд"));}
if (num == 1){strcpy_P(buf, (char*) F("t2 - Bpeмя cepвoфиkcaции "));}
if (num == 2){strcpy_P(buf, (char*) F("t3 - Bpeмя дoтягивания "));}
if (num == 3){strcpy_P(buf, (char*) F("t4 - Bpeмя тopмoжeния "));}
if (num == 4){strcpy_P(buf, (char*) F("t5 - Наложениe тормоза "));}
if (num == 5){strcpy_P(buf, (char*) F("t6 - Снятия нагр воздуха "));}
return buf;
}
- Ошибка: "'lcd' does not name a type" при использовании библиотеки LiquidCrystal.
- Программирование Arduino Uno R3 для срабатывания реле каждые 24 часа
- Попытка сохранить файлы .wav с новым именем в каждом цикле.
- Как управлять двумя шаговыми двигателями и использовать ультразвуковой датчик вместе?
- Матрица и пространство состояний Реализация Arduino
- Новый код приводит к звуковому шуму
- Вызов метода в основном скетче из библиотеки.
- Светодиодное кольцо с различными эффектами циклически
Вы поместили свои строковые литералы во флэш-память?, @KIIV
Я сократил их до 1 буквы, чтобы посмотреть, насколько это уменьшит размер, но размещение во флэш-памяти не решит проблему, так как ее недостаточно., @Natjo
Что ж, тогда вы должны предоставить свой код, чтобы мы могли его попробовать..., @KIIV
Я проверил, и около 75% глобальных переменных уже используются библиотеками, которые я использую. Поскольку они с открытым исходным кодом, я прыгал, чтобы изменить их. Они представлены в ссылках, которые я дал в своем вопросе., @Natjo
Очень общее описание: переменным, которые зависают (глобальные, статические и т. Д.), Присваивается собственное место в памяти в ОЗУ, переменным с ограниченной областью действия временно назначается место в памяти в ОЗУ в области, называемой стеком, и переменные, которые никогда не изменяются. можно поместить в память программ. На встроенном процессоре это обычно означает помещение переменной во флэш-память., @st2000
Это совет «с ходу», поэтому это всего лишь комментарий, а не ответ, но, если вам не хватает памяти, почему бы не переключиться на Arduino на базе ARM. Многие Arduino на базе ARM имеют гораздо больше памяти, чем, скажем, Uno., @st2000
Сколько из этих объектов вы создаете? Наиболее очевидным кандидатом на экономию памяти является
double lastInputs[100]
вклассе PID_ATune
. Он занимает 400 байт. Если вы сократите этот массив, убедитесь, что вы не получаете к нему доступ из связей., @Edgar Bonet@EdgarBonet Я уменьшил число до 80, помогло, спасибо! Почему это не меняет потребление памяти, если я изменяю двойное число на плавающее?, @Natjo
@Jonas, потому что в Arduino double и float имеют одинаковый размер: https://www.arduino.cc/en/Reference/Float или https://www.arduino.cc/en/Reference/Double., @Mali
Первая библиотека определяет класс
PID_ATune
, который содержит множество элементов, включая массив из 100double
, т.е. 400 байтов для каждого экземпляраPID_ATune
. Не уверен, что там нужно так много двойников, но вы можете сначала попытаться уменьшить это число., @jfpoilpretВы решили это, я столкнулся с той же самой проблемой! так как в настоящее время я использую библиотеку автонастройки! и не может оптимизировать пример кода! пожалуйста помоги, @Mutaz alHawash
К сожалению, я не смог решить проблему. Я думаю, что в то время я перешел на более крупный микроконтроллер. Извиняюсь. Вы могли бы попробовать использовать исходный код библиотеки автонастройки напрямую и настроить ее?, @Natjo