Interfacce di input-output - strobing, handshaking, interrupt e DMA
In questa pagina 5
I dispositivi di input/output (I/O) servono a comunicare con l'esterno. Ce ne sono moltissimi, con velocità e caratteristiche diverse, da pochi byte al secondo a molte decine di MB al secondo. Per i moduli di I/O dal punto di vista del calcolatore: Moduli di input-output e input-output programmatoPerché servono i moduli di I/O; funzioni del modulo (controllo, comunicazione, buffer, errori) e registri di stato, controllo e dati; I/O mappato in memoria e isolato con esempi; I/O programmato con attesa attiva e suo costo; confronto delle tre tecniche.Moduli di input-output e input-output programmato →, InterruptClassi di interruzioni; I/O guidato da interrupt; sequenza hardware e software di gestione con salvataggio del contesto sullo stack; identificazione della sorgente (linee multiple, polling, daisy chain, vettore); priorità e interruzioni annidate; eccezioni e modi in ARM.Interrupt →, Accesso diretto alla memoria (DMA)Modulo DMA e informazioni che riceve dalla CPU; trasferimento a blocco con un solo interrupt finale; furto di cicli e modalità a burst, punti in cui la CPU può essere sospesa; configurazioni del bus; canali e processori di I/O; confronto quantitativo con l'I/O a interrupt.Accesso diretto alla memoria (DMA) →, Bus e interconnessioneBus di sistema diviso in linee dati, indirizzi e controllo; ampiezza del bus e spazio di indirizzamento; arbitraggio; bus singolo e gerarchie di bus multipli; temporizzazione sincrona e asincrona; interconnessioni punto a punto.Bus e interconnessione →.
Alcune periferiche
Tastiera. Data rate bassissimo (pochi byte/s). Il tasto premuto si individua con una matrice di scansione: premere un tasto collega una riga a una colonna; un microcontrollore scansiona periodicamente le righe (porta una riga a 1 e controlla se compare un 1 su qualche colonna) con un decoder e un multiplexer; i segnali di controllo al momento del rilevamento identificano il tasto. Si inviano make code (premuto) e break code (rilasciato). La scansione è ripetuta centinaia di volte al secondo: non si perdono pressioni.
Hard disk. Dischi magnetizzati in rapida rotazione; i bit sono memorizzati dalla direzione di magnetizzazione di una piccola area e organizzati in tracce e settori; una testina mobile lungo il raggio legge e scrive. Prestazioni:
- seek time: tempo per portare la testina sulla traccia;
- rotational delay: tempo perché il disco ruoti e metta il dato sotto la testina (in media mezzo giro);
- controller time: tempo del controllore elettronico per elaborare i dati e fornirli all'interfaccia;
- la somma dà il disk access time; i dati si leggono in blocchi contigui perché muovere la testina fa perdere tempo (si usa una memoria intermedia).
Esempio numerico (valori illustrativi). Disco a giri/min: un giro dura ms, il ritardo rotazionale medio è mezzo giro, ms. Con seek ms, controller ms e trasferimento di KB a MB/s ( ms): tempo di accesso ms.
Display a cristalli liquidi (LCD). Formato da pixel indipendenti, ciascuno con tre sottopixel RGB dotati di filtro; una sorgente di luce sta sotto i pixel; i cristalli liquidi, orientati da un campo elettrico, bloccano o lasciano passare la luce, mescolando i tre colori. Data rate di centinaia di MB/s per immagini definite e illusione del movimento; l'elettronica di controllo somiglia a quella di una DRAM (righe scritte consecutivamente, intero pannello rinfrescato in meno di s).
Interfacce di I/O
Servono perché:
- alcune periferiche hanno funzionamento elettromeccanico, molto lontano da quello di una CPU interamente elettronica;
- la velocità di trasferimento della periferica è diversa dalla frequenza di clock della CPU: serve un meccanismo di sincronizzazione;
- codici e formati dei dati possono differire da quelli di CPU e memoria;
- ogni periferica ha particolarità e va controllata senza disturbare le altre.
Collegamento alla CPU. Un unico bus collega più periferiche. Per comunicare con una periferica la CPU mette il suo indirizzo sull'address bus; ogni interfaccia ha un decoder che monitora le linee indirizzo; quando riconosce il proprio indirizzo attiva la propria interfaccia (Decoder, encoder e priority encoderUn decoder $n$-to-$m$ ($m\le2^n$) converte un ingresso binario a $n$ bit in un'uscita 1-hot (un solo 1, nella posizione indicata): le sue uscite sono i mintermini degli ingressi, realizzati con $m$ AND; per decoder grandi si usa l'approccio gerarchico (costo in ingressi: 3-to-8 = 27, 6-to-64 = 182) e un enable. Ogni funzione = decoder + OR dei suoi mintermini. L'encoder fa l'operazione inversa (1-hot $\to$ binario) ma sbaglia con più ingressi a 1 o tutti a 0: il priority encoder risolve con una priorità e un'uscita V (valid).Decoder, encoder e priority encoder →).
Memory-mapped I/O e isolated I/O. La CPU comunica anche con la memoria:
- memory-mapped: un unico bus comune di dati, indirizzi e controllo per memoria e I/O; gli indirizzi di I/O e di memoria devono essere diversi;
- isolated I/O: il bus indirizzi è comune ma le linee di controllo sono separate per memoria e I/O; gli indirizzi assegnati ai due sono indipendenti (le linee di controllo dicono con chi si comunica).
Controllo della trasmissione
La comunicazione tra CPU e interfacce è tipicamente asincrona (clock diversi): servono segnali di controllo e sincronizzazione.
- Strobing: un segnale (strobe) indica che il destinatario è pronto a ricevere (destination-initiated) o che il mittente ha inviato il dato (source-initiated). Non c'è conferma della ricezione.
- Handshaking ("stretta di mano"): la comunicazione è confermata da entrambi i lati; richiede un segnale in più ma è più robusto (meno sensibile ai problemi): il mittente segnala "dato valido", il destinatario risponde "dato accettato" e solo dopo si procede.
Comunicazione seriale e parallela
- Parallela: più bit trasmessi contemporaneamente; più veloce ma più complessa e costosa (molte linee da tenere sincronizzate); per alta velocità e brevi distanze.
- Seriale: un bit alla volta; più lenta per linea ma meno costosa (meno linee). Aumentare la velocità su una linea è più facile che su molte sincronizzate: tendenza crescente alle comunicazioni seriali (dischi da PATA a SATA).
Direzione: simplex (una sola direzione), half-duplex (entrambe, una alla volta), full-duplex (entrambe anche insieme). Trasmissione sincrona (stesso clock per trasmettitore e ricevitore, eventualmente con segnali periodici di sincronismo; il sincronismo può essere estratto dai dati) o asincrona (clock diversi).
Il controllore della tastiera usa comunicazione seriale sincrona tra tastiera e interfaccia, e comunica con la CPU via interrupt.
USB (Universal Serial Bus)
Trasmissione seriale a pacchetti: più dispositivi trasmettono sullo stesso bus in pacchetti diversi. Elementi: hub (interfaccia con controllo e funzioni di ripetizione), device, dispositivi composti (hub + device). Le transazioni sono fatte di pacchetti di vario tipo: in una transazione di output (dati dal computer al dispositivo) un out packet e un data packet provengono dal computer, un handshake packet dal dispositivo.
Codifica NRZI (Non-Return-to-Zero Inverted), per ottenere fronti utili alla sincronizzazione: uno 0 si trasmette con una transizione del livello (da 1 a 0 o da 0 a 1); un 1 con il livello invariato. Se ci sono troppi 1 consecutivi (più di 6) non ci sono transizioni: dopo sei 1 si inserisce uno 0 (bit stuffing). Esempio, con livello iniziale alto: i bit danno i livelli (si inverte a ogni 0); la sequenza viene trasmessa come .
Modalità di trasferimento
I/O programmato
Il trasferimento è iniziato e controllato da un'istruzione del programma. La CPU controlla costantemente lo stato della periferica in un ciclo di istruzioni, il busy-wait, e non può fare altro; la periferica è di solito molto più lenta, quindi si sprecano molti cicli macchina. Sistema semplice ma inefficiente.
Esempio. Periferica a byte/s: un byte ogni ms. Se la CPU impiega ns per controllare lo stato, tra un trasferimento e il successivo lo controlla volte, quasi tutte inutilmente.
Interrupt
Il trasferimento non è più monitorato dalla CPU ma da un'interfaccia che genera un segnale, l'interrupt, quando i dati sono disponibili. Nel frattempo la CPU fa lavoro utile; quando arriva l'interrupt, interrompe l'operazione corrente, esegue un programma di servizio per processare i dati e ritorna al compito iniziale. L'interrupt è un segnale di uscita della periferica e di ingresso della CPU.
- Vectored interrupt: la periferica fornisce la locazione (vector address) della routine di servizio; non-vectored: locazione fissa.
- Più periferiche: come identificare la sorgente? Possibilità di richieste contemporanee: serve una strategia di priorità: tecniche software (la CPU interroga le periferiche dopo un interrupt) o hardware (seriale/daisy chain, o parallela).
- Daisy chain: la priorità è determinata dall'ordine nella catena di collegamento delle periferiche; il primo dispositivo che ha generato l'interrupt trasmette il suo vector address e viene servito dalla CPU. Le periferiche si propagano il permesso lungo la catena, per cui la CPU non determina la periferica a priorità più alta (lo fa la catena) e due interrupt non possono essere gestiti in parallelo.
- Priorità parallela: un encoder con priorità (Decoder, encoder e priority encoderUn decoder $n$-to-$m$ ($m\le2^n$) converte un ingresso binario a $n$ bit in un'uscita 1-hot (un solo 1, nella posizione indicata): le sue uscite sono i mintermini degli ingressi, realizzati con $m$ AND; per decoder grandi si usa l'approccio gerarchico (costo in ingressi: 3-to-8 = 27, 6-to-64 = 182) e un enable. Ogni funzione = decoder + OR dei suoi mintermini. L'encoder fa l'operazione inversa (1-hot $\to$ binario) ma sbaglia con più ingressi a 1 o tutti a 0: il priority encoder risolve con una priorità e un'uscita V (valid).Decoder, encoder e priority encoder →) determina la priorità; le periferiche si possono mascherare (disabilitare) con un mask register.
DMA (Direct Memory Access)
Spesso i dati di una periferica vanno trasferiti in memoria; un trasferimento massiccio da una periferica veloce (un disco) tiene occupata la CPU a lungo. Lasciando che la periferica trasferisca i dati in memoria senza coinvolgere la CPU, il sistema è molto più efficiente: è il DMA. Il controllore DMA prende il controllo dei bus e gestisce direttamente il trasferimento dal dispositivo di I/O alla memoria.
La CPU supporta il controllore con due segnali:
- Bus Request (BR): il controllore DMA chiede il permesso di usare il bus;
- Bus Granted (BG): la CPU concede il bus e si impegna a non usarlo.
Il controllore contiene un registro indirizzo (indirizzo di memoria da leggere o scrivere, incrementato a ogni word trasferita) e un contatore delle word. Il controllore DMA è visto dalla CPU come una periferica (la CPU lo programma con indirizzo e quantità di dati); richiede o cede il bus in base alla quantità di dati e alla velocità della periferica; alla fine genera un interrupt per segnalare il termine del trasferimento.
| I/O programmato | interrupt | DMA | |
|---|---|---|---|
| chi controlla | CPU (polling) | interfaccia (segnale) | controllore DMA |
| CPU durante l'attesa | occupata (busy-wait) | libera | libera |
| adatto a | periferiche lente, semplici | eventi non frequenti | grandi blocchi di dati |
Errori comuni
- Credere che lo strobing garantisca la ricezione: manca la conferma; la conferma è l'handshaking.
- Dire che la CPU stabilisce la priorità in una daisy chain: la stabilisce l'ordine nella catena.
- Confondere memory-mapped (indirizzi condivisi con la memoria) e isolated I/O (linee di controllo separate).
- Dimenticare l'interrupt finale del DMA.
- Dire che l'interrupt è un segnale in ingresso alla periferica: è un'uscita della periferica e un ingresso della CPU.
Versione ripasso
- Periferiche: tastiera (matrice di scansione), disco (seek + rotational delay + controller access time; es. ms), LCD (pixel RGB, centinaia di MB/s). Interfacce: sincronizzazione, codici diversi, controllo.
- Bus unico + decoder di indirizzo; memory-mapped (indirizzi condivisi) vs isolated I/O (controlli separati).
- Strobing (senza conferma, source/destination-initiated) vs handshaking (conferma, robusto, un segnale in più). Seriale (meno linee, tendenza) vs parallela; simplex/half/full duplex; sincrona/asincrona. USB: pacchetti; NRZI: 0 transizione, 1 livello fisso, bit stuffing dopo sei 1.
- I/O programmato: busy-wait; es. 100 B/s, controllo 100 ns: controlli per byte.
- Interrupt: uscita periferica, ingresso CPU; vectored/non; priorità: software, daisy chain (ordine nella catena; no parallelo), parallela (encoder + mask).
- DMA: controllore prende il bus (BR/BG), registro indirizzo incrementato, interrupt finale (Cache e memoria virtuale - mappatura e tabelle delle pagineLe memorie sono in gerarchia (SRAM piccole e veloci, DRAM più grandi e lente, dischi enormi e lenti) perché la CPU riutilizza dati vicini nel tempo e nello spazio (località). Cache hit/miss, hit rate; mappatura diretta (indice = bit meno significativi, tag = bit alti), completamente associativa (tag = indirizzo intero, confronto in parallelo con memoria associativa), a $k$ vie (un blocco può stare in $k$ locazioni di un solo insieme). La memoria virtuale espone a ogni programma l'intera memoria con una traduzione indirizzo virtuale $\to$ fisico a pagine (tabella delle pagine con bit valid, dirty, used); il TLB accelera la traduzione; page fault = pagina da recuperare dal disco.Cache e memoria virtuale - mappatura e tabelle delle pagine →).
- Errori: strobing con conferma; priorità decisa dalla CPU; interrupt in ingresso alla periferica.