PIC 8259 PROGRAMMABLE INTERRUPT CONTROLLER Prof. Marco Solarino
QUALCHE PROBLEMA Nella gestione dell'interrupt vista in precedenza la situazione era semplificata dalla presenza di una sola periferica. Nei sistemi di elaborazione reali, invece, le periferiche sono molte, e questo comporta dei problemi.
QUALI? 1) Convogliare tante richieste di interrupt sull'unico piedino INTR; 2) Gestire la priorità in caso di richieste contemporanee; 3) Identificare la periferica che fa la richiesta di interrupt.
PIC 8259 LA SOLUZIONE Programmable Interrupt Controller (Controllore programmabile dell'Interrupt)
IL PIC 8259 PIC 8259 IRQ0 IRQ1 INTR IRQ2 IRQ3 IRQ4 INTA IRQ5 IRQ6 IRQ7 D0-D7
COLLEGAMENTI P0 CPU 8086 PIC 8259 IRQ0 IRQ1 INTR P1 INTA P7 IRQ7 8 8 BUS DATI
UNO NON BASTA Le periferiche che utilizzano l'interrupt sono più di otto, quindi nel PC sono presenti due PIC collegati in cascata. PIC1 (master) IRQ2 IRQ1 IRQ0 IRQ7 INTR INTA PIC2 (slave) IRQ8 IRQ15 BUS DATI CPU 8
REGISTRI Il colloquio con il PIC avviene tramite due registri al suo interno, uno utilizzato per la programmazione vera e propria del dispositivo e l'altro usato per impostare il mascheramento degli interrupt. Per questo motivo ogni PIC lavora con due indirizzi di I/O (20h e 21h per il PIC1 e A0h e A1h per il PIC2). L'indirizzo pari è dedicato al registro di programmazione, mentre quello dispari individua il registro di maschera.
PROGRAMMAZIONE La programmazione dei due PIC viene effettuata dal BIOS del sistema all'avvio. Noi avremo bisogno di interagire con il registro di programmazione soltanto per segnalare la fine del servizio dell'interrupt, inviando il carattere EOI (End Of Interrupt), codificato col valore 20h, subito prima del termine della nostra ISR.
COME SI FA? In Assembly: OUT 20h,20h OUT A0h,20h In C++: outportb(0x20,0x20); outportb(0xA0,0x20);
MASCHERAMENTO IMR – Interrupt Mask Register Ogni bit di maschera M controlla la rispettiva linea IRQ (M0-IRQ0, M1-IRQ1, ecc.). Con valore 0 la IRQ è abilitata, con valore 1 la IRQ è disabilitata.
ESEMPIO Volendo disabilitare solo l'interrupt della tastiera (collegata su IRQ1) mantenendo abilitati tutti gli altri, la configurazione del registro di maschera sarà: M7 M6 M5 M4 M3 M2 M1 1 M0 Quindi occorrerà inviare all'indirizzo 21h il valore 2 (00000010 in binario).
COME SI FA? In Assembly: OUT 21h,2 In C++: outportb(0x21,2);
C'E' UN PROBLEMA I PIC presenti nel PC sono utilizzati dal sistema per la gestione di molte periferiche, e quindi se dobbiamo mascherare una linea IRQ non dobbiamo alterare lo stato di abilitazione delle altre. CHE SIGNIFICA? Non possiamo utilizzare le istruzioni appena viste con i valori dell'esempio, perché oltre alla disabilitazione di IRQ1 ciò comporterebbe l'abilitazione di tutte le altre linee!
E ALLORA? In Assembly: In C++: IN AL,21h OR AL,2 OUT 21h,AL unsiged char mask; mask=inportb(0x21); mask|=2; outportb(0x21;mask);
outportb(0x21;inportb(0x21)|2); VARIANTE C++ In C++ le istruzioni precedenti si possono nidificare in una unica riga, rendendo non più necessaria la variabile mask: outportb(0x21;inportb(0x21)|2); ...e così la nostra IRQ1 è disabilitata senza modificare lo stato di abilitazione/disabilitazione delle altre linee.
Il PIC 8259 risolve i tre problemi indicati all'inizio, in quanto: IN CONCLUSIONE Il PIC 8259 risolve i tre problemi indicati all'inizio, in quanto: 1) convoglia le richieste di interrupt di fino a otto periferiche per dispositivo sull'unica linea INTR; 2) gestisce la priorità di più richieste contemporanee in base al numero di IRQ (IRQ0 max – IRQ7 min); 3) Identifica la periferica fornendo alla CPU il numero di interrupt relativo alla linea IRQ utilizzata.