Ошибка сегментации и огромная потребность в SRAM для Serial.println
Я написал свой собственный 'assert', так как хочу использовать его как для Windows, так и для Arduino. Класс вызывается из многих файлов (около 10).
AssertUtils.h:
#pragma once
#define assert(expr) AssertUtils::Assert2((expr), (__func__), (__FILE__), (__LINE__));
class AssertUtils
{
public:
static void Assert2(bool expression, const char* funcName, const char* fileName, int line);
};
AssertUtils.cpp:
#include "AssertUtils.h"
#include "Arduino.h"
/* static */ void AssertUtils::Assert2(bool expression, const char* funcName, const char* fileName, int line)
{
if (!expression)
{
Serial.println(funcName);
Serial.println(fileName);
Serial.println(line, DEC);
Serial.flush();
// Abort program execution.
abort();
}
}
Когда я компилирую это, использование SRAM составляет 1469 байт (вместе с остальной частью моего скетча и классов).
Когда я комментирую строку ниже, я получаю ошибку сегментации в случайном вызове assert (когда я комментирую этот вызов, я получаю его в следующем и т. д.).
//Serial.println(funcName);
Когда я также комментирую второй оператор печати, компилятор сообщает об использовании только 1137 байт SRAM (чего я ожидаю, так как это было примерно равно до того, как я добавил класс Assert).
//Serial.println(funcName);
//Serial.println(fileName);
Вопросы:
- Как избавиться от ошибки сегментации?
- Как может быть, что около 332 байт используются для одного и двух дополнительных операторов печати? (возможно, это связано с буферизацией const char* (?)
@Michel Keijzers, 👍0
Обсуждение1 ответ
Лучший ответ:
Обратите внимание, что это не МОЙ ответ, а приблизительное сочетание первых 5 комментариев из моего исходного вопроса.
Я сделал следующее:
- (Юрай) Изменена версия компилятора на 6.21
- (juraj) Добавлена буква F в
F(__FILE__)
- (KIIV) Удалено функция; это не сработало с помощью
F
flash helper, но я все равно могу однозначно найти код из-за имени файла и номера строки. - (Маженко) Я удалил класс и использую макрос. Это требует больше флэш-памяти (в зависимости от количества утверждений, которые я использую, но у меня все еще около 40% (было 35%).
Использование SRAM теперь составляет 1125 байт, даже меньше, чем я начинал.
Результирующий код показан ниже:
#define assert(expression) \
if (!(expression)) \
{ \
Serial.println(F(__FILE__)); \
Serial.println(__LINE__, DEC); \
Serial.flush(); \
abort(); \
}
О классе
- в данном случае он использовался как старая форма пространств имен (поскольку пространства имен не существовали в С++ до 1990 года). Однако чаще использовалась структура, так как ей не нужен спецификатор public:
., @KIIV
- Загрузка Arduino Nano дает ошибку: avrdude: stk500_recv(): programmer is not responding
- Какие накладные расходы и другие соображения существуют при использовании структуры по сравнению с классом?
- Ошибка "'Serial' does not name a type"
- В чем разница между библиотеками Software Serial? Какая из них совместима с Arduino Nano?
- Как отправить команду AT на sim800l с помощью SoftwareSerial
- как быстро loop() работает в Arduino
- Построение графика на Python с использованием Tkinter Canvas
- Команда strtok() с Serial связью
ошибка сегментации — это ошибка компилятора в версиях 1.6.22 и 1.6.23. подробнее здесь https://forum.arduino.cc/index.php?topic=619213.msg4195749#msg4195749, @Juraj
попробуйте
F(__FILE__)
иF(__func__)
. (измените тип параметра на __FlashStringHelper), @Juraj@Juraj Каким-то образом это работает только для
__FILE__
, но не для__func__
. В любом случае, используяF( __FILE__)
была разница около -90B (вероятно, это полный путь, и он использовался только в одном файле)., @KIIVпоэтому компилятор оптимизирует параметры, если они не используются, @Juraj
Зачем вы тратите на это класс? Просто используйте отпечатки прямо в макросе., @Majenko
@juraj Спасибо (см. ответ, но не стесняйтесь добавлять свои собственные, если хотите, чтобы я проголосовал), @Michel Keijzers
@KIIV Спасибо (см. ответ, но не стесняйтесь добавлять свои собственные, если хотите, чтобы я проголосовал), @Michel Keijzers
@Majenko Спасибо (см. ответ, но не стесняйтесь добавлять свои собственные, если хотите, чтобы я проголосовал), @Michel Keijzers