Jakub Rakus
Guest
Tue Oct 14, 2014 8:28 pm
Dawno już nie robiłem nic na 8-bitowcach i chyba mi coś umknęło, a w
październikowej EP na str. 26 przeczytałem co następuje:
"(...)zmienne wyniku pomiaru są współdzielone między pętlą główną a
przerwaniem, a jak wiadomo, w przypadku 8-bitowego mikrokontrolera oraz
zmiennych większych niż jeden bajt, sytuacja taka może prowadzić do złej
interpretacji wartości zmiennej, jeśli się odpowiednio nie zabezpieczymy."
Czy mógłby ktoś wyklarować dlaczego, jak i po co? Jakie zabezpieczenie?
Coś kojarzę, że miałem dawno temu z tym jakieś problemy, bo między
main() a ISR() wymieniałem zmienną typu uint32_t i pojawiały się w niej
jakiejś bzdety, ale już nie pamiętam co wtedy zaradziłem.
--
Pozdrawiam
Jakub Rakus
Grzegorz Niemirowski
Guest
Tue Oct 14, 2014 8:39 pm
Jakub Rakus <szczur01@op.pl> napisał(a):
Quote:
Dawno już nie robiłem nic na 8-bitowcach i chyba mi coś umknęło, a w
październikowej EP na str. 26 przeczytałem co następuje:
"(...)zmienne wyniku pomiaru są współdzielone między pętlą główną a
przerwaniem, a jak wiadomo, w przypadku 8-bitowego mikrokontrolera oraz
zmiennych większych niż jeden bajt, sytuacja taka może prowadzić do złej
interpretacji wartości zmiennej, jeśli się odpowiednio nie zabezpieczymy."
Czy mógłby ktoś wyklarować dlaczego, jak i po co? Jakie zabezpieczenie?
Coś kojarzę, że miałem dawno temu z tym jakieś problemy, bo między main()
a ISR() wymieniałem zmienną typu uint32_t i pojawiały się w niej jakiejś
bzdety, ale już nie pamiętam co wtedy zaradziłem.
Na tych mikrokontrolerach operacje na zmiennych większych niż 8-bitowe nie
są atomowe. Przykładowo dekrementujesz sobie 16-bitową zmienną w przerwaniu,
a w głównym programie masz pętlę sprawdzającą, czy zmienna ta osiągnęła
zero. Może się zdarzyć, że zmienna ta będzie miała wartość 0x0100 i wtedy:
- główny kod sprawdzi młodszy bajt i stwierdzi jego równość zeru
- nastąpi przerwanie, które zmieni wartość zmiennej na 0x00ff
- główny kod sprawdzi starszy bajt i stwierdzi jego równość zeru
- główny kod stwierdzi, że zmienna ma wartość 0x0000, choć nie będzie to
prawdą
Dlatego stosujemy sekcje krytyczne. Kłania się np. makro ATOMIC_BLOCK, które
wyłącza przerwania na czas wykonywania sekcji.
--
Grzegorz Niemirowski
http://www.grzegorz.net/
OE PowerTool i Outlook Express:
http://www.grzegorz.net/oe/
Uptime: 15 days, 2 hours, 38 minutes and 10 seconds
platformowe gĹupki
Guest
Tue Oct 14, 2014 8:42 pm
Quote:
Dlatego stosujemy sekcje krytyczne. Kłania się np. makro ATOMIC_BLOCK,
które wyłącza przerwania na czas wykonywania sekcji.
tak ? makro ?
to ciekawe, a jak niby takie makro ma działać?
wyłącza przerwania czy co?
Sebastian BiaĹy
Guest
Tue Oct 14, 2014 9:17 pm
On 2014-10-14 22:28, Jakub Rakus wrote:
Quote:
"(...)zmienne wyniku pomiaru są współdzielone między pętlą główną a
przerwaniem, a jak wiadomo, w przypadku 8-bitowego mikrokontrolera oraz
zmiennych większych niż jeden bajt, sytuacja taka może prowadzić do złej
interpretacji wartości zmiennej, jeśli się odpowiednio nie zabezpieczymy."
a) volatile, tylko z głową
b) zrób sobie szablon atomic< T > który własnie wyłączy przerwania
podczas dostępu - cli()/sei(). Szablon pozwoli ukryć ten szczegół.
janusz_k
Guest
Wed Oct 15, 2014 8:36 pm
W dniu 2014-10-14 23:17, Sebastian Biały pisze:
Quote:
On 2014-10-14 22:28, Jakub Rakus wrote:
"(...)zmienne wyniku pomiaru są współdzielone między pętlą główną a
przerwaniem, a jak wiadomo, w przypadku 8-bitowego mikrokontrolera oraz
zmiennych większych niż jeden bajt, sytuacja taka może prowadzić do złej
interpretacji wartości zmiennej, jeśli się odpowiednio nie
zabezpieczymy."
a) volatile, tylko z głową
b) zrób sobie szablon atomic< T > który własnie wyłączy przerwania
podczas dostępu - cli()/sei(). Szablon pozwoli ukryć ten szczegół.
Nie trzeba szablonu jest gotowe makro,
--
Pozdr
Janusz_K