จะเปิดใช้งานการจัดการข้อยกเว้นบน Arduino Due ได้อย่างไร

Jan 07 2021

แม้ว่าคำถามในที่นี้จะให้คำแนะนำบางประการ แต่วิธีแก้ปัญหาที่มีให้นั้นไม่สามารถใช้งานได้โดยตรงกับ Due เนื่องจากใช้คอมไพเลอร์และชุดเครื่องมือที่แตกต่างกัน นอกจากนี้ Due ยังมีแฟลชมากเกินพอสำหรับโปรเจ็กต์ส่วนใหญ่ดังนั้นจึงยอมรับรหัสพิเศษที่จำเป็นสำหรับการจัดการข้อยกเว้นได้ แต่เช่นเดียวกับบอร์ดที่ใช้ AVR "-fno-exceptions" จะถูกเพิ่มลงในแฟล็กคอมไพเลอร์โดยอัตโนมัติเมื่อใช้ Arduino IDE เพื่อป้องกันไม่ให้คำสั่งโยนหรือจับเพื่อคอมไพล์

ฉันจะเปิดใช้งานการสนับสนุนข้อยกเว้นในวันครบกำหนดได้อย่างไร

คำตอบ

5 PMF Jan 07 2021 at 15:04

อันดับแรกเราต้องตรวจสอบให้แน่ใจว่าแฟล็กคอมไพเลอร์ "-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++ไลบรารีไปยังอินพุตตัวเชื่อมโยง (มิฉะนั้นคุณจะได้รับข้อผิดพลาดเกี่ยวกับภายนอกที่ไม่ได้รับการแก้ไข) หลังจากการเปลี่ยนแปลงเหล่านี้คุณสามารถสร้างโครงการของคุณใหม่และใช้การจัดการข้อยกเว้น

คำแนะนำการใช้งานบางอย่าง

การสนับสนุนข้อยกเว้นในวันครบกำหนดต้องใช้หน่วยความจำแฟลชเพิ่มเติมประมาณ 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());
  }
}

โปรดทราบว่าข้อยกเว้นที่ไม่มีการจัดการจะยกเลิกโปรแกรม ข้อยกเว้นที่ไม่สามารถจัดการได้จะทำให้เกิดการส่งออกข้อความที่เกี่ยวข้องไปยังคอนโซลอนุกรมจากนั้นจึงเข้าสู่สถานะความล้มเหลวของการหยุดชะงัก