Các đoạn mã sau đây là từ mã nguồn thư viện TimerOne :
// TimerOne.h:
void (*isrCallback)();
// TimerOne.cpp:
ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
Timer1.isrCallback();
}
// TimerOne.cpp:
void TimerOne::attachInterrupt(void (*isr)(), long microseconds)
{
if(microseconds > 0) setPeriod(microseconds);
isrCallback = isr; // register the user's callback with the real ISR
TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
resume();
}
Câu hỏi: nếu bộ định thời gian đang chạy và chương trình chính gọi attachInterrupt()
, bộ ngắt thời gian có thể xảy ra ở đó trong quá trình gán con trỏ hàm isrCallback = isr;
không? Sau đó, với thời gian may mắn, Timer1.isrCallback();
con trỏ hàm sẽ bao gồm một phần của địa chỉ cũ và một phần của địa chỉ mới, khiến ISR nhảy đến một vị trí không có thật?
Tôi cho rằng đây có thể là trường hợp, vì các con trỏ hàm chắc chắn rộng hơn 1 byte và truy cập dữ liệu> 1 byte không phải là nguyên tử. Cách giải quyết có thể là:
- Luôn gọi
detachInterrupt()
để đảm bảo bộ định thời không chạy, trước khi gọiattachInterrupt()
, tức là làm rõ các tài liệu Timer1. - Hoặc, sửa đổi Timer1, vô hiệu hóa tạm thời ngắt tràn bộ đếm thời gian
isrCallback = isr;
Điều này có ý nghĩa không, hoặc có một cái gì đó trong Timer1
các nguồn hoặc các bài tập con trỏ hàm mà tôi đã bỏ lỡ?