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

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

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

, 👍3


1 ответ


Лучший ответ:

5

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

Перейдите к C:\Users \<Имя пользователя>\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 требует около 40k дополнительной флэш-памяти. Учитывая, что он имеет 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());
  }
}

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

,

Интересно. Я наполовину ожидал, что вам также придется создавать все процедуры "личности"., @timemage

@timemage Я тоже. До сих пор я тестировал его только на небольшом примере, но буду использовать его в более крупной кодовой базе, а затем посмотрю, действительно ли он работает так, как ожидалось. Проект действительно становится настолько большим, что использование кодов возврата повсюду больше не является вариантом., @PMF