Как обнаружить ошибки переполнения памяти в коде Arduino C?


10

Несколько раз у меня возникали некоторые подозрительные результаты на Serial Monitor после загрузки кода в Arduino: например, вечный вывод пробелов или внезапный разрыв строк или зашифрованных строк.

Поскольку в Arduino IDE не было ни ошибки компиляции, ни предупреждения, я подумал, что Arduino не работает, но после некоторых тестов я обнаружил, что компилятор Arduino IDE перехватывает не все виды ошибок, особенно при назначении переменных в цикле для структур массива. Это, кажется, разбивает Arduino за короткий промежуток времени.

Как я могу обнаружить ошибки, не отображаемые в Arduino IDE?

Ответы:


10

Библиотека MemoryFree может помочь вам найти риски с использованием памяти.

Пример:

#include <MemoryFree.h>

// On Arduino Duemilanove with ATmega328:
//
// Reported free memory with str commented out:
// 1824 bytes
//
// Reported free memory with str and Serial.println(str) uncommented:
// 1810
//
// Difference: 14 bytes (13 ascii chars + null terminator)

// 14-bytes string
//char str[] = "Hello, world!";


void setup() {
    Serial.begin(115200);
}


void loop() {
    //Serial.println(str);

    Serial.print("freeMemory()=");
    Serial.println(freeMemory());

    delay(1000);
}

Я не уверен, что MemoryFree учитывает указатель стека. Если ваш указатель стека сталкивается с указателем кучи, вы можете столкнуться с ошибками сегментации.


7

Наиболее распространенной причиной исчерпания ОЗУ является использование объекта String или использование множества константных символов (строка в стиле c).

Forteantly IDE 1.0.4 включает в себя исправление malloc, которое мучает объект String в течение очень долгого времени.

Чтобы уменьшить объем оперативной памяти, потраченной на строки с постоянными символами, такие как:

Serial.print("Hello World");  // This consumes RAM!

Вы можете использовать макрос F (). Этот макрос заставит массив символов оставаться в PROGMEM. Когда используется массив, используется только один байт памяти.

Serial.print(F("Hello World"));  // Keeps the character-array in PROGMEM

Помните, что строки, хранящиеся в PROGMEM, не могут быть изменены во время выполнения.

Что касается обнаружения, то без отладчика или контроллера памяти вы должны использовать устаревшие детективные методы, чтобы найти, где возникают проблемы.


1
Спасибо за полезный ответ! Там действительно нет поддержки IDE памяти отладчика?
Powtac

1
Это старый вопрос, но да, существуют правильные отладчики для микроконтроллеров ATmela ATmega . Для arduinos нет отладчиков , потому что набор инструментов arduino и «IDE» - это в основном игрушка.
Коннор Вольф

1
На самом деле ваш намек на F () сэкономил нам несколько сотен байтов в оперативной памяти!
Powtac

1
Я получаю ошибку компиляции при использовании F () со строками, которые содержат //. :-(
Powtac

Я получаю эту ошибку компиляции на Arduino 1.5.7 ...
powtac

3

Похоже, вы говорите об ошибках во время выполнения (типа утечки памяти / типа segfault) здесь.

Нет никакого способа обнаружить такие ошибки (если вы не очень тщательно прочесываете код) в уже написанном коде. Тем не менее, это довольно легко предотвратить во время написания кода. Просто будьте очень осторожны при написании циклов или рекурсивных вызовов; спросите себя "может ли это выйти из-под контроля?" Если это выглядит так, как будто это «выходит из-под контроля», тогда напишите код для защиты от этого.

О segfaults - просто проверьте граничные значения индексов массива, и все должно быть в порядке. Если вы используете указатели, будьте осторожны с арифметикой указателей.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.