Как включить обработку исключений на Arduino Due?

Jan 07 2021

Хотя вопрос здесь дает некоторые подсказки, предоставленное там решение не работает напрямую с Due, поскольку оно использует другой компилятор и инструментарий. Кроме того, у Due более чем достаточно флэш-памяти для большинства проектов, так что дополнительный код, необходимый для обработки исключений, является приемлемым. Но, как и в случае с платами на базе AVR, «-fno-exceptions» автоматически добавляется к флагам компилятора при использовании Arduino IDE, предотвращая компиляцию любых команд throw или catch.

Как я могу включить поддержку исключений в срок?

Ответы

5 PMF Jan 07 2021 at 15:04

Во-первых, мы должны убедиться, что флаг компилятора «-fno-exceptions» перезаписан на «-fexceptions». Кроме того, мы должны подключить отдельную библиотеку, которая включает функции поддержки компилятора для раскрутки стека.

Найдите C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12и создайте новый файл platform.local.txtс этим содержимым:


compiler.cpp.extra_flags=-fexceptions
linker.elf.extralibs=-lsupc++

recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" -mcpu={build.mcu} -mthumb {compiler.c.elf.flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group {compiler.combine.flags} {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -lm -lgcc {linker.elf.extralibs}

Последняя строка должна совпадать с соответствующей строкой platform.txtс добавлением {linker.elf.extralibs}в конце (обновление инструментария может обновить эту строку, поэтому вам может потребоваться сравнить другие параметры).

Эти строки добавляют -fexceptionsк командной строке компилятора и supc++библиотеке к вводу компоновщика (в противном случае вы получите ошибки о неразрешенных внешних факторах). После этих изменений вы можете перестроить свой проект и использовать обработку исключений.

Некоторые подсказки по использованию

Для поддержки исключений на Due требуется около 40 КБ дополнительной флэш-памяти. Учитывая, что у него 512k, это обычно приемлемо. Также используется немного дополнительной оперативной памяти, но она тоже кажется достаточно маленькой.

Поскольку не определены стандартные классы исключений (а библиотека ArduinoSTL не компилируется в установленном порядке), вам придется написать свои собственные классы исключений, то есть что-то вроде этого:

class Exception
{
  private:
  const char* _msg;
  public:
  Exception(const char* msg)
  {
    _msg = msg;
  }

  const char* Message() const
  {
    return _msg;
  }
};

Использовать как:


void ThrowExceptionFunc()
{
  throw Exception("Something bad happened");
}

void ValidateExceptionHandling()
{
  try
  {
    ThrowExceptionFunc();
    Serial.print("Exception was not thrown:");
  }
  catch(Exception& ex)
  {
    Serial.print("Exception happened:");
    Serial.println(ex.Message());
  }
}

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