1. Obsługa zdarzeń poprzez przerwania
Obsługa przerwania polega na przerwaniu aktualnie wykonywanego procesu i wykonaniu procedury przypisanej danemu zdarzeniu gdy takie zdarzenie zajdzie.
Procedura nazywa się procedurą obsługi przerwania ( ang. interrupt handler). Często używany jest też skrót ISR ( ang. Interrupt Service Routine).
Powrót
Zdarzenie Z1
z procedury
P1 - Procedura
Przerwanie
obslugi
obslugi
przerwania
przerwania
P1
P0 - Proces
glówny
P0
P0
Obsługa zdarzenia Z1 poprzez procedurę obsługi przerwania P1
Zachodzi potrzeba rozstrzygnięcia które zdarzenie ma obsługiwane gdy wiele z nich wystąpi naraz. Istnieją tu dwie podstawowe strategie postępowania:
1. Jednopoziomowy system przerwań.
2. Priorytetowy system przerwań.
Gdy za obsługę oczekuje więcej nie obsłużonych przerwań wybór przerwania do obsługi może być dokonany według różnych zasad.
1. Poszczególnym przerwaniom mogą być przypisane priorytety.
2. Przerwania mogą być obsługiwane według kolejności zgłoszeń.
PDF created with pdfFactory trial version www.pdffactory.com
Zdarzenie Z2
Przyjecie obslugi
przerwania
Z2
Obsluga
Obsluga
przerwania
przerwania
P0 - Proces
Z1
Z2
glówny
P0
P0
Dwa przerwania obsługiwane w systemie jednopoziomowym Obsluga
przerwania
Z1
Obsluga
zawieszona
przerwania
Zdarzenie Z1
Zdarzenie Z2
Z1
wznowiona
Obsluga
Obsluga
Kontynuacja
przerwania
przerwania
obslugi
Z1
Z2
przerwania
P0
Z1
P0
Dw
a przerwania obsługiwane w systemie wielopoziomowym
Obsługa przerwań w systemie komputerowym jest czasami blokowana przez system operacyjny. Maksymalny czas zablokowania przerwań Tdmax jest podstawową miarą jakości systemu czasu rzeczywistego.
Czas Tdmax powinien być jak najkrótszy.
Maksymalny czas Tmax reakcji na zdarzenie, w systemie z przerwaniami, jest równy maksymalnemu czasowi zablokowania przerwań Tdmax czyli Tmax = Tdmax .
PDF created with pdfFactory trial version www.pdffactory.com
Obsługa zdarzeń poprzez przerwania ma dla systemu komputerowego daleko idące konsekwencje.
Istnieją dwie strategie obsługi zdarzeń poprzez przerwania: 1. Zdarzenie obsługiwane jest przez procedurę obsługi przerwania.
2. Procedura obsługi przerwania odblokowuje wątek który wykonuje obsługę zdarzenia.
wątek procedura obsługi
przerwania
przerwanie
ISR
powrót z procedury
obsługi przerwania
Obsługa zdarzenia poprzez procedurę obsługi przerwania procedura
wątek obsługi
wątek
obsługi
przerwania
Czas
przerwania
event
przerwanie
ISR
odblokowanie
wątku
Procedura obsługi przerwania wykonuje część pracy a następnie odblokowuje wątek
wątek obsługi
wątek
przerwania
event
przerwanie
odblokowanie
wątku
Czas
Przerwanie zamieniane w zdarzenie które odblokowuje wątek.
PDF created with pdfFactory trial version www.pdffactory.com
2. Obsługa przerwań w komputerach typu PC
Procesory serii 80x86 stosowane w komputerach PC obsługują następujące rodzaje przerwań:
1. Przerwania zewnętrzne – generowane są przez urządzenia zewnętrzne i koordynowane przez kontroler przerwań.
2. Przerwania wewnętrzne - generowane są przez układy wewnętrzne procesora i zwykle związane z naruszeniem systemu ochrony.
3. Przerwania programowe – generowane przez oprogramowanie.
Procesor posiada jedną linię zgłaszania przerwania IRQ ( ang. Interrupt Request). Liczba urządzeń mogących zgłosić przerwanie jest większa.
Aby rozwiązać ten problem stosuje się urządzenie nazywane kontrolerem przerwań ( ang. Interrupt Controller) RAM
Procedura
Linie
obslugi
P1
NMI
przerwan
przerwania
Urzadzenie
IRQ0
IRQ1
255
INTA Kontroler
VH7
IRQi
INT
Procesor
INT
przerwan
Tablica
V
Kontroler
wektorów
VH1
IRQ7
urzadzenia
przerwan
VH0
IMR
CR
0
Baza B
V = B + i
i - numer lini IRQ
kontrolera
Obsługa przerwań w komputerze PC
Linia IRQ0 posiada najwyższy priorytet, Linia IRQ7 najniższy. Kontroler posiada dwa dostępne z zewnątrz 8 bitowe rejestry:
1. Rejestr poleceń CR ( ang. Control Register). Do rejestru CR system wpisuje polecenia i odczytuje zeń statusy.
2. Rejestr maski IMR ( ang. Interrupt Maskl Register).
Rejestr IMR pozwala na zamaskowanie przyjmowania przerwań. Gdy bit i IMR jest ustawiony na 1 przerwanie IRQi będzie ignorowane. Gdy bit i ustawimy na 0 przerwanie IRQi będzie przyjmowane.
PDF created with pdfFactory trial version www.pdffactory.com
1. Arbitraż przerwań.
2. Maskowanie przerwań.
3. Tworzenie powiązania pomiędzy pobudzeniem linii przerwania IRQi a wektorem przerwań VHi.
Gdy przerwanie IRQi zostanie przyjęte, kontroler przekazuje do procesora bajt zawierający liczbę V = B + i (baza kontrolera + numer przerwania). Na tej podstawie procesor wykonuje instrukcję INT V a zatem i procedurę obsługi przerwania IRQi . Adres procedury obsługi przerwania IRQi procesor pobiera z wektora VHi = V.
IRQ
IRQ Wektor
Urządzenie
Master Slave HEX
0
8
Timer – generuje przerwania
zegarowe
1
9
Klawiatura
8
70
Zegar czasu rzeczywistego RTC
2
9
71
W kontrolerze master wejście z
kontrolera slave
W kontrolerze slave wolne
10
72
wolne
11
73
wolne
12
74
wolne
13
75
Koprocesor
14
76
Kontroler 1 dysków IDE
15
77
Kontroler 2 dysków IDE
3
B
Układ transmisji szeregowej COM2
4
C
Układ transmisji szeregowej COM1
5
D
Port drukarki LPT1
6
E
Kontroler dysków elastycznych
7
F
Port drukarki LPT2
Tablica linii przerwań, wektorów przerwań i urządzeń generujących przerwania w komputerze AT
PDF created with pdfFactory trial version www.pdffactory.com
3. Programowanie obsługi przerwań w systemie QNX
Aby zaimplementować obsługę pewnego przerwania w procesie należy: 1. Napisać procedurę obsługi tego przerwania.
2. Zainstalować procedurę w systemie to znaczy spowodować aby procedura była wykonana gdy wybrane przerwanie zostanie przez system odebrane (instalacja procedury).
Instalacja procedury obsługi przerwania
int qnx_hint_attach(unsigned intnum, void far
*handler, unsigned DS)
intnum
Numer przerwania – odpowiada numerowi linii IRQ
kontrolera przerwań (liczba od 0 do 15)
handler
Nazwa funkcji obsługi przerwania.
DS
Identyfikator segmentu danych procesu.
Funkcja zwraca:
> 0 – identyfikator procedury obsługi przerwań ( mała liczba typu int)
- 1 – gdy błąd.
Parametr DS jest identyfikator segmentu danych procesu. Aby go uzyskać należy wykonać makro systemowe FP_SEG(…).
Deinstalacja funkcji obsługi przerwania:
int qnx_hint_detach(int iidend)
iidend
Identyfikator funkcji obsługi przerwania – liczba
zwracana przez funkcję qnx_hint_attach
Funkcja zwraca: > 0 – sukces, - 1 – błąd. Wykonanie funkcji zrywa powiązanie pomiędzy przerwaniem a funkcją jego obsługi.
PDF created with pdfFactory trial version www.pdffactory.com
Maskowanie / odmaskowanie przerwania.
Kontroler przerwań pozwala na zablokowanie przyjmowania przerwań (maskowanie) lub dopuszczenia ich do obsługi (odmaskowanie).
Zamaskowane przerwania nie są obsługiwane. Aby przerwanie zamaskować, odmaskować czy testować stan maski używa się funkcji: int qnx_hint_mask(unsigned intnum, unsigned action) intnum
Numer przerwania – odpowiada numerowi linii IRQ
kontrolera przerwań (liczba od 0 do 15)
action
Specyfikacja akcji: 0 – testuj stan maski, 1 –
odmaskuj przerwanie, 2 – zamaskuj przerwanie
Funkcja zwraca:
0 – przerwanie dozwolone (nie zamaskowane)
1 – przerwanie zabronione ( zamaskowane).
Zasady tworzenia funkcji obsługi przerwania:
1. Funkcja musi być poprzedzona kwalifikatorem far.
2. Funkcja może zwracać 0 lub identyfikator utworzonego w procesie depozytu (proxy). Gdy funkcja zwraca numer depozytu jest on generowany i może być odebrany przez funkcję Receive która zostanie wtedy odblokowana.
3. Procedura obsługi przerwania powinna być tak krótka jak to tylko możliwe. Wszelkie dłuższe akcje powinny być wykonane w procesie który zostanie przez procedurę odblokowany (przez generację depozytu).
4. Funkcja nie może zawierać żadnych wywołań systemowych.
PDF created with pdfFactory trial version www.pdffactory.com
Wzorzec konstruowania mechanizmu obsługi przerwań.
// Kompilacja: cc int1.c -o int1 -Wc -s
#include <stdlib.h>
#include <sys/irqinfo.h>
#include <sys/proxy.h>
#include <sys/kernel.h>
pid_t proxy;
volatile unsigned counter = 0;
// Funkcja obsługi przerwania -------
pid_t far handler(void) {
counter++;
if(counter % 100 == 0)
return(proxy);
else
return(0);
}
void main(void) {
int id,i=0;
pid_t pid;
// Utworzenie proxy ---------------
proxy = qnx_proxy_attach(0,0,0,-1);
// Instalacja handlera ------------
id = qnx_hint_attach(0,&handler,FP_SEG(&counter)); counter = 0;
do {
pid = Receive(0,0,0);
printf("Przerwan %d\n",i);
i++;
} while(i < 100);
qnx_hint_detach(id);
}
Przykład 3-1 Przykład użycia procedury obsługi przerwania zegarowego PDF created with pdfFactory trial version www.pdffactory.com
D/A1
CLK 0
GATE0
Dekoder
generator
OUT0
adresu
wybór
10 MHz
licznik 0
rejestru
2 kan 12 bit
/ 10
licznik 1
konwerter
DA
/ 10
licznik 2
8254
zatrzask 24
status
la ISA
bit
Wyjścia
8
ista
Bufor
cyfrowe
ag
Magistrala wewnętrzna
danych
16 bit
8
M
układ
Wyjścia
wyboru
multiplekser
8
Uklad
cyfrowe
kanału
sterowania
16 bit
8
DMA
konwerter AD 12
wyzwalani
bit
e
TRIG0
EOC
Ster.
sample &
Multiplekse
przerwania
hold
r 8 / 16 we
mi
wzmacniacz
wejścia
pomiarowy
analogowe
Rys. 3-1 Schemat blokowy karty interfejsowej PCL-718
PDF created with pdfFactory trial version www.pdffactory.com
Adres
Odczyt
Zapis
portu
BASE+0
A/D bajt młodszy & kanał
Wyzwalanie programowe
A/D
BASE+1
A/D bajt starszy
N/A
BASE+2
Zakres kanałów multipleksera Zakres kanałów
multipleksera
BASE+3
D/I bajt młodszy (DI0-7)
D/O bajt młodszy (DO0-7)
BASE+4
N/A
D/A 0 bajt młodszy
BASE+5
N/A
D/A 0 bajt starszy
BASE+6
N/A
D/A 1 bajt młodszy
BASE+7
N/A
D/A 1 bajt starszy
BASE+8
Status
Kasowanie źródła
przerwania
BASE+9
Rejestr sterujący - zapis
Rejestr sterujący - odczyt
BASE+10
N/A
Konfiguracja liczników
BASE+11
D/I bajt starszy (DI8-15)
D/O bajt starszy (DO8-15)
BASE+12
Licznik 0
Licznik 0
BASE+13
Licznik 1
Licznik 1
BASE+14
Licznik 2
Licznik 2
BASE+15
N/A
Sterowanie licznikami
Tabela 3-1 Rejestry karty PCL-718
// Program obslugi karty PCL718 w trybie przerwan
// Kompilacja:
// cc pcltest4.c -o pcltest4 -T0
#include <stdio.h>
#include <sys/kernel.h>
#include <sys/irqinfo.h>
#include <sys/proxy.h>
#define INTE 1
#define BASE 0x300
#define IRQ 0x05;
// Counter 1 i 2 f=Fzeg/C1*C2 Fzeg = 10MHz
// f = 50kHz, T = 20us
#define C1 2
#define C2 100
unsigned base = BASE;
unsigned irq = IRQ;
pid_t id_handler;
pid_t proxy_irq;
int cnt = 0;
PDF created with pdfFactory trial version www.pdffactory.com
int PCL_init(unsigned int baseI, unsigned int irqI) {
outp(baseI+9, 0x70);
...
}
int PCL_mux(unsigned int baseI, unsigned int first, unsigned int last){
outp(baseI+2,(last<<4) + first);
return 1;
}
int PCL_counter(unsigned int baseI, unsigned int l1, int l2){
...
return 1;
}
// handler obslugi przerwania IRQ5
#pragma off(check_stack)
pid_t far handler_irq() {
return (proxy_irq);
}
#pragma on(check_stack)
void main(void) {
int i, adlow, adhigh;
int x,chn;
//inicjalizacja karty PCL
base = PCL_init(base, irq);
if(base == 0) {
printf("Brak karty PCL718 lub uszkodzona\n");
exit(1);
}
PCL_mux(base, 0, 0);
PCL_counter(base, C1, C2);
//inicjalizacja depozytu (proxy)
if((proxy_irq = qnx_proxy_attach(0, 0, 0, -1)) == -1) {
printf("proxy_irq\n");
exit(0);
}
//inicjalizacja handlera obslugi przerwania
id_handler = qnx_hint_attach(5, &handler_irq, FP_SEG(&i)); if(id_handler = -1) {
printf("hint_attach\n");
exit(0);
}
PDF created with pdfFactory trial version www.pdffactory.com
for(;;) {
// pobieranie co 20 us 1 wejscia analogowego
Receive(proxy_irq, 0, 0); // obsluga depozytu irq
outp(base+8, 0);
// start przetwarzania
adlow = inp(base);
adhigh = inp(base+1);
x = (adhigh<<4) | (adlow>>4);
chn = adlow & 0x0F;
printf("cnt= %d x= %d chn= %d\n",cnt,x,chn); cnt++;
}
qnx_proxy_detach(proxy_irq);
qnx_hint_detach(id_handler);
}
Przykład 3-2 Obsługa karty PCL718 w trybie przerwań
przerwanie
wątek
wątek
główny
odczytu
cnt
wspólne
Przetwornik A/D
dane
tail
head
bufor buf
PDF created with pdfFactory trial version www.pdffactory.com