CALCOLATORI ELETTRONICI II
• BUS I/O PD32
• POLLING / BUSY WAITING
• PROGETTAZIONE INTERFACCE
INPUT / OUTPUT
I/OBus PD32
I/O Address bus fatto da 8 bit
Quante periferiche possiamo
collegare al massimo?????
Istruzioni I/O PD32 Classe 7
TIPO
0
CODICE
INs
OPERANDI
dev, D0
CNZV P I
------
COMMENTO
Il dato contenuto nel
buffer del device dev è
trasferito nella
destinazione D0.
dev ->d0
1
OUTs
S,dev
------
Il dato sorgente S
viene trasferito nel
buffer del device dev.
S->dev
2
START
dev
------
3
JR
dev, D1
------
4
JNR
dev, D1
------
Viene azzerato il flipflop STATUS del dev e
viene avviata
l'operazione.
Se STATUS=1 salta
alla destinazione D1
Se STATUS=0 salta
alla destinazione D1
Per la destinazione D0 sono ammessi tutti i tipi di indirizzamento tranne quello immediato.
Per la destinazione D1 sono ammessi tutti i tipi di indirizzamento tranne quello con registro e
immediato.
Formato istruzioni I/O
Per l’operando dev sono ammessi solo due modi di indirizzamento: diretto
con registro ed assoluto. Per la codifica di questo campo sono usati i campi
I/O e k.
Il campo I/O può assumere solo due valori:
• 01 => indica che il contenuto di k è l’indirizzo del device
• 10 => indica che l’indirizzo del device è contenuto nel registro generale
specificato dai primi 3 bit del campo k
Poichè i campi modo sorgente e sorgente sono inutilizzati, la sorgente S
viene specificata nei campi modo destinazione e destinazione.
CLASSE
111
31
TIPO
29 28
24 23
k
I/O
s
16 15 14 13 12 11
-----
-----
9 8
MODO
6 5
DEST
32
0
Interazione con le periferiche
Esistono due tipologie di interazione con le
periferiche:
• Sincrona
• Asincrona
In questa parte faremo focus sull’interazione
sincrona, successivamente verrà analizzata anche
quella asincrona.
Interazione Sincrona
Come tutte le comuni interazioni sincrone, il software si preoccupa
di testare direttamente lo stato della periferica. L’architettura deve
quindi dare la possibilità al processore di poter sapere in ogni istante
la situazione attuale della periferica. Le tecniche più usare di
interazione sincrona sono:
• Busy Waiting
• Polling
sei pronta??
si /no
pd32
periferica 1
Busy Waiting
Idea che sta dietro all’implementazione del busy waiting:
Loop:
Salta a “Loop” se la periferica non è pronta
Si rimane in attesa attiva che la periferica abbia terminato.
La CPU è impegnata al 100% in questo controllo.
Busy Waiting / Implementazione
Implementazone del busy waiting in assembly pd32:
Aspetta: JNR Device, Aspetta
L’istruzione JNR (Jump Not Ready) salta all’etichetta
“Aspetta” se Device non è pronto, altrimenti se Device è
Ready passiamo alle istruzioni successive.
Polling
verifica circolare se ogni
DEVICE è pronto ad interagire
I/O AB
I/O DB
I/O CB
PD32
DEV 1
DEV 2
DEV 3
DEV 4
Polling / Implementazione
Implementazone del polling in assembly pd32:
POLL1: JR D1, Op_Dev_1
POLL2: JR D2, Op_Dev_2
POLL3: JR D3, Op_Dev_3
JMP POLL1
Ciclicamente il software interroga le periferiche per sapere
se qualcuna è pronta ad interagire. Altrimenti va avanti
fino a che non arriva alla fine delle periferiche da
controllare e con una jmp non condizionata torna sulla
prima da controllare.
Polling vs Busy Waiting
Che succede se nell’implementazione del polling esiste
solo una periferica da interrogare??
Il busy waiting può essere interpretato come caso
particolare del polling.
POLL1: JR D1, Op_Dev_1
POLL2: JR D2, Op_Dev_2
POLL3: JR D3, Op_Dev_3
JMP POLL1
Progettazione Periferiche
Progettiamo la nostra interfaccia hardware con lo scopo di
fornire i componenti e le interconnessioni di supporto alla
“semantica” della periferica (ovvero cosa deve fare la
periferica).
1. Si deve poter leggere e/o scrivere sulla periferica
2. Si deve poter selezionare la periferica tra tutte quelle
collegate al bus
3. Si deve poter interrogare la periferica per sapere se ha
completato il suo lavoro
4. Si deve poter avviare la periferica
Classico protocollo alto livello
In maniera molto astratta si dovranno eseguire almeno
queste operazioni per interagire con le periferiche:
1. Aspettare che la periferica sia disponibile
2. Avviare la periferica
3. Scrivere / Leggere i dati d’interesse
Interfaccia di Input
I/O programmato – PROTOCOLLO DI HANDSHAKING IMPLEMENTATO A
SOFTWARE
I/O AB
I/O DB
I/O CB
PD32
I/O RD
START
WAIT
READY
“0”
STARTD
SELECT
REG
SCA
O.C.
R
Q
STATUS
S
Q
COMPLETE STARTDEV
SCO
Interfaccia di Input / Impl
1.
2.
3.
4.
Aspettare finché la periferica DeviceIn non è disponibile
Avvio la periferica così che possa produrre informazioni
Aspetto la sua terminazione
Leggo il risultati scquisiti.
Aspetta1:
JNR DeviceIN, Aspetta1
START DeviceIN
Aspetta2:
JNR DeviceIN, Aspetta2
INB DeviceIN, R0
Cosa implementa??
Busy Waiting / Polling??
Interfaccia di Output
I/O programmato – PROTOCOLLO DI HANDSHAKING IMPLEMENTATO A
SOFTWARE
PD32
I/O WR
I/O AB
I/O DB
I/O CB
START
READY
STARTD
DEC
SELECT
REG
SCA
O.C.
R
Q
STATUS
S
Q
COMPLETE STARTDEV
SCO
Interfaccia di Output / Impl
1.
2.
3.
4.
Aspettare finché la periferica DeviceOut non è disponibile
Scrivi il dato sul registro di interfaccia
Avverto la periferica che può considerare un nuovo dato.
Aspetto la sua terminazione
Aspetta1:
JNR DeviceOUT, Aspetta 1
OUT R0, DeviceOUT
START DeviceOUT
Aspetta2:
JNR DeviceOUT, Aspetta2
Cosa implementa??
Busy Waiting / Polling??
Interfaccia di Output / Impl
1.
2.
3.
4.
Aspettare finché la periferica DeviceOut non è disponibile
Scrivi il dato sul registro di interfaccia
Avverto la periferica che può considerare un nuovo dato.
Aspetto la sua terminazione
Aspetta1:
JNR DeviceOUT, Aspetta 1
OUT R0, DeviceOUT
START DeviceOUT
Aspetta2:
JNR DeviceOUT, Aspetta2
Esercizio Busy Waiting
Dato questo frammento di codice implementante il codice
di una funzione chiamante, definire la subroutine IN_AD1
che legge 100 dati dalla periferica di input con indirizzo
AD1 e li memorizza in un vettore a partire dall’indirizzo
1280.
Si noti che i dati sono già nei registi R0 ed R1
…
MOVL #100, R0
MOVL #1200, R1
JSR IN_AD1
; numero di dati da acquisire
; ind.dell’area di memoria
Soluzione Busy Waiting
…
MOVL #100, R0 ; numero di dati da acquisire
MOVL #DATI, R1 ; ind.dell’area di memoria
JSR IN_AD1
…
IN_AD1: PUSH R0
; salv. registri usati
PUSH R1
PUSH R2
IN_1:
JNR AD1, IN_1
; attende che AD1 sia pronto
IN_2:
START AD1
;avvia l’acquisizione di un dato
IN_3:
JNR AD1, IN_3
; attende che il dato sia stato prodotto
INW AD1, R2
; prelievo del dato e….
MOVW R2, (R1)+ ; … suo trasferimento in memoria
SUBL #1, R0
; decremento del contatore
JNZ IN_2
; acquisizione di un altro dato se non si è azzerato ; il contatore
POP R2
; ripristino dei registri usati
POP R1
;
POP R0
;
RET
; ritorno al programma chiamante
Esercizio Polling
Dato questo frammento di codice implementante il codice
di una funzione chiamante, definire la subroutine IN_AD1
che legge 100 dati da quattro periferiche di input con
indirizzo AD1, AD2, AD3, AD4 e li memorizza in un
vettore a partire dall’indirizzo 1280. I 100 dati possono
essere letti non necessariamente rispettando l’ordine delle
periferiche, ovvero 25 da AD1, 25 da AD2…….
Si noti che i dati sono già nei registi R0 ed R1
…
MOVL #100, R0
MOVL #1200, R1
JSR IN_AD1
; numero di dati da acquisire
; ind.dell’area di memoria
Soluzione Polling
IN_AD1: PUSH R0
PUSH R1
PUSH R2
POLL1: JR AD1, IN_1
POLL2: JR AD2, IN_2
POLL3: JR AD3, IN_3
POLL4: JR AD4, IN_4
JMP POLL1
…
IN_i:
START ADi
WAIT: JNR ADi, WAIT
INW ADi, R2
MOVW R2, (R1)+
SUBL #1, R0
JZ EXIT
JMP POLL_i+1
EXIT:
POP R2
POP R1
POP R0
RET
; salv. registri usati
; attende che AD1 sia pronto
; avvia l’acquisizione di un dato
; attende che il dato sia stato prodotto
; prelievo del dato e….
; … suo trasferimento in memoria
; decremento del contatore
; continua a interrogare le altre periferiche
; ripristino dei registri usati
;
;
; ritorno al programma chiamante
Esercizio
Una stanza e’ monitorata da 4 sensori di temperatura, i quali sono
pilotati da un PD32. Quest’ultimo 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 un’apposita periferica, detta ALARM. Il segnale
d’allarme utilizzato e’ il valore 1 codificato con 8 bit. Se la
temperatura ritorna all’interno dell’intervallo [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.
Macchina a stati finiti
newTemp,T_media NON in [Tmin-Tmax] /
Alarm_ON
T_media in
[Tmin-Tmax]
newTemp,
T_media in [Tmin-Tmax] /
-
Legenda per le transizioni:
Input, Condizione / Output
newTemp,
T_media NON in [Tmin-Tmax]/
-
T_media fuori da
[Tmin-Tmax]
newTemp,T_media in [Tmin-Tmax] /
Alarm_OFF
Diagramma di flusso
T_media=Ts1=Ts2=Ts3=Ts4=
= (Tmin+Tmax)/2
Stato=IN_RANGE
controlla dev.succ
dev i
ready?
NO
SI
Input da dev_i: new_T_si
Stato=OUT
Stato=IN
Ricalcola media:
T_media=T_media+(new_T_si-old_T_si)/4
SI
SI
Stato =
IN
NO
OUTPUT:
ALARM OFF
SI
T_media
in_range?
NO
Stato =
OUT
NO
OUTPUT:
ALARM ON
Scarica

Gestione delle subroutine