Làm thế nào để kích hoạt xử lý ngoại lệ trên Arduino Do?

Jan 07 2021

Mặc dù câu hỏi ở đây đưa ra một số gợi ý, nhưng giải pháp được cung cấp ở đó không trực tiếp hoạt động trên Đến hạn, vì nó sử dụng một trình biên dịch và bộ công cụ khác. Ngoài ra, Due có quá đủ flash cho hầu hết các dự án, do đó mã bổ sung cần thiết để xử lý ngoại lệ có thể chấp nhận được. Nhưng cũng như với các bo mạch dựa trên AVR, "-fno-exceptions" được tự động thêm vào các cờ trình biên dịch khi sử dụng Arduino IDE, ngăn chặn bất kỳ lệnh ném hoặc bắt nào để biên dịch.

Làm cách nào để kích hoạt hỗ trợ ngoại lệ khi Đến hạn?

Trả lời

5 PMF Jan 07 2021 at 15:04

Đầu tiên, chúng ta phải đảm bảo rằng cờ trình biên dịch "-fno-exceptions" được ghi đè bằng "-fexceptions". Ngoài ra, chúng ta phải liên kết một thư viện riêng biệt bao gồm các chức năng hỗ trợ trình biên dịch để giải nén ngăn xếp.

Điều hướng đến C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12và tạo một tệp mới platform.local.txtvới nội dung này:


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}

Dòng cuối cùng phải phù hợp với dòng tương ứng trong platform.txt, với thêm {linker.elf.extralibs}vào cuối (nâng cấp bộ công cụ có thể cập nhật dòng đó, vì vậy bạn có thể cần phải so sánh các thông số khác).

Các dòng này thêm -fexceptionsvào dòng lệnh của trình biên dịch và supc++thư viện vào đầu vào của trình liên kết (nếu không bạn sẽ gặp lỗi về các phần tử bên ngoài chưa được giải quyết). Sau những thay đổi này, bạn có thể xây dựng lại dự án của mình và sử dụng xử lý ngoại lệ.

Một số gợi ý sử dụng

Hỗ trợ ngoại lệ vào thời hạn yêu cầu khoảng 40k bộ nhớ flash bổ sung. Vì nó có 512k, điều này thường có thể chấp nhận được. Một chút RAM bổ sung cũng được sử dụng, nhưng điều đó dường như cũng đủ nhỏ.

Vì không có lớp ngoại lệ tiêu chuẩn nào được xác định (và thư viện ArduinoSTL không biên dịch khi xuất xưởng), bạn sẽ phải viết các lớp ngoại lệ của riêng mình, tức là một cái gì đó như sau:

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

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

Sử dụng như là:


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

Lưu ý rằng các ngoại lệ chưa được xử lý sẽ chấm dứt chương trình . Một ngoại lệ không được xử lý sẽ gây ra do xuất một thông báo tương ứng đến bảng điều khiển nối tiếp và sau đó chuyển sang trạng thái không hủy bỏ.