Esercizio Temperatura Una stanza e monitorata da 4 sensori di temperatura, i quali sono pilotati da un PD32. Questultimo controlla costantemente che il valor medio della temperatura rilevata nella stanza sia compreso tra i valori [Tmin-Tmax]. Nel caso in cui il valor medio della temperatura non cada in tale intervallo, il microprocessore inviera un segnale di allarme su unapposita periferica, detta ALARM. Il segnale dallarme utilizzato e il valore 1 codificato con 8 bit. Se la temperatura ritorna allinterno dellintervallo [Tmin-Tmax], la CPU invia sulla periferica ALARM il valore 0. I sensori ritornano la temperatura misurata come un numero intero ad 8 bit, usando i decimi di gradi Celsius come unita di misura. Scrivere il codice assembly per il controllo dei sensori di temperatura e della periferica di allarme.
ASF Esercizio T_media in [Tmin-Tmax] T_media fuori da [Tmin-Tmax] newTemp,T_media NON in [Tmin-Tmax] / Alarm_ON Legenda per le transizioni: Input, Condizione / Output newTemp,T_media in [Tmin-Tmax] / Alarm_OFF newTemp, T_media NON in [Tmin-Tmax] / - newTemp, T_media in [Tmin-Tmax] / -
Esercizio Temperatura T_media=T s1 =T s2 =T s3 =T s4 = = (Tmin+Tmax)/2 Stato=IN_RANGE dev i ready? controlla dev.succ Polling NO SI Ricalcola media: T_media=T_media+(new_T_si-old_T_si)/4 T_media in_range? SI Stato = IN SI Stato = OUT SI OUTPUT: ALARM OFF NO OUTPUT: ALARM ON Input da dev_i: new_T_si NO Stato=IN Stato=OUT NO
Dal busy-wait allinterrupt Tecniche di interazione con periferiche di I/O finora studiate sono: Polling Busy-waiting Entrambe nella categoria sincrona. Adesso analizzeremo per la categoria asincrona, la metodologia ad interrupt Interrupt = interruzione. interromperà La periferica, una volta avviata, procederà in maniera autonoma fino a che non avrà completato la sua elaborazione ed interromperà il processore per avvertire che ha terminato. IL PROCESSORE DOPO AVER AVVIATO LA PERIFERICA CONTINUA LA SUA NORMALE ESECUZIONE.
Dal busy-wait allinterrupt Si assuma che per linterrogazione di un dispositivo, incluso il trasferimento del controllo alla procedura di gestione, laccesso al dispositivo, ed il ritorno al programma utente, siano necessari 400 cicli e che il processore lavori con una frequenza di clock di 2 GHz. Si calcoli la frazione di tempo di CPU consumata nei seguenti casi, assumendo che si esegua una interrogazione del dispositvo tramite busy-wait con una frequenza sufficiente a far sì che nessun dato venga mai perso e supponendo che i dispositivi siano potenzialmente sempre al lavoro. 1. Mouse => per non perdere alcun movimento dellutente deve essere interrogato almeno 30 volte al secondo. 2. CDROM player (20X)=> trasferisce dati al processore in blocchi da 8 bytes ad un tasso di 3 MB/s. Non è permesso perdere dati. 3. Hard Disk => trasferisce dati in blocchi da 4 longwords con un throughput max di 16 MB/s. Di nuovo non è permesso perdere dati.
Cicli di clock per secondo per linterrogazione= 30 * 400=12000 cicli/sec % cicli di clock del processore utilizzati= 12 * 10 3 = 0,0012% 1000 * 10 6 Frequenza di interrogazione=3000 Kb/sec =375K accessi/sec 8 byte/accesso Cicli per secondo spesi dalla CPU= 375K * 400 = 150*10 6 % processore utilizzato= 150 * 10 6 = 7,5% 2000 * 10 6 CD-ROM PLAYER (20x =>3 MB/sec) MOUSE Ignoriamo la discrepanza tra base 2 e base 10 Soluzione 1
Frequenza di interrogazione=16 Mb/sec =1 M=10 6 accessi/sec 16 byte/accesso Cicli per secondo spesi= 400 * 10 6 % processore utilizzato= 400 * 10 6 = 20% 2000 * 10 6 HARD DISK Ignoriamo la discrepanza tra base 2 e base 10 Osservazione: Per il mouse lipotesi di costante attività ha senso e l overhead è accettabile (frequenza di interrogazione necessaria è bas- sa). CD-ROM e HD sono attivati solo quando è esplicitamente richiesto dal sistema operativo, e non costantemente. Loverhead medio è quindi minore a quello da noi calcolato, assumendo che il dispositivo sia sempre attivo. Tuttavia, nel momento in cui il SO inizia una operazione sul dispositivo, questo deve essere interrogato costantemente perché non è possibile sapere a priori quando il dispositivo avvierà effettivamente il trasferimento. Soluzione 2
Ridurre overhead Idea : utilizzare un meccanismo per segnalare al processore quando un dispositivo di I/O richiede la sua attenzione=> le interruzioni. Problemi: 1.Evitare che il verificarsi di uninterruzione non provochi interferenze indesiderate con il programma interrotto. => Salvataggio del contesto 2.Una CPU può colloquiare con diversi devices, i quali devono essere gestiti tramite routine specifiche => necessità di identificare lorigine dellinterruzione 3. Gestire richieste concorrenti di interruzione o interruzioni che pervengono al processore mentre è già in corso uninterruzione (si dovrà interrompere la routine di servizio del primo interrupt?). =>definizione della gerarchia di priorità.
Fasi per la gestione dellinterrupt a.Salvare lo stato del processo in esecuzione; b.Identificare il programma di servizio relativo all'interruzione (driver); c.Eseguire il programma di servizio; d.Riprendere le attività lasciate in sospeso.
Il contesto su cui opera un programma è costituito da: Il registo PC: contiene lindirizzo dellistruzione da cui dovrà essere ripresa lesecuzione del programma interrotto Il registro di stato I registri del modulo ALU, compresi i bit di condizione, che possono contenere valori che il programma interrotto non ha terminato di elaborare. Gestendo linterruzione solo prima della fase di fetch, quando lesecuzione dellistruzione precedente è completamente conclusa, possiamo evitare di memorizzare sia questi registri, che lo stato del microprogramma. Quando si verifica uninterruzione avviene una commutazione dal contesto del programma interrotto a quello della routine di servizio. Analogamente il contesto del programma interrotto deve essere ripristinato una volta conclusa la routine di servizio. Context switch
Context switch 2 Occorre impedire che si verifichino altre interruzioni mentre sono in corso le operazioni di commutazione, pena possibili incongruenze tra i valori presenti nei registri di un contesto commutato solo parzialmente. Per fare ciò quando, al termine dellesecuzione di unistruzione, il segnale IRQ=0 assume valore 1, il flip-flop I viene settato a 0 via firmware. Inoltre il PD32 provvede a salvare nello stack lo SR e il PC. Infine, nel PC è caricato lindirizzo della routine di servizio del device che ha richiesto linterruzione. I CPU INT IRQ i+1 IRQ i IRQ i-1 Vcc Modulo interfaccia i-1 Modulo interfaccia i Modulo interfaccia i+1
PerifericaCPU INT IACK identificazione periferica Indirizzo 0 iniziale 1 prog.servizio 2 prima perife. 3 Indirizzo 4 iniziale 5 prog.servizio 6 seconda perife. 7 Indirizzo 4*i iniziale 4*i prog.servizio 4*i+2 perife. i-esima 4*i+3 PUSH … POP RTI Identificativo Periferica x 4 Riconoscimento interruzioni (IVN)
Introdurre una gerarchia per la gestione delle interruzioni consiste essenzialmente nel definire dei meccanismi per: Stabilire quale dispositivo debba essere servito per primo nel caso di richieste contemporanee. Consentire che il servizio di una interruzione possa essere a sua volta interrotto da dispositivi più prioritari. Tali meccanismi possono essere implementati via hardware (vedi controllore interruzione a priorità) o, nel caso in cui non via un supporto hardware dedicato, via software. Priorità nella gestione interrupt
PRIORITA CRESCENTE PROGRAMMA PRINCIPALE SERVIZIO RIPRESA SERVIZIO RIPRESA PROGRAMMA PRINCIPALE t LIVELLO 0 LIVELLO 1 LIVELLO 2 INTERR. FINE IR0IR2IR1 SERVIZIO FINE Priorità tra dispositivi
Gestire la gerarchia di priorità delle interruzioni via software Implementazione gerarchia
1) Stabilire quale dispositivo debba essere servito per primo nel caso di richieste contemporanee. Soluzione Hardware: si utilizza il segnale di IACK propagato in daisy-chain per il riconoscimento dellorigine dellinterruzione. Così facendo si introduce una priorità che è funzione della distanza dal processore (la periferica più vicina ha priorità max). Una soluzione alternativa implementabile via software è di interrogare una dopo laltro le periferiche (polling). Lordine di interrogazione definisce la priorità nella gestione delle interruzioni. Gestione priorità / 1
2) Consentire che il servizio di una interruzione possa essere a sua volta interrotto da dispositivi più prioritari. Abbiamo già studiato una soluzione hw a tale scopo. Una possibile alternativa implementabile completamente tramite software prevede che: 1.Ogni routine di servizio che prevede di essere interrotta (di priorità non max) debba rendere il processore nuovamente interrompibile (SETI). 2.Per inibire i dispositivi a priorità minore, prima della SETI devono essere opportunamente mascherati i flip-flop IM dei devices presenti, cosi da stabilire da quali di questi, la routine di servizio possa essere interrotta. 3.Lo stato di interrompibilità, definito dai valori dei registri IM dei dispositivi al momento dellinterruzione, fa parte del contesto del programma e va ripristinato prima della RTI. 4.Prima di rendere interrompibile il processore deve essere rimossa la causa dellinterruzione stessa, per evitare lo stack overflow. Si può raggiungere questo scopo impedendo alla periferica di generare altre interruzioni con CLRIM. Anche resettando il flip-flop di status (START,CLEAR), rimuoviamo la causa dellinterruzione, ma non inibiamo la periferica a generarne altri. Di conseguenza possono sorgere problemi nel caso in cui un driver sia interrotto da una nuova richiesta di interruzione a cui è associato lo stesso driver! Conflitti sui dati e sul codice!
2) Consentire che il servizio di una interruzione possa essere a sua volta interrotto da dispositivi più prioritari. 5) Il ripristino del contesto deve avvenire con il processore non interrompibile, per evitare le incongruenze che potrebbero sorgere a causa di una commutazione incompleta. Ad esempio, si consideri il driver periferica di priorità media (interrompibile solo da device con priorità alta e non da device con priorità bassa) …; codice del driver per device con priorità media SET I; il processore è interrompibile … ; fine codice, inizio ripristino contesto setim dev_low_priority; pop …; altre op. ripristino contesto pop …; rti Se arriva uninterruzione da parte del device a bassa priorità, questa viene subito servita ed è violata la gerarchia di priorità! Gestione priorità / 3
3 rilevatori di movimento sono connessi al PD32. Quando viene rilevato un movimento, i sensori generano una richiesta di interruzione. Si vuole servire le interruzioni provenienti dai sensori con la seguente priorità : Sensore0 Sensore1 Sensore2 Priorità crescente Driver sensore 0: SETIM Sensore1 SETIM Sensore2 CLRIM Sensore0 SETI …. CLRI SETIM Sensore0 RTI Driver sensore 1: SETIM Sensore2 CLRIM Sensore1 CLRIM Sensore0 SETI …. CLRI SETIM Sensore0 SETIM Sensore1 RTI Driver sensore 2: …. RTI Gestione priorità / Esempio
Interruzioni & PD32
Riassumendo interruzioni PD32 Periferica attiva il segnale di interruzione sul Control Bus di I/O Prima della fase di fetch il PD32 si preoccupa di controllare se ci sono richieste pendenti di interruzione Legge lIVN della periferica che ha lanciato linterruzione, lo moltiplica per 4 ed accedere allarea di memoria in cui è memorizzata la routine di servizio (driver) Allattivazione del driver viene fatto un cambio di contesto, salvando SR e PC. Viene effettuata listruzione CLRI inibendo la ricezione di eventuali nuove interruzioni Allesecuzione del comando RTI al termine della routine viene fatta automaticamente un ripristino di PC e SR
Progettiamo la nuova periferica per le interruzioni tenendo presente il F/F di mascheramento
Generica interfaccia di Input
Scambio di dati da periferica di input e periferica di output Si vuole realizzare lo scambio dei dati, in formato byte, tra una periferica di input e una di output. Lo scambio avverrà attraverso luso di un buffer, di un byte, allocato in RAM. La periferica di input caricherà il buffer con il dato prodotto, quella di output lo scaricherà consumandolo. Si deve inoltre impedire che la periferica di input possa inviare un nuovo dato, fino a che il buffer non sarà vuoto. Analogamente la periferica di output non potrà consumare dati se il buffer è vuoto. Esercizio Interruzioni
Interrupt da INPUT device Interrupt da OUTPUT device Salva R0 nello stack Buffer pieno si Inibisce INPUT dev CLRIM input Ripristina contesto ed esci Setta flag: buffer pieno no INB input,buffer START input Output device ha IM abilitato? si no Ripristina contesto ed esci SETIM output Salva R0 nello stack Buffer vuoto si no Inibisce OUTPUT dev CLRIM output Ripristina contesto ed esci Resetta flag: buffer vuoto OUTB buffer,output START output INPUT device ha IM abilitato? si no Ripristina contesto ed esci SETIM input
; PROGRAMMA DIMOSTRATIVO SULL'USO DEI DEVICES ; Una periferica di input invia dati in un buffer di 1byte con il meccanismo degli ; interrupt, la periferica di output preleva il dato dal suddetto buffer ; Nel simulatore è necessario installare due periferiche: ; INPUT:I/O=I, ind=30h, IVN=2 ; OUTPUT:I/O=O, ind=56h, IVN=7 org 400h ;INIZIO PROGRAMMA inputequ 30h;indirizzo periferica input outputequ 56h;indiririzzo periferica output flagdb 0;flag =0 buffer vuoto, flag=1 buffer pieno bufferequ 500h;indirizzo buffer di scambio code;inizio istruzioni seti;abilita PD32 ad accettare interruzioni setim input;abilita periferica di input ad accettare interruzioni setim output;abilita periferica di output ad accettare interruzioni start input; avvio produzione del dato start output; avvio consumo del dato main: jmp main ; progr. Principale = loop infinito
;DRIVER DI INPUT ;Invia dati al buffer se questo e' pieno pone in attesa la periferica ;di input 0->IM, sblocca (se in attesa) la periferica di output 1->IM driver 2, 600h ;Il driver della periferica con IVN=2 ;inizia dall'ind. 600h pinput:push r0;salva contenuto di R0 movb flag,r0;carica flag in R0 cmpb #1,r0;controlla se buffer pieno jz inibisci;se pieno pongo in attesa la periferica di input accetta:;altrimenti invia dato movb #1,flag;pongo il flag=1 (buffer pieno) inb input,buffer;carico dato nel buffer start input;abilito device a generare un nuovo dato jnim output,sbloccato;se periferica di output e' in attesa la sblocco jmp fineinp;termina inibisci: clrim input;pone perif. input in attesa (buffer pieno) fineinp: pop r0;fine driver rti;ritorno da interruzione sbloccato:setim output;sblocco periferica output jmp fineinp ;FINE DRIVER DI INPUT
;DRIVER DI OUTPUT ;Preleva dati dal buffer se questo e' vuoto pone in attesa la periferica ;di output 0->IM, sblocca (se in attesa) la periferica di input 1->IM driver 7,700h;Il driver della periferica di IVN=7 ;inizia dall'indirizzo 700h poutput:push r0;salva contenuto di R0 movb flag,r0;carica flag in R0 cmpb #0,r0;il buffer e' vuoto? jz blocca;se vuoto pongo in attesa la periferica di output consuma: outb buffer,output;altrimenti invio dato alla periferica di output movb #0,flag;pongo flag=0 (buffer vuoto) start output;abilito perif. output a consumare il dato jnim input,sblocca;se perif. di input 'in attesa' la sblocco jmp esci;termina blocca:clrim output;blocco perif. output (buffer vuoto) esci:pop r0;termina prog. rti;ritorna da interruzione sblocca:setim input;sblocco input jmp esci ;FINE DRIVER DI OUTPUT end;FINE PROGRAMMA
Costo aggiuntivo di unoperazione di I/O gestita tramite interruzioni Come nel precedente esempio, si ha un processore a 2GHZ e un hard disk che trasferisce dati in blocchi da 4 longwords con un throughput max di 16 MB/s. Si ipotizzi che il costo aggiuntivo per ogni trasferimento, tenendo conto delle interruzioni, è pari a 500 cicli di clock. Si trovi la frazione del processore utilizzata nel caso in cui lhard disk stia trasferendo dati per il 5% del suo tempo. Frequenza di interrogazione=16 Mb/sec =1 M=10 6 accessi/sec 16 byte/accesso Cicli per secondo spesi= 500 * 10 6 % processore utilizzato= 500 * 10 6 = 25% 2000 * 10 6 Frazione del processore utilizzata in media=25 % * 5 %= 1,25%
La gestione dellI/O tramite interrupts solleva il processore dal peso di attendere il verificarsi degli eventi di I/O. Il costo aggiuntivo può essere comunque intollerabile se i dispositivi con cui si interagisce hanno a disposizione una elevata larghezza di banda.
Un esempio già noto… Una stanza e monitorata da 4 sensori di temperatura, i quali sono pilotati da un PD32. Questultimo controlla costantemente che il valor medio della temperatura rilevata nella stanza sia compreso tra i valori [Tmin-Tmax]. Nel caso in cui il valor medio della temperatura non cada in tale intervallo, il microprocessore inviera un segnale di allarme su unapposita periferica (ALARM). Il segnale dallarme utilizzato e il valore 1 codificato con 8 bit. Se la temperatura ritorna allinterno dellintervallo [Tmin-Tmax], la CPU invia sulla periferica il valore 0. I sensori ritornano la temperatura misurata come un numero intero ad 8 bit, usando i decimi di gradi Celsius come unita di misura. Scrivere il codice assembly per il controllo dei sensori di temperatura e della periferica di allarme… utilizzando il meccanismo delle interruzioni vettorizzate (piuttosto che il polling + busy wait).
Il codice (1) org 400h ;INIZIO PROGRAMMA sensore1 equ 0h; indirizzo sensore1 sensore2 equ 1h; indirizzo sensore2 sensore3 equ 2h; indirizzo sensore3 sensore4 equ 3h; indirizzo sensore4 alarm equ 4h; indiririzzo periferica allarme lowbound equ 200; T-min espresso in decimi di gradi Celsius upbound equ 300; T-min espresso in decimi di gradi Celsius media dl 0; valore medio della temperatura rilevato baseadd equ 2000h; buffer contenente la temperatura misurata device dl 0; indirizzo ultimo sensore che ha acquisito switch db 0; valore da spedire sulla periferica dallarme state db 0; stato allarme (0=off, 1=on) code ;inizio istruzioni main: ;... jsr init ;... loop:jmp loop ;trucco per simulare il codice sul PD32, la periferica è libera per eventuali elaborazioni
Il codice (2) ; subroutine di inizializzazione delle periferiche e avvio acquisizione init: push r0 push r1 ; calcola il centro dell'intervallo [Tmin-Tmax]... movl #lowbound, R0; addl #upbound, R0 ; asrl #1, R0 ; e lo memorizza in R0 movl #baseadd,R1 movl R0, (R1); aggiorna i buffer dei 4 movl R0, 4(R1); sensori con il valor medio movl R0, 8(R1); dellintervallo movl R0, 12(R1); movl R0, media; inizializza la media movb #0,state ; state memorizza lo stato (IN=0, OUT=1) SETIM sensore1 ; SETIM sensore2 SETIM sensore3 SETIM sensore4; abilita i sensori a inviare interruzioni CLRIM alarm; blocca la periferica dallarme che al momento non serve SETI; abilita il processore a ricevere interruzioni
Il codice (3) START sensore1; START sensore2; START sensore3; START sensore4; avvia lacquisizione dei dati dai sensori di temp. pop r1 pop r0 ret ; fine subroutine init ; DRIVERS driver 0, 1600h ; periferica con IVN 0 ha driver allocato a partire dallind 1600h movl #sensore1, device jsr GET rti driver 1, 1650h movl #sensore2, device jsr GET rti driver 2, 1700h …; … e 3
Il codice (4) driver 4, 1800h OUTB SWITCH, alarm ;invia il valore di switch sul buffer di alarm start alarm;avvia il consumo del dato clrim alarm;disabilita ulteriori interrupts della periferica rti ; SUBROUTINE GET: ACQUISIZIONE DATI DALLA PERIFERICA IL CUI IND. E ; E' SPECIFICATO NELLA VARIAB. DEVICE GET:PUSH r0 push r4 push r5 movl #baseadd, R0 movl device,r5 asll #2,r5 ; r5=device*4 ADDL r5, R0 ; r0=baseadd+device*4 asrl #2,r5 ;ripristina R5 alladdress del device INL r5, (R0); preleva il valore e lo mette in RAM nel corrispondente buffer START r5 ; avvia nuova acquisizione JSR NEWMEDIA
Il codice (5) MOVL media, R5 ; carico la media aggiornata in R5 movb state, R4 CMPL #upbound, R5 JNC OUT; upbound <= R5 CMPL #lowbound, R5; JC OUT;lowbound > R5 ; altrimenti siamo nell'intervallo [TMIN-TMAX]... CMPb #0, R4; verifico se lo stato era IN=0 o OUT=1 JNZ eraout; exit:pop r5 pop r4 pop r0 RET eraout: MOvb #0,switch SETIM alarm movb #0, state jmp exit OUT:CMPb #0, R4; verifico se lo stato era IN=0 o OUT=1 JZ erain; jmp exit
Il codice (6) erain: MOVb #1,switch SETIM alarm movb #1, state jmp exit ; aggiorna la media in base ai valori presenti nelle 4 longwords a partire da baseadd NEWMEDIA: PUSH R0 PUSH R1 MOVL #baseadd,R1 XORL R0,R0 ADDL (R1),R0 ADDL 4(R1), R0 ADDL 8(R1), R0 ADDL 12(r1), R0 ASRL #2, R0 MOVL R0, media POP R1 POP R0 RET end