А сколько памяти корректно занимать под переменные и прошивку?

Чечако
Offline
Зарегистрирован: 15.06.2018

Компилятор постоянно показывает текущий расклад, за что ему спасибо (ниже для примера):

Скетч использует 17630 байт (57%) памяти устройства. Всего доступно 30720 байт.

Глобальные переменные используют 1162 байт (56%) динамической памяти, оставляя 886 байт для локальных переменных. Максимум: 2048 байт.
 
А есть ли какие-то ограничения кроме этих цифр? Понятно, что скажем динамической памяти занять больше 2048 байт я не могу. Но значит ли это, что я могу реально сожрать все 2048, или какое-то количество с точки зрения cтабильной работы программы я должен оставить свободным? Скажем, если используются переменные типа String?
 
Аналогичный вопрос по флешу - я могу реально отожрать все 30720, или сколько-то я должен сам оставить?
Навскидку гугл мне на эти вопросы ответить не смог. Внутренний параноик говорит, что безусловно сколько-то нужно оставить свободными. Но вот сколько?
b707
Offline
Зарегистрирован: 26.05.2017

По оперативке - чем меньше занято, тем проще жить. Желательно выше 75% не залезать. Если используются String - запас должен быть больше.

Флеш можно занимать хоть весь.

inspiritus
Offline
Зарегистрирован: 17.12.2012

Программа для чпу grbl занимает на нане 97% и вроде ничего критичного в ея фунциклировании не отмечено

однако! Как то залез выше 80% оперативы и получил глюков по полной программе, остерегаюсь теперь я

sadman41
Онлайн
Зарегистрирован: 19.10.2016

По RAM, думаю, точный лимит можно только "прочувствовать". Конечно, если завести у себя в голове компилятор, просчитать все оптимизации, рост стека на вызове вложенных процедур и пр и др, то получиться предсказать ограничение с точностью до байта )

В частности, думаю, можно в критических местах провести промеры свободного объёма ОЗУ и постепенно к ним приближаться. Но, опять же - структура кода изменится, компилятор поменяет стратегию и начинай всё сначала...

И, да, компилятор показывает не всё. Заведёте у себя стринги с маллоками или библиотеку с неопикселями начнёте использовать и вся эта статистика компилятора не будет стоить ломанного гроша.

По ROM же, как ранее написали, можно весь забить - тут компилятор не соврёт в "предсказаниях".

Bobre
Offline
Зарегистрирован: 01.12.2014
// Переменные, создаваемые процессом сборки,
// когда компилируется скетч
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;
}

Работает на atmega328 - Вызываете memoryFree и смотрите сколько осталось RAM.  Как только превысите лимит, в переменных будет появляться мусор, пока это не приведет к критической ошике. Flash можно хоть весь использовать, он все равно не перезаписывается

Чечако
Offline
Зарегистрирован: 15.06.2018

Bobre пишет:

Работает на atmega328 - Вызываете memoryFree и смотрите сколько осталось RAM.  Как только превысите лимит, в переменных будет появляться мусор, пока это не приведет к критической ошике. Flash можно хоть весь использовать, он все равно не перезаписывается

А вот за этот код вам просто ОГРОМНОЕ спасибо. Добавил в проект и погонял как следует. По факту, вместо обещаных компилятором 874 у меня остается 690 максимум. Причем интересно, что в процессе работы оно долго висело на 720, потом прыгнуло на 690, и на этом успокоилось. Буду изучать предметно, на чем это я аж 30 байт сходу потерял. 

Update: 30 байт улетели на две вводимых в том месте в игру переменных типа String. Сурово. Причем сами по себе они хранят по 8 символов максимум. Буду значит минимизировать их использование.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Гонять как следует мало. Надо ещё и замерять где следует ;)

Чечако
Offline
Зарегистрирован: 15.06.2018

sadman41 пишет:

Гонять как следует мало. Надо ещё и замерять где следует ;)

У меня в отладочном режиме раз в секунду в сериал выплевывается средняя загрузка в процентах, теперь туда же выплевывается и остаток памяти. Вполне себе наглядно получается. :)

sadman41
Онлайн
Зарегистрирован: 19.10.2016

На всякий случай проиллюстрирую:


int getRamFree(void) {
  extern int __bss_end;
  extern void *__brkval;
  int freeValue;
  if ((int)__brkval == 0)
    freeValue = ((int)&freeValue) - ((int)&__bss_end);
  else
    freeValue = ((int)&freeValue) - ((int)__brkval);
  return freeValue;
}

void ramDevourer() {
  uint8_t array[500];
  memset(array, 0xFF, sizeof(array));
  Serial.println(getRamFree());
}

void setup() {
  Serial.begin(115200);
  Serial.println(getRamFree());
  ramDevourer();
  Serial.println(getRamFree());
}

void loop(){}