Là dễ bay hơi khi biến được truy cập từ> 1 ISR, nhưng không được chia sẻ bên ngoài ISR?


9

ghi rõ ràng rằng khi dữ liệu toàn cầu được chia sẻ với một ISR và chương trình chính, nhu cầu dữ liệu được khai báo volatileđể tầm nhìn bộ nhớ bảo lãnh (và đó chỉ đủ cho dữ liệu 1 byte; bất cứ điều gì nhu cầu lớn hơn sắp xếp đặc biệt để đảm bảo cũng nguyên tố) . Ở đây chúng tôi có các quy tắc tốt:

  • Các biến chỉ được sử dụng bên ngoài ISR ​​sẽ không biến động.
  • Các biến chỉ được sử dụng bên trong ISR sẽ không biến động.
  • Các biến được sử dụng cả bên trong và bên ngoài ISR ​​sẽ không ổn định.

Nhưng có volatilecần thiết khi biến được truy cập từ> 1 ISR, nhưng không được chia sẻ bên ngoài ISR ​​không? Ví dụ: tôi có một hàm duy trì trạng thái bên trong bằng cách sử dụng một staticbiến:

void func() {
    static volatile long counter; // volatile or not?
    // Do stuff with counter etc.
}

Hàm đó được gọi theo hai cách: từ ngắt pin và từ thư viện TimerOne :

  1. attachInterrupt(0, func, CHANGE);
  2. Timer1.attachInterrupt(func);

Không có vấn đề về nguyên tử, vì khi nhập ISR, các ngắt sẽ tự động bị vô hiệu hóa , nhưng đây volatilelà câu hỏi của trình biên dịch: cái gì được lưu trữ và cái gì không.

An toàn tốt hơn xin lỗi, tất nhiên ...

Câu trả lời:


9

volatile chỉ thông báo cho trình tạo mã của trình biên dịch rằng biến có thể được sửa đổi bởi một thứ khác ngoài mã được tạo, do đó không cho rằng bất kỳ bản sao nào của nó vẫn chính xác.

Mã ISR phải được viết / tạo theo giả định rằng nó không có ngữ cảnh khi vào và bảo toàn bối cảnh của CPU xung quanh hoạt động của chính nó (ISR). Vì vậy, như với tính không thể tách rời của các hoạt động phi nguyên tử, tính biến động phụ thuộc, trong trường hợp này * , vào việc các ngắt có được phép lồng hay không. Nếu không lồng nhau được đảm bảo, biến chia sẻ không thể thay đổi khác với ISR ​​này trong quá trình thực thi của chính nó. Nếu ISR của bạn một ngày nào đó có thể được sử dụng trong môi trường mà các ngắt được phép lồng, thì ràng buộc đó sẽ không còn được giữ nữa.

* trong trường hợp này :
Tôi giả sử một biến được duy trì bằng phần mềm ở đây. Nếu chúng ta đang nói về một biến có thể được cập nhật bởi một sự kiện phần cứng, chẳng hạn như một thanh ghi hẹn giờ, tất cả các cược đều bị tắt: biến đó không ổn định cho dù thế nào đi chăng nữa.


Vì vậy, miễn là tôi không thay đổi hành vi "ngắt không lồng" mặc định của Arduino, thì biến không cần phải có volatile, vì nó không bị sửa đổi bởi bất kỳ thứ gì ngoài mã được tạo; trình biên dịch có thể "giả sử" rằng ISR thực thi tuyến tính, và nó, miễn là các ngắt không làm tổ. Điều đó có ý nghĩa. Cảm ơn!
Joonas Pulakka
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.