3

While the question here gives some hints, the solution provided there does not directly work on the Due, since it uses a different compiler and toolkit. Also, the Due has more than enough flash for most projects, so that the extra code required for exception handling is acceptable. But as with the AVR-based boards, "-fno-exceptions" is automatically added to the compiler flags when using the Arduino IDE, preventing any throw or catch instructions to compile.

How can I enable exception support on the Due?

5

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.

2
  • Interesting. I half-expected you'd have to create all of the "personality" routines also. – timemage Jan 7 at 13:43
  • @timemage Me too. I have only tested it with the small example so far, but will be using it in a larger code base and then see whether it really works as expected. The project is really getting so big that using return codes all over the place is no longer an option. – PMF Jan 7 at 13:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.