Przeglądając dokumentacje kompilatora AVR-GCC (i nie tylko) można natrafić na przykłady, w których tu i ówdzie występuje OPERACJA KRYTYCZNA, w czasie której nie może wystąpić przerwanie, więc sobie na chwilkę wyłączamy wszystkie przerwania. Dalej mamy tą OPERACJĘ KRYTYCZNĄ, (zazwyczaj kilka instrukcji maszynowych) i potem odblokowujemy przerwania. Przy tym wszystkim ani słowa o możliwości błędnego zadziałania systemu z powodu wyłączenia przerwań. A co jeśli wystąpi przerwanie wyzwalane zboczem z enkodera zamontowanego na silniku? Jestem przekonany, że stracimy informację o dokładnym położeniu silnika. We wszelkiej maści systemach czasu rzeczywistego dla AVR jest to wręcz na porządku dziennym. Strasznie denerwuje mnie, że to wyłączanie przerwań 'na chwilę' jest robione w przykładach bez słowa o konsekwencjach. A może ja czegoś nie wiem??? Proszę o komentarze. Pozdrawiam Wojtek
Wyłączanie przerwań 'na chwilę'
Oct 18, 2005
51 Replies
Tak, nie wiesz:) AVR "pamieta", ze bylo przerwanie i zaraz po odblokowaniu zostanie ono zgloszone. Oczywiscie jesli sekcja krytyczna trwa dluzej niz odstep pomiedzy kolejnymi przerwaniami TEGO SAMEGO TYPU to kolejne przerwania zostana zgubione.
Wylaczanie obslugi przerwan sie robi normalnie tylko w programie obslugi przerwan (samo sie robi) albo przy inicjacji systemu. Wszelkie inne zatrzymywanie rpzerwan jest potencjalnie niebezpieczne. A poza tym normalnie uklady z mikrokontrolerem powiny miec WatchDog jesli jest o cos wbudowane w procek to czasem unieszkodliwiasz i to tez. Jjesli zewnetrzny to ryzykujesz ze zadziala w nieodpowiednim momencie.
Wiem ze mimo to te rzeczy sie praktykuje powszechnie ale wiem ze rowniez powszechnie daje to fatalne rezultaty.
No niekoniecznie. Prosty przyklad - odczytujesz na 8-bitowcu zmienna wielobajtowa, ktorej zawartosc jest modyfikowana w procedurze obslugi przerwan. Jesli nie zablokujesz przerwan na czas odczytu calej zmiennej grozi ci, ze odczytasz smieci (jesli pomiedzy odczytami wystapilo przerwanie modyfikujace wartosc zmiennej). A to tylko pierwszy z brzegu przyklad.
Pytanie dotyczylo AVR, a ich watchdogowi nie szkodzi blokowanie przerwan (byloby to swoiste kuriozum). Zewnetrzne WD tez chyba bazuja na sygnale RESET, bo zglaszanie prockowi przerwania z sugestia "cos ci sie stary poknocilo, wiec sie zresetuj" byloby chyba nie na miejscu;P
Przyklad prosze?
Użytkownik Greg napisał:
Stek bzdur.
T.M.F. przemówił ludzkim głosem:
To ja dorzucę do tego przykładu jeszcze wszelkie operacje wykonywane na SFR 16-bitowych w AVR. Jeśli jakieś przerwanie także korzysta z SFR
16-bitowych , to istnieje spora szansa odczytania poza przerwaniem nie tej zawartości rejestru pośredniego, o którą nam chodziło :-)
O tylen wstrzymywanie przerwn nie jest konieczne ze normalnie program obslugi przerwan powinien ustawiac odpowiednie semafory kture tez sam potem sprawdza. Jak ma zapisywac ta liczbe to musi wiedziec ze w tym momencie nie jest ona czytana.
Mas racje to co napisalem o WD i przerwaniach mija sie z prawda. Rozpedzilem sie.
To widze ze nie uzywales takowego kolego. Jet odwrotnie. Procek musi periodycznie podac do WD sygnal, impuls ze ciagle jest zywy. Jak nie poda tego sygnalu przez sekunde to znaczy ze sie gdzies zapedzil w martwy punkt i nalezy go resetowac. Kawalek programu ktory daje kpniaga do WD powinien byc wsadzony w takim miejscu w programie przez kture musi przechodzic regularnie zazwyczaj w glownej petli (Main Loop) systemu. Ludzie robia blad wsadajac to w wielu miejscach Czasem to sie wydaje konieczne ale nie powinno miec miejsca. Wtedy pogram zapetlony jakiejs "bocznej petli" moze dawac sygnal ze jest w porzadku podczas gdy w rzeczywistosci nie jest.
Bardzo fajne sa ukladziki Dallas'a ktore maja w sobie uklad resetu przy zalaczniu, WD a takze rozpoznanie spadku zasilania i wtedy generuja przerwanie a pozniej reset.
Tu chodzi glownie o to ze pogram moze sie zapetlic i nie zreaktywowac przerwan. Wiem. Powiesz ze jak dobrze napisany to sie nie zapetli. Ale to nie zawsze ma miejsce (dobre napisanie) a poza tym program sie zapetla w z powodu zaklocen i to znacznie czesciej niz niektorzy mysla. Mam z tym troche praktyke i dlatego to mowie. Glownym jednak problemem jest wlasnie to ze najpierw sie mysli ze zatrzymuje przerwania na malenka chwilke a potem ktos inny modyfikuje program i ta chwilka sie robi troche wieksza. No i czasem dochodzi do problemu z przeoczonymi przerwaniami. Wiele programistow zaklada ze to tylko on bedzie tworzyl i modyfikowal program a czasem zreszta swidomi pisza tak zeby nikt tego nie mogl zrozumiec. Ale czesto jednak jest tak ze ktos inny to potem porawia i przerabia i wlasnie te zle obyczaje programistyczne i brak dyscypliny w strukturze programu przynosi fataln skutki. Po paru modyfikacjach program jest juz nie do naprawienia przez nikogo.
To mnij wiecej tyle co mi teraz przyszlo do glowy w tym temacie.
Pozdro grzechu
To sie nazywa rzeczowa dyskusja
Operacja odczytaj-zapisz semafor powinna być atomowa. Podobnie mutexu. Chyba nie da się jej na AVRach zrobić bez wyłaczania przerwań. A może się mylę ?
Na zakłucenia nic nie pomoże, czy wyłaczysz czy nie przerwania to przestawienie jednego bitu w pamięci może wywołać dowolne efekty. IMHO zastanawianie się co wtedy zrobić nie ma zupełnie sensu. Jesli nastapił błąd obliczeń procesora to nalezy do niego niedopuścić następnym razem i już.
Hmmm jedyne co mi przychodzi do głowy to stawiać instrukcjie CLI/SEI jak najbliżej siebie. Choć akurat grzebanie w sekcjach krytycznych nie powinno byc częste, prawda ? Jak dla mnie to nie jest argument.
Ale przeciez to jest bez sensu. Na 32-bitowym procku, przy dostepie do jakis poteznych struktur danych mozna sie bawic w semafory, ale nie na malym AVR, gdzie kazdy bajt jest cenny, szczegolnie przy odczycie zmiennej typu np. WORD. Zreszta w niektorych przypadkach (np. odczyt/zapis EEPROM) sama architektura AVR narzuca istnienie takich sekcji krytycznych.
No ok, ale co to zmienia? Istnienie sekcji programu, ktore wymagaja wylaczenia przerwan nic nie zmienia. Przeciez to nie sa sekcje, ktore wykonuja sie 1 sekunde, tylko kilkuinstrukcjowe fragmenty, jak wiec maja one wplynac na WD?
No ale jesli sie zapetli to WD go zresetuje, co to ma wspolnego z przerwaniami? Zreszta jesli sie zapetli to pewnie dlatego, ze poszedl w maliny, co ci wiec zagwarantuje, ze w miedzyczasie nie wykona jakiejs przypadkowej instrukcji CLI?
No ale to nie jest argument. Kazdy program mozna zle napisac. Ja tylko pokazuje, ze jakkolwiek trzeba uwazac to jednak istnienie takich sekcji jest konieczne (vide przyklad z EEPROM, czytania wielobajtowych zmiennych, czy np. zmiana kontekstu procesora w systemach z implementacja wielowatkowosci). W tych przypadkach w architekturze AVR po prostu nie da sie tego zrobic inaczej zachowujac efektywnosc kodu.
Użytkownik "T.M.F." snipped-for-privacy@nospam.mp.pl> napisał w wiadomości news: snipped-for-privacy@hermes.wizzard...
Właśnie, o to chodzi, coprawda ja dopiero zaczynam praktykę, ale nie da się w 2kb (2313) upchnąć semaforów, zaawansowanych procesów sterowania itd. A przerwania są i działają dobrze. Pozatym w tak małym kodzie zazwyczaj potem nie wprowadza się wielkich poprawek które mogły by wpłynąć na zbyt długie wyłączenie obsługi przerwań, no i ogarnąć go łatwo.
Pozdrawiam Łukasz
Nie widze problemu. Np semafor "Dane Gotowe" ustawiasz w czasei obslugi przerwania. Tam gdzie dane sa czytane mozesz go zerowac po przeczytaniu i jest ok. Jesli przychodza nastepne dane a semafor nie jest wyzerowany to ustawia sie sygnal ze jest "overflow"
Nie zrozumielismy sie moze. Jak przerwania sa utrupione to latwiej o calkowita zakorkowanie sie programu. Wurzadzeniah ktore chodza same i nie powinny wumagac interwencji czlowieka to jest raczej katastrofa. Masz np. streownik ogrzewania i musisz do niego dojsc i zresetowac recznie albo sprawdzac co jest bo nie chodzi
Nie powinno byc, jako rzekles
To o czym piszesz to raczej odmiana mutexu (a i to nie do końca) niż semaforu - semafory służą raczej do podziału zadań między wątki a nie do synchronizacji 2 procesów.
Taki przykład miałby sens większy, gdybysmy mieli do czynienia z przełaczaniem kontekstu dwóch watków w nieoczekiwanych miescach. A AVR raczej chyba nie stosowane ze względu na spory narzut samego przełaczania.
IMHO stosowanie mutexów/semaforów na AVR jest bez sensu a tego typu proste machanizmy jak opisujesz są dość oczywiste.
Natomaist dalej będe się upierał, że _semafor_ wymaga operacji atomowej złożonej (dekrementacja/inkrementacja semafora).
Myśle, że urzadzenie, które się "korkuje" samo z siebie nie nadaje się do używania w dowolnej formie ;)
:) Nie wiem, czy uzywanie watchdoga jest dobrym pomysłem do łatania programu :)
Oboje macie racje ;-) Ale w momencie jak chcemy uzyc jakiegos RTOSa, to Sebastian ma racje - bez blokowania przerwan w sekcjach krytycznych za duzo nie nawojujemy. Po prostu trzeba wiedziec jak pisac takie programy. A trzeba to robic naprawde starannie ;-)
Program ma byc pisany i testowany bez WD. Ja WD uzywam dopiero w finalnej wersji programu - wczesniej nie ma sensu, bo moge nie zauwazyc ze czasami idzie wszystko w maliny.
Użytkownik jerry1111 napisał:
Otóż właśnie. Program powinien działać pewnie i stabilnie bez zabezpieczeń, przy wszystkich możliwych kombinacjach czasowych zdarzeń. Zabezpieczenia są lekiem tylko na szczególne przypadki. Oczywiście nie licząc tricków specjalnego przeznaczenia, jak np okresowe wzbudzanie programu przez wd. Poza tym nieumiejętne użycie resetu krytycznego też może nieźle namieszać w urządzeniu, którym steruje nasz program.
Użytkownik "T.M.F." snipped-for-privacy@nospam.mp.pl> napisał w wiadomości news: snipped-for-privacy@hermes.wizzard...
Dzięki za odpowiedzi a za TĄ szczególnie. Pozdrawiam Wojtek
Szczerze mowiac to nie wiem co to jest mutex, moglby ktos odkryc te tajemnice. Nie jestem z zawofu specjalista od software pomimo ze to robie (z malymi przerwami) od 30 lat.
A ktorz mowi ze WD ma program latac. Tyle ze program ktory programista mniemal zrobic dobrze nie koniecznie przewiduje wszytkie mozliwosci ktore moga sie zdarzyc. Poza tym jak powiedzilem maga sie zdarzac rozne nieprzewidzane zaklocenia ktore powoduja nierawidlowy bieg programu. WD nigdy sie nie uzywa przy uruchamianiu. Jak mozna by uruchamiac jak WD robilby Reset jak program sie zatrzymuje na jakims Breakpoint'cie. Pozdro Grzechu
Co to za ciekawostka ? Ja zawsze uwazalem ze WD ma powodowac restart kompletnie od zera i tyle. Nie stosuje sie go do nieczego innego jak do zapobierzenia nieprzewidzanym sytuacjom gdzie program przestaje dzialac prawidlowo z jakiegos powodu.
Reset jest zawsze zlem koniecznym i oczywiscie trzeba uwzglednic co sie steruje. Urzadzenie w ruchu, jakas mszyna moze byc poszkodowane/na w takeij sytuacji.
Użytkownik Greg napisał:
Żadna ciekawostka, jeden ze sposobów okresowego wyciągania procesora z uśpienia jub pętli do której został (celowo) wprowadzony.
Manewrowanie peryferiami daje bardzo ciekawe możliwości. Oczywiście używa się takich rzeczy tylko w razie potrzeby i dostępności peryferiów.
No to to jest nieczyste zagranie. Domyslam sie ze procek nie musi caly czas pracowac. Robilem so takiego do radiotelefony chodzacego na baterii slonecznej. Chodzilo o to zeby spal jak najdluzej i tylko co jakis czas sie budzil i sprawdzal czy czegos od niego nie chca. Ale na to mialem tajmerek z 555 ktory wysylal przerwanie co jakis czas. WD powinien byc tylko dla bezpiecznstwa i ma robic Reset kompletny. Regularne, okresowe robienie resetu to raczej nonsens. Przynajmniej w urzadzeniach ktore robile to nie mialoby sensu. Jak inicjalizacja trwa 300 ms to nie moge sobie pozwalac na robienie tego bez potrzeby. Ale jak robisz maly programik to moze to miec jakis sens.
Napisales ogolnikowo wiec to znaczy wszytko i nic.
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required