Como habilitar o tratamento de exceções no Arduino Due?
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
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.12
e crie um novo arquivo platform.local.txt
com 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.