W projekcie założyłem sobie dwa przerwania z dwóch timerów. Jedno (nazwijmy je A) wywoływane często i krytyczne czasowo (przerwanie musi być obsłużone jak najszybciej po jego pojawieniu się), trwające tylko kilkanaście cykli. Drugie (B) mniej krytyczne (właściwie w ogóle nie krytyczne), wołane rzadziej, trwające kilkaset cykli. Główna pętla programu będzie zawierała jedynie sleepa, całość ma się dziać w przerwaniach.
Ogólnie A obsługuje odbiór transmisji asynchronicznej (z odbiornika podczerwieni) a B całą resztę. Przerwanie A to tak naprawdę dwa przerwania - najpierw PCINT a potem output compare z timera (będzie pracował w CTC), ale konstrukcja programu sprawi że albo będzie wołany PCINT (początek transmisji - inicjalizacja timera, wyłączenie siebie) albo timer (podczas samej transmisji - po jej zakończeniu wyłączenie timera i włączenie PCINT-a), więc dla uproszczenia nazwałem je jednym przerwaniem.
Czyli w skrócie - przerwanie A ma mieć priorytet nad przerwaniem B. Nie dosłownie (dwa przerwania w jednym cyklu), bo dosłownie to priorytety w AVR maleją wraz ze wzrostem adresu w tablicy wektorów, ale ma się móc w każdej chwili wciąć w trwającą obsługę B, a w odwrotnej sytuacji (trwa A, pojawia się B) to B ma grzecznie poczekać na zakończenie A (z tego co wiem to właśnie tak działają przerwania w AVR - są opóźniane).
Wymyśliłem żeby obsługiwać przerwanie A normalnie - z wyłączonymi innymi przerwaniami (tak żeby B nie mogło przeszkodzić), a B z włączonymi (instrukcja SEI na początku ISR, avr-libc to załatwia). To ma sens i zadziała tak jak tego chcę? Mógłbym sam sprawdzić i nie zawracać wam głowy, ale akurat race conditions są dosyć trudne do wytropienia a działać może, bo sygnał chcę samplować w środku trwania bodu, więc jak się trochę przesunie, to zazwyczaj zadziała... Ale ma działać zawsze a nie tylko zazwyczaj.
Alternatywnie myślałem nad przeniesieniem obsługi B do głównej pętli - tak żeby B tylko ustawiało flagę, ale to rodzi inne problemy (race condition między sprawdzeniem flagi a sleepem), chciałbym ich uniknąć.
Co myślicie?
Ogólnie A obsługuje odbiór transmisji asynchronicznej (z odbiornika podczerwieni) a B całą resztę. Przerwanie A to tak naprawdę dwa przerwania - najpierw PCINT a potem output compare z timera (będzie pracował w CTC), ale konstrukcja programu sprawi że albo będzie wołany PCINT (początek transmisji - inicjalizacja timera, wyłączenie siebie) albo timer (podczas samej transmisji - po jej zakończeniu wyłączenie timera i włączenie PCINT-a), więc dla uproszczenia nazwałem je jednym przerwaniem.
Czyli w skrócie - przerwanie A ma mieć priorytet nad przerwaniem B. Nie dosłownie (dwa przerwania w jednym cyklu), bo dosłownie to priorytety w AVR maleją wraz ze wzrostem adresu w tablicy wektorów, ale ma się móc w każdej chwili wciąć w trwającą obsługę B, a w odwrotnej sytuacji (trwa A, pojawia się B) to B ma grzecznie poczekać na zakończenie A (z tego co wiem to właśnie tak działają przerwania w AVR - są opóźniane).
Wymyśliłem żeby obsługiwać przerwanie A normalnie - z wyłączonymi innymi przerwaniami (tak żeby B nie mogło przeszkodzić), a B z włączonymi (instrukcja SEI na początku ISR, avr-libc to załatwia). To ma sens i zadziała tak jak tego chcę? Mógłbym sam sprawdzić i nie zawracać wam głowy, ale akurat race conditions są dosyć trudne do wytropienia a działać może, bo sygnał chcę samplować w środku trwania bodu, więc jak się trochę przesunie, to zazwyczaj zadziała... Ale ma działać zawsze a nie tylko zazwyczaj.
Alternatywnie myślałem nad przeniesieniem obsługi B do głównej pętli - tak żeby B tylko ustawiało flagę, ale to rodzi inne problemy (race condition między sprawdzeniem flagi a sleepem), chciałbym ich uniknąć.
Co myślicie?