¿Cómo habilitar el manejo de excepciones en Arduino Due?

Jan 07 2021

Si bien la pregunta aquí da algunas sugerencias, la solución proporcionada allí no funciona directamente en Due, ya que utiliza un compilador y un kit de herramientas diferentes. Además, Due tiene flash más que suficiente para la mayoría de los proyectos, por lo que el código adicional requerido para el manejo de excepciones es aceptable. Pero al igual que con las placas basadas en AVR, "-fno-exceptions" se agrega automáticamente a las banderas del compilador cuando se usa el IDE de Arduino, evitando cualquier instrucción de lanzamiento o captura para compilar.

¿Cómo puedo habilitar el soporte de excepciones en el vencimiento?

Respuestas

5 PMF Jan 07 2021 at 15:04

Primero, debemos asegurarnos de que el indicador del compilador "-fno-exceptions" se sobrescriba con "-fexceptions". Además, debemos vincular una biblioteca separada que incluya las funciones de soporte del compilador para desenrollar la pila.

Navegue C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12y cree un nuevo archivo platform.local.txtcon este contenido:


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}

La última línea debe coincidir con la línea correspondiente platform.txt, con un extra {linker.elf.extralibs}al final (la actualización del kit de herramientas puede actualizar esa línea, por lo que es posible que deba comparar los otros parámetros).

Estas líneas agregan -fexceptionsa la línea de comando del compilador y la supc++biblioteca a la entrada del enlazador (de lo contrario, obtendrá errores sobre externos no resueltos). Después de estos cambios, puede reconstruir su proyecto y usar el manejo de excepciones.

Algunas sugerencias de uso

El soporte de excepciones en Due requiere alrededor de 40k de memoria flash adicional. Dado que tiene 512k, esto suele ser aceptable. También se usa un poco de RAM adicional, pero parece que también es lo suficientemente pequeña.

Dado que no hay clases de excepción estándar definidas (y la biblioteca ArduinoSTL no se compila en el debido de fábrica), tendrá que escribir sus propias clases de excepción, es decir, algo como esto:

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

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

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

Tenga en cuenta que las excepciones no controladas terminarán el programa . Una excepción no controlada hará que el debido envíe un mensaje correspondiente a la consola serial y luego ingrese a un estado de falla sin salida.