Bagaimana cara mengaktifkan penanganan pengecualian pada Arduino Due?

Jan 07 2021

Sementara pertanyaan di sini memberikan beberapa petunjuk, solusi yang disediakan di sana tidak langsung bekerja pada Due, karena ia menggunakan compiler dan toolkit yang berbeda. Selain itu, Due memiliki flash lebih dari cukup untuk sebagian besar project, sehingga kode tambahan yang diperlukan untuk penanganan exception dapat diterima. Tetapi seperti halnya papan berbasis AVR, "-fno-exception" secara otomatis ditambahkan ke flag compiler ketika menggunakan Arduino IDE, mencegah instruksi throw atau catch untuk dikompilasi.

Bagaimana saya dapat mengaktifkan dukungan pengecualian pada Jatuh Tempo?

Jawaban

5 PMF Jan 07 2021 at 15:04

Pertama, kita harus memastikan flag compiler "-fno-exception" ditimpa dengan "-fexceptions". Selain itu, kita harus menautkan pustaka terpisah yang menyertakan fungsi dukungan kompilator untuk pelepasan tumpukan.

Arahkan ke C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12dan buat file baru platform.local.txtdengan konten ini:


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}

Baris terakhir harus cocok dengan baris yang sesuai di platform.txt, dengan tambahan {linker.elf.extralibs}di akhir (meningkatkan toolkit mungkin memperbarui baris itu, jadi Anda mungkin perlu membandingkan parameter lain).

Baris-baris ini menambahkan baris -fexceptionsperintah kompilator dan supc++pustaka ke input linker (jika tidak, Anda akan mendapatkan kesalahan tentang eksternal yang belum terselesaikan). Setelah perubahan ini, Anda dapat membangun kembali proyek Anda dan menggunakan penanganan pengecualian.

Beberapa petunjuk penggunaan

Dukungan pengecualian pada Due membutuhkan sekitar 40k memori flash tambahan. Mengingat memiliki 512k, ini biasanya dapat diterima. Sedikit RAM ekstra juga digunakan, tapi tampaknya itu cukup kecil juga.

Karena tidak ada kelas pengecualian standar yang ditentukan (dan pustaka ArduinoSTL tidak dikompilasi pada saat keluar-of-the-box), Anda harus menulis kelas pengecualian Anda sendiri, yaitu sesuatu seperti ini:

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

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

Digunakan sebagai:


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

Perhatikan bahwa pengecualian tidak tertangani akan menghentikan program . Pengecualian yang tidak tertangani akan menyebabkan karena mengeluarkan pesan yang sesuai ke konsol serial dan kemudian memasuki keadaan gagal yang buntu.