Poniższe fragmenty kodu źródłowego biblioteki 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();
}
Pytanie: jeśli minutnik już działa, a główny program wywołuje attachInterrupt()
, czy przerwanie czasomierza może nastąpić podczas przypisywania wskaźnika funkcji isrCallback = isr;
? Czy przy szczęśliwym czasie Timer1.isrCallback();
wskaźnik funkcji składałby się częściowo ze starego, a częściowo z nowego adresu, powodując skok ISR do fałszywej lokalizacji?
Myślę, że może tak być, ponieważ wskaźniki funkcji są z pewnością szersze niż 1 bajt, a dostęp do danych> 1 bajtowych nie jest atomowy. Możliwe obejścia to:
- Zawsze zadzwoń,
detachInterrupt()
aby upewnić się, że stoper nie jest uruchomiony, zanim zadzwoniszattachInterrupt()
, tj. Wyjaśnij dokumenty Timera 1. - Lub zmodyfikuj Timer1, wyłączając tymczasowo przepełnienie timera
isrCallback = isr;
Czy to ma sens, czy jest coś Timer1
, co brakowało w przypisaniach do źródeł lub wskaźników funkcji?
Wygląda na to, że masz rację. Logiczną rzeczą byłoby wyłączenie przerwań w taki sposób, abyś nie włączał ich ponownie, gdyby były one w pierwszej kolejności wyłączone. Na przykład:
Ma to na celu umożliwienie pisania takiego kodu:
Bez tego przepisu możesz mieć przerwę między tymi dwiema liniami, a zatem spać w nieskończoność (ponieważ przerwanie, które miało cię obudzić, nastąpiło przed zaśnięciem ). Zapewnienie w procesorze, że następna instrukcja po przerwie staje się włączona, jeśli wcześniej nie były włączone, jest zawsze wykonywana, chroni przed tym.
źródło
TIMSK1=0; TIFR1=_BV(TOV1); isrCallback=isr; TIMSK1=_BV(TOIE1);
? Oszczędza jeden rejestr procesora i nie przyczynia się do opóźnienia.