3.3 Programmable Interrupt Controller

PIC (Programowalny Kontroler Przerwań) jak sama nazwa wskazuje jest programowalnym kontrolerem przerwań. Jest on modułem chipsetu, ale kiedyś był samodzielnym układem scalonym o nazwie 8259A. Służy on do zarządzania systemem przerwań generowanych przez sprzęt i podawaniem tych zgłoszeń procesorowi. Na początek omówię część techniczną układu, a w drugiej części przedstawię jego rejestry i sposób programowania.

Schemat wyprowadzeń
Schemat ideowy

Wejścia IRQ0-7 są połączone z odpowiednimi wejściami rejestrów urządzeń i służą do przesyłania impulsów zgłoszeń przerwań.

Wejścia D0-7 są wejściami podłączonymi do szyny danych i służa do przekazywania danych i rozkazów..

Wejścia ~WR ~RD służą do ustalania kierunku przepływu informacji między procesorem i układem kontrolera.

Wejście ~CS umożliwia wprowadzenie układu w tryb programowania.

Wejście ~SP/~EN spełnia rolę wejścia EN w buforowym trybie pracy lub wybiera tryb pracy układu w trybie nie buforowym (Master lub Slave).

Wejście INT służy do komunikowania procesora o konieczności obsługi przerwania.

Wejście ~INTA jest to wejście, przez które procesor nadsyła impulsy potwierdzające.

Wejście A0 służy do rozróżniania rozkazów w trybie programowania.

Tryb pracy pojedynczego układu 8259A

Przypuśćmy, że pewne urządzenie połączone z układem kontrolera wysyła impuls na linii IRQn. Jeżeli w rejestrze kontrolera IMR (Interrupt Mask Register) bit odpowiadający numerowi zgłoszenia n jest wyzerowany to impuls od urządzenia jest zapamiętywany w rejestrze IRR (Interrupt Request Register). Czyli IMR jest maską przyjmowania zgłoszeń nadchodzących przerwań. Rejest IRR może przyjmować zgłoszenia wszystkich przerwań jednocześnie, ale tylko jedno zgłoszenie może być na raz obsługiwane przez procesor. Wyselekcjonowaniem tego zgłoszenia zajmuje się blok oceny priorytetu. Przerwania o niższym numerze mają wyższy priorytet tak więc blok ten wybierze zgłoszenie o numerze, który jest przypisany najmniej znaczącemu ustawionemu bitowi w rejestrze IRR.

Po wybraniu przerwania wysyłany jest sygnał linią INT do procesora. Procesor odpowiada sygnałem na linii ~INTA pod warunkiem, że obsługa przerwań nie jest programowo wyłączona bitem IF rejestru flag procesora.

Układ PIC po odebraniu sygnału potwierdzenia na linii ~INTA przystępuje do ustawiania odpowiedniego bitu rejestru ISR (Interrupt Service Register). Jeżeli bity rejestru IRR niższe od n są wyzerowane to następuje ustawienie bitu n w rejestrze ISR. Rejestr ISR przechowuje zawsze tylko jeden ustawiony bit i jest to bit aktualnie obsługiwanego zgłoszenia. Procesor wysyła drugi impuls ~INTA i kontroler przesyła wektor przerwania na linii danych D0-7 w postaci:

bity
opis
3-7
offset wektora przerwań
0-2
numer bitu ustawionego w rejestrze ISR

Moment wyzerowania bitu w rejestrze ISR jest zależny od trybu pracy układu kontrolera i jest wymagany do umożliwienia obsługi kolejnych przerwań. W trybie pracy AEOI (Automatic End Of Interrupt) rejestr ISR jest automatycznie zerowany, gdy procesor przełącza się do wektora obsługi danego przerwania. W trybie pracy EOI kontroler czeka na programowe wyzerowanie rejestru, które powinno wystąpić podczas procedury obsługi danego przerwania. Zwykle kod taki znajduje się przed powrotem z danego przerwania.

Po wyzerowaniu rejestru ISR kontroler przechodzi do obsługi następnego zgłoszenia jeżeli tylko jest ono zasygnalizowane ustawionym bitem w rejestrze IRR.

Kaskadowy tryb pracy układów 8259A

Oczywiście w komputerach PC istnieją dwa układy pracujące w połączeniu kaskadowym. Drugi układ pracujący jako SLAVE jest podłączony pod wejście IRQ2 układu MASTER. Cała sekwencja obsługi zgłoszenia jest bardzo podobna do pracy pojedynczego układu. Oczywiście priorytety wejść IRQ układu SLAVE maleją ze wzrostem ich numeru, ale wszystkie te wejścia mają większy priorytet niż wejścia IRQ3-7 układu MASTER, a mniejszy od wejść IRQ0-1.

Programowanie układów SLAVE/MASTER odbywa się po przez różne porty. Należy pamiętać, że podczas pracy z dwoma układami w trybie EOI należy wysłać dwa rozkazy zerowania rejestrów ISR. Do każdego z układów po jednym rozkazie zerującym odpowiedni bit przerwania. Tak samo programowanie układów jest rzeczą niezależną. Możliwe jest adresowanie wektorów jednego układu w zupełnie innym miejscy niż wektory drugiego. Zwykle jednak wektory przerwań układów ustawia się obok siebie.

Programowanie kontrolera 8259A

Programowanie układu odbywa się po przez przekazywanie tak zwanych słów ("słowo" jest tylko nazwą, a w rzeczywistości przekazujemy bajty) rozkazowych na odpowiednie porty procesora. Już na wstępie można podzielić te rozkazy na dwie grupy. Pierwsza grupa rozkazów są to rozkazy podawane tylko podczas inicjalizacji układu do pracy, nazywane są one ICW (Initialization Control Word). Mają one stałą budowę, którą przedstawiłem niżej.

ICW1
bity opis
5-7 000
4 1
3
Wyzwalanie wejść IRQ:
1 - poziomem
0 - zboczem
2 0
1
1 - Jeden układ
0 - kaskada układów
0 Jedynka na tym miejscu oznacza, że będzie wysyłany bajt ICW4.
ICW2
bity opis
3-7 Offset wektora przerwań.
0-2 000
ICW3 (Master)
bity opis
0-7 Jedynka na miejscu n oznacza, że wejście IRQn jest wyjściem układu Slave.
ICW3 (Slave)
bity opis
3-7 00000
0-2 Numer wejścia układu Master, do którego podłączone jest wejście INT układu Slave.
ICW4
bity opis
5-7 000
4 W komputerach PC/AT zawsze 0. Jedynka modyfikuje sposób klasyfikacji priorytetów w połączeniach kaskadowych.  
3 Zmienia znaczenie końcówki ~SP/~EN. Gdy równe 0 to końcówka służy do wybierania układu Master.
2
1 - Master
0 - Slave
Bit służący do wybierania układu Master i Slave, gdy bit3 tego rejestru jest ustawiony na buforowy tryb pracy: bit3=1.
1
1 - Tryb AEOI
0 - Tryb EOI
0 Jedynka oznacza tryb pracy dostosowany do procesorów 8086/88.

Druga grupa rozkazów to rozkazy, które mogą być przekazywane i zmieniać parametry układu podczas jego pracy. Są one nazwane OCW (Operation Control Word). Budowa rozkazów została opisana poinżej.

A teraz przedstawię porty, przez które uzyskujemy dostęp do danych rejestrów i przez które wysyłamy rozkazy.

Układ Port Rejestry Tryb dostępu
I

(IRQ0-IRQ7)

0x20 IRR, ISR, offset wektora przerwań odczyt
ICW1, OCW2, OCW3 zapis
0x21 IMR odczyt
ICW2, ICW3, ICW4, OCW1 zapis
II

(IRQ8-IRQ15)

0xA0 IRR, ISR, offset wektora przerwań odczyt
ICW1, OCW2, OCW3 zapis
0xA1 IMR odczyt
ICW2, ICW3, ICW4, OCW1 zapis

Przedstawię teraz przykładowy sposób programowania układu do pracy po przez podanie serii rozkazów ICW:

Zamierzam ustawić zgłoszenia przerwań sprzętowych IRQ0-IRQF na wektory INT20-INT2F.

Jako pierwszy bajt wysyłamy ICW1 do obu układów kontrolera ustawiając wyzwalanie zboczem, obecność połączenia kaskadowego i informując, że będzie wysyłany bajt ICW4.

mov al, 0x11 out 0x20, al out 0xA0, al

Teraz wysyłamy ICW2 do obu układów z zawartością offsetu wektora przerwań. Dla układu pierwszego jest to bajt o wartości 0x20, a dla drugiego układu 0x28. Jak widać z rozpiski umieszczonej pod koniec tej strony możemy w tym rozkazie ustawiać wartości z zakresu 0-0xF8 z przeskokiem 8. Czyli osiem kolejnych procedur INT od zadanego przez nas wektora będzie obsługiwać kolejne przerwania sprzętowe.

mov al, 0x20 out 0x21, al add al, 0x28 out 0xA1, al

Teraz należy ustawić parametry odnośnie połączonych kaskadowo dwóch układów. Oznaczamy dla układu MASTER, iż wejście IRQ2 jest połączone z układem SLAVE. Układ SLAVE także informujemy o tym połączeniu.

mov al, 4 out 0x21, al mov al, 2 out 0xA1, al

Ustawiamy tryb AEOI i tryb zgodności z procesorami 8086/88.

mov al, 1 out 0x21, al out 0xA1, al

Proces inicjalizacji rozkazami ICW jest już zakończony. Dodam jednak do tego kodu jeszcze wysłanie rozkazów OCW1 dla obu kontrolerów o wartości 0xFF. Jest to po prostu zamaskowanie wszystkich przerwań w rejestrze IMR kontrolera.

Rozkazy OCW nie muszą być podawane razem ani w żadnej ustalonej kolejności.

mov al, 0xFF out 0x21, al mov al, 0xFF out 0xA1, al

Jednak należy pamiętać, że w takim stanie komputer nie może pozostać dlatego, że komputer po przez brak obsługi jakiegokolwiek przerwania jest odcięty od świata zewnętrznego i nie jesteśmy w żaden sposób go kontrolować. No, ale taka chwilowa sytuacja jest czymś normalnym podczas ładowania podstawowych sterowników systemu operacyjnego.


OCW1
bity opis
0-7 Zawartość tego rozkazu zostanie przesłana do rejestru IMR. Bit n ustawiony oznacza, że przerwanie na linii IRQn nie będzie obsługiwane. Czyli jest to blokada sprzętowa zgłoszeń przerwań IRQ.
OCW2
bity opis
5-7
011 - Rozkaz EOI adresowany przez bity 0-2.
001 - nie adresowany rozkaz EOI
3-4 00 - sygnatura rozkazu
0-2 Numer linii IRQ, której dotyczy wysłanie rozkazu EOI.
OCW3
bity opis
7 0
5-6
11 - ustawienie maski specjalnej
10 - wyzerowanie maski specjalnej
3-4 01 - sygnatura rozkazu
2
1 - polling
0 - występowanie przerwań
0-1
11 - kontroler wystawia zawartość rejestru ISR do portu 0x20 dla układu Master, a do portu 0xA0 dla układu Slave.
10 - kontroler wystawia zawartość rejestru IRR do portu 0x20 dla układu Master, a do portu 0xA0 dla układu Slave.