Nó 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ó volatile
cầ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 static
biế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 :
attachInterrupt(0, func, CHANGE);
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 volatile
là 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 ...
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!