Arduino Dueで例外処理を有効にするにはどうすればよいですか?
ここでの質問はいくつかのヒントを与えますが、そこで提供されるソリューションは、異なるコンパイラーとツールキットを使用するため、Dueでは直接機能しません。また、Dueにはほとんどのプロジェクトに十分なフラッシュがあるため、例外処理に必要な追加のコードは受け入れられます。ただし、AVRベースのボードと同様に、Arduino IDEを使用すると、コンパイラフラグに「-fno-exceptions」が自動的に追加され、コンパイルするスロー命令またはキャッチ命令が防止されます。
Dueで例外サポートを有効にするにはどうすればよいですか?
回答
まず、「-fno-exceptions」コンパイラフラグが「-fexceptions」で上書きされていることを確認する必要があります。さらに、スタック巻き戻し用のコンパイラサポート関数を含む別のライブラリをリンクする必要があります。
移動するC:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12
と、新しいファイルの作成platform.local.txt
このコンテンツでは:
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}
最後の行は、の対応する行と一致し、最後にplatform.txt
余分な{linker.elf.extralibs}
行が必要です(ツールキットをアップグレードすると、その行が更新される可能性があるため、他のパラメーターを比較する必要がある場合があります)。
これらの行は-fexceptions
、コンパイラのコマンドラインにsupc++
ライブラリを追加し、リンカの入力にライブラリを追加します(そうしないと、未解決の外部に関するエラーが発生します)。これらの変更後、プロジェクトを再構築して例外処理を使用できます。
いくつかの使用上のヒント
Dueの例外サポートには、約40kの追加フラッシュメモリが必要です。512kがあることを考えると、これは通常許容できます。少し余分なRAMも使用されますが、それも十分に小さいようです。
標準の例外クラスが定義されていないため(ArduinoSTLライブラリはすぐにコンパイルされないため)、独自の例外クラスを作成する必要があります。つまり、次のようになります。
class Exception
{
private:
const char* _msg;
public:
Exception(const char* msg)
{
_msg = msg;
}
const char* Message() const
{
return _msg;
}
};
使用:
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());
}
}
未処理の例外はプログラムを終了することに注意してください。未処理の例外が原因で、対応するメッセージがシリアルコンソールに出力され、行き止まりの失敗状態になります。