Przerwanie

Z Wikipedii, wolnej encyklopedii
Skocz do: nawigacji, wyszukiwania

Przerwanie (ang. interrupt) lub żądanie przerwania (IRQInterrupt ReQuest) – sygnał powodujący zmianę przepływu sterowania, niezależnie od aktualnie wykonywanego programu. Pojawienie się przerwania powoduje wstrzymanie aktualnie wykonywanego programu i wykonanie przez procesor kodu procedury obsługi przerwania (ang. interrupt handler).

Rodzaje przerwań[edytuj | edytuj kod]

Przerwania dzielą się na dwie grupy:

  1. Sprzętowe:
    1. Zewnętrzne – sygnał przerwania pochodzi z zewnętrznego układu obsługującego przerwania sprzętowe; przerwania te służą do komunikacji z urządzeniami zewnętrznymi, np. z klawiaturą, napędami dysków itp.
    2. Wewnętrzne, nazywane wyjątkami (ang. exceptions) – zgłaszane przez procesor dla sygnalizowania sytuacji wyjątkowych (np. dzielenie przez zero); dzielą się na trzy grupy:
      1. faults (niepowodzenie) – sytuacje, w których aktualnie wykonywana instrukcja powoduje błąd; gdy procesor powraca do wykonywania przerwanego kodu wykonuje tę samą instrukcję która wywołała wyjątek;
      2. traps (pułapki) – sytuacja, która nie jest błędem, jej wystąpienie ma na celu wykonanie określonego kodu; wykorzystywane przede wszystkim w debugerach; gdy procesor powraca do wykonywania przerwanego kodu, wykonuje następną, po tej która wywołała wyjątek, instrukcję;
      3. aborts (nienaprawialne) – błędy, których nie można naprawić.
  2. Programowe – z kodu programu wywoływana jest procedura obsługi przerwania; najczęściej wykorzystywane do komunikacji z systemem operacyjnym, który w procedurze obsługi przerwania (np. w DOS 21h, 2fh, Windows 2fh, Linux x86 przerwanie 80h) umieszcza kod wywołujący odpowiednie funkcje systemowe w zależności od zawartości rejestrów ustawionych przez program wywołujący lub oprogramowaniem wbudowanym jak procedury BIOS lub firmware.

Producenci procesorów część pozycji w tablicy wektorów przerwań rezerwują dla przerwań wewnętrznych. Pozostałe numery przerwań mogą być dowolnie wykorzystane przez producentów systemów komputerowych i oprogramowania. Obsługiwanie większości przerwań (wszystkich lub wybranych numerów) można wstrzymać lub zablokować, wyjątkiem są przerwania niemaskowalne.

Opis procesorów rodziny x86[edytuj | edytuj kod]

Tryb rzeczywisty[edytuj | edytuj kod]

W trybie rzeczywistym (ang. real) pracy procesora adres procedury obsługi przerwania jest zapisany w tablicy wektorów przerwań. Tablica wektorów przerwań przechowuje adresy poszczególnych procedur obsługi przerwań; przerwania identyfikowane są przez numer (wektor przerwania) i w przypadku procesorów serii x86 jest możliwych do 256 przerwań.

Tablica wektorów przerwań znajduje się w pierwszych 1024 (256 4 Bajtowych adresów procedur obsługi przerwań) komórkach pamięci operacyjnej.

W komputerach PC jest zazwyczaj 16 (efektywnie 15 co wynika z kaskadowego połączenia dwóch kontrolerów przerwań) różnych sygnałów IRQ (ang. interrupt request) – IRQ0 do IRQ15. Często mówiąc o IRQ ma się na myśli sam numer przerwania, jako zasób udostępniany przez procesor. Jako, że jest ich tylko 16, bywają problemy z przydzieleniem osobnego przerwania każdemu z urządzeń, które go potrzebuje, może to powodować przydzielenie tego samego przerwania dwóm urządzeniom. Mówi się wtedy o konflikcie przerwań, gdyż najczęściej dwa urządzenia nie mogą współdzielić jednego.

Tryb chroniony[edytuj | edytuj kod]

W trybie chronionym (ang. protected) pracy procesora x86 (od procesora i286) mamy do czynienia z tablicą deskryptorów przerwań (ang. Interrupt Descriptor Table, IDT) łączącą każdy wektor wyjątku lub przerwania z deskryptorem bramy (deskryptory bram to deskryptory pozwalające na kontrolowany dostęp do segmentów kodu o różnych stopniach uprzywilejowana) dla procedury lub zadania (ang. task) obsługującym dany wyjątek lub przerwanie.

Położenie IDT jest zapisane w rejestrze tablicy deskryptorów przerwań (ang. Interrupt Descriptor Table Register, IDTR). IDT zawiera do 256 wpisów zwanych deskryptorami. Rozmiar IDT to 256*8B (8 Bajtów to rozmiar pojedynczego deskryptora); w przypadku mniejszej ilości deskryptorów (obsługiwanych przerwań) niż maksymalne 256, puste sloty (czyli w rzeczywistości nieważne deskryptory) powinny zawierać flagę dostępności segmentu (ang. Segment Present Flag, P) ustawioną na 0 (zobacz budowa deskryptora).

IDT może zawierać trzy różne rodzaje deskryptorów bram:

  1. deskryptor bramy zadania (ang. Task-Gate Descriptor)
  2. deskryptor bramy przerwania (ang. Interrupt-Gate Descriptor)
  3. deskryptor bramy pułapki (ang. Trap-Gate Descriptor)

Przerwania w PowerPC[edytuj | edytuj kod]

Gdy wystąpi przerwanie:

  1. Procesor czeka aż wcześniejsze instrukcje (będące w potoku) zostaną ukończone (procesor wykonuje instrukcje w niezmienionym kontekście tj. przy niezmienionym rejestrze MSR <<ang. Machine State Register>>).
  2. Mechanizm przerwania sprzętowo zapisuje adres następnej instrukcji do rejestru SRR0 (ang. Save/Restore Register), a rejestr MSR kopiuje do rejestru SRR1 (niektóre bity rejestru SRR1 są także zapisywane na podstawie typu przerwania, które nastąpiło).
  3. Nowa wartość dla rejestru MSR jest wpisywana (na podstawie typu przerwania, które nastąpiło). MSR[IR] i MSR[DR] są wyzerowane dla każdego typu przerwania, czyli translacja adresów zarówno dla instrukcji i danych jest zawsze wyłączona w czasie obsługi przerwania. Bit MSR[ILE] jest kopiowany do MSR[LE] (wybór trybu pracy procesora: MSR[LE]=0 big-endian mode albo MSR[LE]=1 little-endian mode). Obsługa przerwania odbywa się w trybie nadzorcy (ang. supervisor mode).
  4. Bit MSR[RI] jest wyzerowany. MSR[RI]=0 oznacza, że program obsługi przerwania jest w trakcie inicjacji i w momencie nastąpienia kolejnego przerwania pierwsze przerwanie będzie nadpisane (innymi słowy gdy MSR[RI]=0, to przerwanie jest nieodzyskiwalne <<ang. not recoverable>>).
  5. Gdy program obsługi przerwania zapisze na stosie SRR0 oraz SRR1, a wskaźnik stosu zostanie zaktualizowany, bit MSR[RI] jest ustawiany na 1 przez program obsługi przerwania. Ustawienie MSR[RI]=1 oznacza, że procesor może przyjąć kolejne przerwanie bez utraty poprzedniego (ang. recoverable exception).
  6. Procesor wykonuje pierwszą instrukcję procedury obsługi przerwania zgodnie z nową wartością rejestru MSR. Początek procedury obsługi przerwania jest wyliczany na podstawie typu przerwania (ang. vector offset) oraz bitu MSR[ME] (MSR[ME]=0 adres fizyczny 0x000n_nnnn, MSR[ME]=1 0xFFFn_nnnn).
  7. Powrót do przerwanego programu za pomocą instrukcji rfi (ang. return from interrupt). Instrukcja rfi wykonuje synchronizację kontekstu (ang. context synchronization).

Przerwania dzieli się na klasy: precyzyjne/nieprecyzyjne (ang. precise/imprecise), synchroniczne/asynchroniczne oraz maskowalne/niemaskowalne. Każdemu przerwaniu przypisywany jest priorytet. Najwyższy priorytet mają przerwania ‘System reset’ (priorytet 1) i ‘Machine check’ (priorytet 2). Oba przerwania należą do asynchronicznych i niemaskowalnych. W związku z najwyższym priorytetem obsługa tych przerwań nie będzie nigdy opóźniona. Ponieważ pojedyncza instrukcja może wywołać więcej niż jedno przerwanie (przerwanie precyzyjne, synchroniczne z priorytetem 3), to kolejność ich obsługi jest ściśle określona w zależności od typu instrukcji (np. instrukcje odczytu i ładowania liczb stałoprzecinkowych mają tą samą kolejność).

Pozostałe priorytety są następujące:

4 – przerwania nieprecyzyjne, np. przerwania od jednostki zmiennoprzecinkowej

5 – przerwania maskowalne, nieprecyzyjne, asynchroniczne, np. przerwanie zewnętrzne (ang. external)

6 – przerwania maskowalne, nieprecyzyjne, asynchroniczne, np. decrementer

Zobacz też[edytuj | edytuj kod]