Arduino IDE - хранение глобальных переменных в оперативной или флеш-памяти - PullRequest
0 голосов
/ 31 октября 2019

Традиционно считается, что глобальные и статические данные хранятся в нижней части ОЗУ вместе с другими вещами. Где-то выше это куча, затем свободная память, а в верхней части оперативной памяти находится стек. Перед прочтением ознакомьтесь с приведенным ниже кодом.

Когда я компилирую это с помощью IDE Arduino (1.8.10) на MEGA2560, я получаю следующую статистику:

Sketch использует 2750 байт (1%)места для хранения программ. Максимум 253952 байта. Глобальные переменные используют 198 байтов (2%) динамической памяти, оставляя 7994 байта для локальных переменных. Максимум - 8192 байта.

Если я изменю ARRAY_SIZE с 1 на 7001, я получу точно такие же числа. Я ожидал, что динамическая память должна увеличиться на 7000. Когда я делаю то же самое сравнение с AtmelStudio V7, динамическая память действительно увеличивается на 7000.

Еще одна часть информации в этом направлении. Если я сделаю malloc 7000, который довольно близок к свободной памяти, можно ожидать, что malloc должен быть успешным, когда ARRAY_SIZE равен единице, и потерпит неудачу, когда ARRAY_SIZE равен 7001. Я был встревожен, обнаружив, что malloc был успешным с обоимималенький и большой размеры массива. С AtmelStudio этого не происходит.

Я подозреваю, что соответствующие параметры компилятора / компоновщика могут где-то объяснить разницу (AtmelStudio - свойства проекта и Arduino IDE - platform.txt, возможно?).

Я также подозреваючто IDE Arduino динамически распределяет глобальные переменные в FlashMemory.

Я не новичок, но я не гуру - кто-нибудь комментирует?

Спасибо Michèle

Спасибо заответ. Я добавил некоторый код для имитации использования массива, добавив параметр 'a', который суммирует содержимое массива и затем печатается. Это решает проблему. Я думал, что инициализация массива была достаточной. Что касается AtmelStudio, так как я работал в режиме отладки, оптимизации отключены и, следовательно, не инициализируют массив.

Проблема решена.

Спасибо, Michèle

#define ARRAY_SIZE 3001
uint16_t globalArray[ARRAY_SIZE] {1};
void setup() {
  Serial.begin(115200);
  for (int i = 0; i < ARRAY_SIZE; i++) globalArray[i] = 1;
  Serial.print(F("Just initialized globalArray, size = ")); Serial.println(ARRAY_SIZE);
  uint16_t a {0};
  for (int i = 0; i < ARRAY_SIZE; i++) a +=globalArray[i];
  Serial.print(F("Value of a = ")); Serial.println(a);
  Serial.print(F("Just initialized globalArray, size = ")); Serial.println(ARRAY_SIZE);
  uint8_t* testPointer = (uint8_t*) malloc(7000);
  Serial.print(F("Allocation of 7000 bytes "));
  if ( testPointer != (uint8_t*) 0) {
    Serial.print(F("SUCCESSFUL"));
  } else {
    Serial.print(F("NOT SUCCESSFUL"));
  }
} // setup
void loop() {} // loop

1 Ответ

0 голосов
/ 01 ноября 2019

Я провел еще несколько тестов, чтобы выяснить, почему AtmelStudio и Arduino IDE предоставляют совершенно разные значения использования ОЗУ после объявления массива. Ответ от juraj (спасибо) состоял в том, что компилятор оптимизировал неиспользуемый код. Этот ответ был верным, однако я включил цикл инициализации массива, чтобы компилятор включал массив в код. Оказывается, что AtmelStudio и Arduino IDE имеют разные критерии для кодирования того, что означает «используемый код». В результате globalArray в строке инициализации для (int i = 0; i

a + = globalArray [i];не используется Atmel Studio: использование памяти данных как 7211 байт IDE Arduino: глобальные переменные используют 198 байт

a + = globalArray [i];использовал Atmel Studio: использование памяти данных как 7211 байт. Arduino IDE: глобальные переменные используют 7199 байт

QED Интересно, что две IDE не совсем означают одно и то же с «использованием».

Спасибо - мой первый раз на этом форуме я получил ответ на мой вопрос довольно быстро.

Michèle

#define ARRAY_SIZE 7001
uint8_t globalArray[ARRAY_SIZE];
void setup() {
  Serial.begin(115200);
  for (int i = 0; i < ARRAY_SIZE; i++) globalArray[i] = 1;
  Serial.print(F("Just initialized globalArray, size = "));
  Serial.println(ARRAY_SIZE);
  //   uint16_t a {0};
  //   for (int i = 0; i < ARRAY_SIZE; i++) a+=globalArray[i];
  //   Serial.print(F("Value of a = ")); Serial.println(a);
  uint8_t* testPointer = (uint8_t*) malloc(7000);
  Serial.print(F("Allocation of 7000 bytes "));
  if ( testPointer != (uint8_t*) 0) Serial.print(F("SUCCESSFUL"));
  else Serial.print(F("NOT SUCCESSFUL"));
} // setup
...