Come abilitare la gestione delle eccezioni su Arduino Due?

Jan 07 2021

Mentre la domanda qui fornisce alcuni suggerimenti, la soluzione fornita non funziona direttamente sul Due, poiché utilizza un compilatore e un toolkit diversi. Inoltre, il Due ha un flash più che sufficiente per la maggior parte dei progetti, quindi il codice aggiuntivo richiesto per la gestione delle eccezioni è accettabile. Ma come con le schede basate su AVR, "-fno-exceptions" viene automaticamente aggiunto ai flag del compilatore quando si utilizza l'IDE di Arduino, impedendo qualsiasi istruzione di lancio o cattura per la compilazione.

Come posso abilitare il supporto delle eccezioni sul Due?

Risposte

5 PMF Jan 07 2021 at 15:04

Per prima cosa, dobbiamo assicurarci che il flag del compilatore "-fno-exceptions" sia sovrascritto con "-fexceptions". Inoltre, dobbiamo collegare una libreria separata che includa le funzioni di supporto del compilatore per lo svolgimento dello stack.

Individua C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12e crea un nuovo file platform.local.txtcon questo contenuto:


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}

L'ultima riga dovrebbe corrispondere alla riga corrispondente in platform.txt, con un extra {linker.elf.extralibs}alla fine (l'aggiornamento del toolkit potrebbe aggiornare quella riga, quindi potrebbe essere necessario confrontare gli altri parametri).

Queste righe aggiungono il -fexceptionsalla riga di comando del compilatore e la supc++libreria all'input del linker (altrimenti otterrai errori sugli esterni non risolti). Dopo queste modifiche, è possibile ricostruire il progetto e utilizzare la gestione delle eccezioni.

Alcuni suggerimenti per l'utilizzo

Il supporto delle eccezioni su Due richiede circa 40k di memoria flash aggiuntiva. Dato che ha 512k, questo è generalmente accettabile. Viene utilizzata anche un po 'di RAM extra, ma anche quella sembra essere abbastanza piccola.

Poiché non sono definite classi di eccezione standard (e la libreria ArduinoSTL non si compila sul dovuto), dovrai scrivere le tue classi di eccezione, ovvero qualcosa del genere:

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

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

Usare come:


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

Notare che le eccezioni non gestite terminano il programma . Un'eccezione non gestita farà sì che la causa emetta un messaggio corrispondente alla console seriale e quindi entri in uno stato di errore deadend.