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