First, we must make sure the "-fno-exceptions" compiler flag is overwritten with "-fexceptions". In addition, we must link a separate library that includes the compiler support functions for stack unwinding.
Navigate to C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12
and create a new file platform.local.txt
with this content:
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}
The last line should match the corresponding line in platform.txt
, with an extra {linker.elf.extralibs}
at the end (upgrading the toolkit might update that line, so you may need to compare the other parameters).
These lines add the -fexceptions
to the compiler command line and the supc++
library to the linker input (otherwise you'll get errors about unresolved externals). After these changes, you can rebuild your project and use exception handling.
Some usage hints
The exception support on the Due requires about 40k of extra flash memory. Given it has 512k, this is usually acceptable. A bit of extra RAM is also used, but that seems to be small enough as well.
Since there are no standard exception classes defined (and the ArduinoSTL library doesn't compile on the due out-of-the-box), you'll have to write your own exception classes, i.e something like this:
class Exception
{
private:
const char* _msg;
public:
Exception(const char* msg)
{
_msg = msg;
}
const char* Message() const
{
return _msg;
}
};
Use as:
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());
}
}
Note that Unhandled exceptions will terminate the program. An unhandled exception will cause the due to output a corresponding message to the serial console and then enter a deadend fail state.