Cho biết nếu ngắt được kích hoạt


7

Có cách nào để nói nếu sei()/ interrupts()hoặc cli()/ noInterrupts()được gọi lần cuối không?

Tôi cần điều này để có thể kích hoạt các ngắt, thực thi một số mã và đặt các ngắt vô hiệu hóa các ngắt nếu chúng bị vô hiệu hóa.

Đây là một số mã mẫu:

void function_requiring_interrupts(void) {
    bool interruptsEnabled = getInterrupsState(); // what function / variable here?

    interrupts();

    // Code requiring interrups are enabled

    if(!interruptsEnabled) {
        noInterrupts();
    }
}

Câu trả lời:


9

Một cách để làm điều này là lưu, và sau đó khôi phục thanh ghi trạng thái SREG, do đó lưu và sau đó khôi phục trạng thái ngắt thành bất cứ thứ gì, do đó:

  uint8_t oldSREG = SREG; // Save the status
  cli();

  // Do stuff, as little as possible.

  SREG = oldSREG;

Ngoài ra, lý do được mô tả trong câu hỏi có vấn đề cố hữu: Nếu một số mã khác đã bị ngắt và mã của bạn cho phép bị gián đoạn, hỏng dữ liệu hoặc lỗi chương trình có thể xảy ra. Bất kỳ khối mã "bị gián đoạn" nào cũng sẽ mong muốn tất cả các thanh ghi và bộ nhớ / biến vẫn không được làm sáng tỏ, trong khi việc kích hoạt các ngắt có thể khiến điều đó thay đổi.

Do đó, logic ngược lại, như trong đoạn mã ở trên, là cách tốt nhất: Hoàn toàn vô hiệu hóa các ngắt cho mã của riêng bạn khi cần, nhưng khôi phục các ngắt càng sớm càng tốt, sau đó tiến hành phần còn lại của quá trình xử lý của bạn.


Anindo nói đúng về cảnh báo. Bạn không bao giờ nên kích hoạt các ngắt trong thư viện hoặc cuộc gọi khác không được thiết kế riêng để thực hiện điều đó. Mã bị gián đoạn đã làm như vậy vì một lý do và cho phép các ngắt trong thói quen thư viện của bạn có thể gây ra tất cả các loại tàn phá với mã khác.

Sẽ có vấn đề nếu một ngắt xảy ra sau khi lưu thanh ghi trạng thái, nhưng trước khi vô hiệu hóa các ngắt?
Người chăn cừu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.