Instrukcja AVR SEI ( http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_SEI.html ) czeka na zakończenie kolejnej instrukcji przed włączeniem przerwań.
Jeśli użyję innej instrukcji, aby ustawić flagę I w SREG, czy to również czeka 1 instrukcję?
Innymi słowy: czy czekanie jest cechą instrukcji SEI lub rejestru statusu?
Jeśli jest to cecha instrukcji SEI, to w którym momencie faktycznie ustawiana jest flaga, w cyklu wykonującym SEI lub z następną instrukcją?
avr
interrupts
assembly
jayjay
źródło
źródło
Odpowiedzi:
Wyniki empiryczne!
Podczas gdy inne odpowiedzi są przemyślane i dobrze uzasadnione, wszystkie są niekompletne lub jedynie domysł. Tam, gdzie dokumentacja jest niejednoznaczna, musimy eksperymentować i testować każdy przypadek.
To pytanie zasługuje na rozstrzygającą odpowiedź, więc wyciągnijmy AVR i zacznijmy ustawiać trochę bitów!
Procedura
Aby przetestować, stworzyłem mały program Arduino (ATMEGA328P), który ...
while (1)
)INT0
niski poziom)Użyłem łóżka testowego, które włączałoby diodę LED w pojedynczej instrukcji po włączeniu przerwań. Próbując różnych sposobów włączania przerwań w łóżku testowym i sprawdzania diody LED, mogłem stwierdzić, czy instrukcja po instrukcji aktywującej została wykonana, czy nie.
Jeśli dioda LED nie zapaliła się, to wiem, że ISR wykonał (i zablokował) natychmiast po włączeniu przerwań.
Jeśli dioda LED się zapaliła, to wiem, że następna instrukcja mogła zostać wykonana przed wywołaniem ISR.
Wyniki
SEI
instrukcja (skrzynka podstawowa)Kod:
sei
Wynik: dioda LED włączona. Wykonano instrukcję.
OUT
instrukcjaKod:
Wynik:
LED włączone. Wykonano instrukcję.
ST
instrukcjaKod:
Wynik:
LED włączone. Wykonano instrukcję.
Wniosek!
P: Czy oczekiwanie jest funkcją instrukcji SEI lub rejestru statusu?
Odp .: Wygląda na to, że zmiana
I
bitu inSREG
z a0
na a1
pozwoli następnej instrukcji na wykonanie następnej, nawet jeśli występuje oczekujące przerwanie, niezależnie od instrukcji użytej do ustawienia bitu.Notatki
To faktycznie przerodziło się w bardzo interesujące pytanie z wieloma komplikacjami. Jeśli jesteś zainteresowany szczegółami, sprawdź ...
http://wp.josh.com/2016/01/05/different-ways-to-set-i-bit-in-avr-sreg-besides-sei/
źródło
Z mojej dokumentacji wynika, że wykonanie
sei
instrukcji nie różni się niczym od bezpośredniego wpisania 1 do bitu I SREG. Zaletą instrukcji jest to, że nie trzeba najpierw ładować wartości1<<I
do działającego rejestru, aby zmienić SREG, co oszczędza czas.Aby rozwinąć, używając
sei
:Ustawienie bitu za pomocą
sbi
(działałoby tylko, jeśli SREG znajdował się w dolnych 32 bajtach mapy rejestrów, ale wydaje się, że w większości, jeśli nie wszystko, nie jest).Piszę do I bit bezpośrednio w SREG:
I
Bit powinien być ustawiony w SREG jak tylkosei
instrukcją (lubsbi
lubout
) zakończy. Jednak wszelkie oczekujące przerwania nie będą obsługiwane, dopóki nie zakończy się kolejna instrukcja - bit zostanie ustawiony, ale włączenie przerwań wymaga dodatkowego cyklu. Ponieważ przerwanie nie może być obsługiwane w połowie instrukcji, a niektóre instrukcje wymagają więcej niż jednego cyklu do wykonania, określają czas potrzebny do włączenia jako jedna instrukcja. Tak powinno być w przypadku wszystkich wersji kodu - tzn. Każda z powyższych spowoduje opóźnienie instrukcji.Po kilku poszukiwaniach znalazłem ten wątek na forum Arduino, na którym przeprowadzono kilka różnych testów w celu zweryfikowania zachowania. Wydaje się, że zgadza się z tym, co powiedziałem powyżej.
Ponadto, zgodnie z tym wątkiem, jeśli
I
flaga jest już ustawiona, wówczas nie ma opóźnionej odpowiedzi przerwania, przezsei
co implikuje się, że opóźniona odpowiedź nie jest spowodowana przez samą instrukcję, ale raczej w wewnętrznym sprzęcie kontrolowanym przezI
flagę - więc każdej operacji, która zmienia flagę w SREG, czy tosei
lubout
czysts
będzie miał dokładnie takie samo zachowanie.źródło
SBI
nie można go użyć do ustawieniaI
bitu,SREG
więc każdy kod, który to robi, prawdopodobnie nie został przetestowany w prawdziwym życiu, ponieważ nawet się nie zgromadzi.SBI
może działać tylko na niższych 32 rejestrach, a SREG znajduje się w slocie 63.out
tego, którego użyłem pierwotnie. Myślałem, że natknę się na AVR (może być ATTiny), który ma SREG w niższych 32 rejestrach, ale mogę sobie to wyobrazić.IMHO zapisuje do SREG nadal opóźnia 1 instrukcję można przetestować w ten sposób (pseudokod):
Niestety brakuje mi czasu na zrobienie tego :(
źródło
To nie tak mówi. Dokumentacja mówi
nie że czeka na następną instrukcję. Przeczytałem to, ponieważ flaga jest ustawiana natychmiast, ale nawet jeśli jest włączona, żadne przerwania nie będą obsługiwane, dopóki następna instrukcja nie zostanie wykonana.
źródło