Comment activer la gestion des exceptions sur l'Arduino Due?

Jan 07 2021

Bien que la question ici donne quelques indices, la solution qui y est fournie ne fonctionne pas directement sur le Due, car elle utilise un compilateur et une boîte à outils différents. En outre, le Due a plus que suffisamment de flash pour la plupart des projets, de sorte que le code supplémentaire requis pour la gestion des exceptions est acceptable. Mais comme avec les cartes basées sur AVR, "-fno-exceptions" est automatiquement ajouté aux drapeaux du compilateur lors de l'utilisation de l'IDE Arduino, empêchant toute instruction throw ou catch à compiler.

Comment puis-je activer la prise en charge des exceptions sur l'échéance?

Réponses

5 PMF Jan 07 2021 at 15:04

Tout d'abord, nous devons nous assurer que l'indicateur du compilateur "-fno-exceptions" est écrasé par "-fexceptions". De plus, nous devons lier une bibliothèque distincte qui inclut les fonctions de support du compilateur pour le déroulement de la pile.

Accédez à C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12et créez un nouveau fichier platform.local.txtavec ce contenu:


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 dernière ligne doit correspondre à la ligne correspondante platform.txt, avec un supplément {linker.elf.extralibs}à la fin (la mise à niveau de la boîte à outils peut mettre à jour cette ligne, vous devrez peut-être comparer les autres paramètres).

Ces lignes ajoutent le -fexceptionsà la ligne de commande du compilateur et la supc++bibliothèque à l'entrée de l'éditeur de liens (sinon, vous obtiendrez des erreurs sur les externes non résolus). Après ces modifications, vous pouvez reconstruire votre projet et utiliser la gestion des exceptions.

Quelques conseils d'utilisation

La prise en charge des exceptions sur le Due nécessite environ 40k de mémoire flash supplémentaire. Étant donné qu'il a 512k, c'est généralement acceptable. Un peu de RAM supplémentaire est également utilisée, mais cela semble également assez petit.

Puisqu'il n'y a pas de classes d'exceptions standard définies (et que la bibliothèque ArduinoSTL ne se compile pas à la sortie de la boîte), vous devrez écrire vos propres classes d'exceptions, c'est-à-dire quelque chose comme ceci:

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

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

Utilisé comme:


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

Notez que les exceptions non gérées mettront fin au programme . Une exception non gérée entraînera le due à envoyer un message correspondant à la console série, puis à entrer dans un état d'échec impasse.