Como habilitar o tratamento de exceções no Arduino Due?

Jan 07 2021

Embora a questão aqui dê algumas dicas, a solução fornecida não funciona diretamente no Devido, uma vez que usa um compilador e um kit de ferramentas diferentes. Além disso, o Due tem flash mais do que suficiente para a maioria dos projetos, de modo que o código extra necessário para o tratamento de exceções é aceitável. Mas, como acontece com as placas baseadas em AVR, "-fno-exceptions" é adicionado automaticamente aos sinalizadores do compilador ao usar o IDE do Arduino, evitando qualquer instrução de lançamento ou captura para compilar.

Como posso ativar o suporte a exceções no vencimento?

Respostas

5 PMF Jan 07 2021 at 15:04

Primeiro, devemos nos certificar de que o sinalizador do compilador "-fno-exceptions" seja sobrescrito por "-fexceptions". Além disso, devemos vincular uma biblioteca separada que inclui as funções de suporte do compilador para o desenrolamento da pilha.

Navegue C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12e crie um novo arquivo platform.local.txtcom este conteúdo:


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}

A última linha deve corresponder à linha correspondente platform.txt, com um extra {linker.elf.extralibs}no final (atualizar o kit de ferramentas pode atualizar essa linha, portanto, pode ser necessário comparar os outros parâmetros).

Essas linhas adicionam o -fexceptionsà linha de comando do compilador e a supc++biblioteca à entrada do vinculador (caso contrário, você obterá erros sobre itens externos não resolvidos). Após essas alterações, você pode reconstruir seu projeto e usar o tratamento de exceções.

Algumas dicas de uso

O suporte de exceção no Due requer cerca de 40k de memória flash extra. Dado que tem 512k, isso geralmente é aceitável. Um pouco de RAM extra também é usado, mas também parece ser pequeno o suficiente.

Uma vez que não há classes de exceção padrão definidas (e a biblioteca ArduinoSTL não compila no devido momento), você terá que escrever suas próprias classes de exceção, ou seja, algo assim:

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

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

Use como:


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());
  }
}

Observe que as exceções não tratadas encerrarão o programa . Uma exceção não tratada fará com que o due produza uma mensagem correspondente para o console serial e entre em um estado de falha sem saída.