Sei sulla pagina 1di 59

“La scienza, qualsivoglia siano i suoi ultimi sviluppi, ha le sue origini nelle tecniche,

nelle arti e nei mestieri. La scienza emerge nel contatto con le cose, dipende
dall’evidenza dei sensi, e, per quanto sembri allontanarsi da essi, sempre ad essi deve
tornare” [Farrington, 1949]

Tecniche di input/output 2

Interfacciamento dei sistemi embedded per la


gestione delle periferiche d’ingresso/uscita:
Tecniche di gestione delle interrupt

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale
1
Generalità

Memoria Memoria
istruzioni CPU dati
BUS BUS
ISTRUZIONI DATI

Driver
Periferica

Driver
Periferica
ESEMPIO DI MICROCOMPUTER
(architettura Harward) Driver
Periferica

Driver
Periferica

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 2
Tecniche di INPUT/OUTPUT
 Le tecniche utilizzate nello scambio d’informazioni tra CPU e
periferiche si possono riportare essenzialmente a tre:
1. POLLING: la CPU interroga le periferiche ciclicamente, una per
volta, per verificare se ciascuna necessita di essere servita in seguito al
verificarsi di un evento da gestire
2. INTERRUPT: protocollo automatico con il quale una periferica può
interrompere l’esecuzione del programma in esecuzione per richiedere
il servizio
3. DIRECT MEMORY ACCESS (DMA): meccanismo hardware di
trasferimento autonomo di dati dalla periferica direttamente alla
memoria e viceversa senza la necessità d’intervento della CPU

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 3
Eccezioni e Interruzioni
 C’è una ricca differenziazione nella letteratura tecnica riguardo alle definizioni
di “Eccezione” (Exception) e “Interruzione” (Interrupt)
 Io intendo, in termini generali, per
 ECCEZIONE: qualsiasi evento, sincrono o asincrono rispetto all’esecuzione del
programma in corso, che richieda l’attenzione della CPU e necessiti di una
interruzione del flusso corrente dell’elaborazione per poter essere servito
 INTERRUZIONE: il meccanismo automatico con cui è possibile interrompere
l’esecuzione del programma corrente, consentire la gestione ordinata
dell’eccezione e rientrare correttamente nel punto d’interruzione oppure, se
necessario, eseguire del codice d’emergenza
 Nel mondo effettivo dell’architettura ARM-Cortex, le due definizioni hanno
una specializzazione maggiore, riferendosi a eventi più specifici, ciò non toglie
la validità della precedente definizione
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 4
Eccezioni nel CORTEX M
HARDWARE INVALID OPCODE
INVALID INTERRUPT RETURN
UNCORRECT USAGE
FAULT DIVIDE BY ZERO
BUS UNALIGNED MEMORY ACCESS
MEMORY MANAGEMENT VIOLATIONS
SINCRONE
SUPERVISOR CALL (SVC)

TRAP DEBUG MONITOR

ECCEZIONI PENDING SVC

INTERNE SYSTICK (periodic interrupt)

ASINCRONE RESET
NON MASCHERABILI
NMI
ESTERNE TIMERS, EVENT COUNTERS
(external interrupt)
MASCHERABILI
INPUT/OUTPUT PERIPHERALS

Architettura dei sistemi embedded


30/09/2012 5
Il meccanismo di “interrupt”
 Ogni eccezione è associata a un “thread ” ovvero a un segmento di codice
che la CPU deve eseguire per servire l’evento che ha procurato l’eccezione
 Nel caso delle eccezioni il “thread” è eseguito in “background”, nel senso
che la sua attivazione è gestita automaticamente dall’hardware, e viene
denominato come:
 Interrupt Service Routine (ISR) o Interrupt Handler
 Se l’eccezione è sincrona oppure è asincrona non mascherabile,
l’interrupt sarà sicuramente presa in carico e il “thread” ad essa associato
verrà comunque attivato
 Se l’eccezione è asincrona mascherabile essa sarà considerata, e il relativo
“thread” sarà attivato, solo se l’interrupt è stata abilitata dal programma

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 6
Il meccanismo di “interrupt”: handshaking tra CPU e periferica
CPU Periferica
Esegue Main Attesa

Arma la periferica
Attiva l’evento da servire Periferica pronta

Abilita le interrupt

(Prosegue esecuzione Main)


Richiesta interrupt Accade evento da servire
(Trigger)

• Se abilitata, riconosce la richiesta


• Completa ciclo istruzione in corso
• Interrompe esecuzione Main
• Salva lo stato macchina
• Salta alla ISR relativa all’evento

Esegue Interrupt Service Routine appropriata per Interrupt acknowledge


soddisfare la richiesta di servizio della periferica

• Ripristina lo stato macchina salvato Periferica pronta


• Riprende l’esecuzione del Main all’istruzione
successiva a quella completata

(Prosegue esecuzione Main)

30/09/2012 Architettura dei sistemi embedded 7


Problemi attinenti la gestione delle interrupt

1. Problema del riconoscimento dell’evento da servire


quando le periferiche in grado di richiedere interrupt
sono più di una
2. Problema della gestione delle priorità in quanto non
tutte le eccezioni e non tutte le periferiche hanno lo
stesso rango e la stessa urgenza nell’essere servite
3. Problema del “nesting” (nidificazione): “chi può, e
deve, interrompere chi?”; ovvero, se è in esecuzione
una ISR presa in carico, questa può a sua volta essere
interrotta per servirne un’altra?
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 8
Valutazione delle prestazioni
 Nel risolvere i tre problemi precedenti occorre tenere in conto i seguenti
parametri di valutazione delle prestazioni:
1. Latenza: è il tempo che intercorre tra il verificarsi dell’evento e il servizio
dell’evento stesso. Nei sistemi “real time” questo parametro è cruciale.
2. Flessibilità: possibilità di gestire le priorità dinamicamente in modo da
poterle assegnare agli eventi specifici in funzione del contesto in cui il
software sta eseguendo il Main e delle condizioni effettive in cui il sistema
sta operando. (Un evento poco significativo in un certo istante può diventare
determinante in un altro momento)
3. Divisione del carico tra hardware e software: quanto lavoro è assegnato al
Main per individuare e gestire l’evento e quanto, invece, può essere
automatizzato da un hardware ad hoc.

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 9
Tecniche di riconoscimento

 Polling: la richiesta di interrupt è unica e condivisa da tutte le periferiche, è compito del


software interrogare un opportuno registro di stato di ogni periferica per determinare
quale ha chiesto di essere servita.
Valutazione: latenza alta, flessibilità buona, hardware semplice, carico software elevato.
 Vettorizzazione in “daisy chain”: la richiesta è unica ma le periferiche sono collegate in
cascata con una priorità fissa legata all’ordine in cui sono connesse fisicamente. Al
momento dell’“acknowlodgement”, la periferica più in cima alla cascata forza sul data bus
un vettore di riconoscimento che servirà a identificarla per saltare alla ISR corretta.
Valutazione: latenza bassa, flessibilità bassa, hardware semplice, carico software basso.
 Vettorizzazione con “Programmable Interrupt Controller”: le richieste sono raccolte da
un unico hardware esterno che provvede alla gestione delle priorità e fornisce il vettore
corretto associato all’evento che più ha diritto al servizio.
Valutazione: latenza bassa, flessibilità buona, hardware complesso, carico software basso.

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 10
Il collegamento in “daisy chain”

CPU Memoria
BUS

IntReq
IntAck
Vettore 1

Vettore 2

Vettore 3

Vettore 4
Vcc

IEI IEI IEI IEI


Periferica Periferica Periferica Periferica
1 2 3 4
IEO IEO IEO IEO

1. Ogni periferica che necessita servizio attiva il suo segnale IntReq


2. Una periferica può essere servita solo quando il suo IEI = 1
3. Se una periferica ha il suo IEI = 0, pone il suo IEO = 0 che si propagherà per tutta la catena
4. Se una periferica può essere servita, quando la CPU attiva il segnale IntAck, mette a zero il suo IEO,
disabilitando tutte le periferiche a valle, e forza il suo vettore di riconoscimento sul BUS DATI
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 11
Programmable Interrupt Controller

CPU
Memoria
BUS

Vettore i
Programmazione
Registri PIC

IntReq
Programmable Interrupt Controller
IntAck
IntAck1

IntAck2

IntAck3

IntAck4
IntReq1

IntReq2

IntReq3

IntReq4
Periferica Periferica Periferica Periferica
1 2 3 4

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 12
Riconoscimento vettorizzato via PIC
1. Il Main ha abilitato le interruzioni e programmato il PIC associando ad ogni periferica
sia un codice binario (VETTORE) che la identifica sia uno specifico livello di priorità,
in funzione dell’importanza dell’evento a cui è associata
2. La periferica è stata resa idonea a interrompere il Main nel caso di necessità di servizio
3. Al verificarsi dell’evento da servire, la periferica richiede l’interruzione al PIC
4. Il PIC, risolto il problema delle priorità, attiva il segnale d’interrupt verso la CPU
preparandosi a fornire il codice dell’interrupt associata alla periferica richiedente
5. La CPU, completata l’istruzione in corso, effettua un ciclo macchina di “read”,
attivando il segnale di “Interrupt Acknowledge” per leggere il vettore fornito dal PIC
6. Il vettore letto è utilizzato dalla CPU come indice per accedere a una TABELLA
DELLE ECCEZIONI, presente in memoria, in cui sono stati caricati gli indirizzi delle
ISR necessarie a servire ogni specifico evento previsto
7. La CPU preleva dalla tabella l’indirizzo della ISR, salva lo stato macchina attuale ed
effettua un salto alla funzione necessaria a servire l’evento che ha generato l’interrupt
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 13
Il meccanismo di vettorizzazione
CPU MEMORIA
Tabella dei vettori di interrupt

IND_BASE + 0 ISR #0 Start Address

Ind Base Tabella dei vettori IND_BASE + 4 ISR #1 Start Address

Indirizzo vettore
………………….. …………………..
in tabella
IND_BASE + 4*j ISR #j Start Address
+
………………….. …………………..
OFFSET vettore j
Supponendo
4 indirizzi di IND_BASE + 4*N ISR #N Start Address B ISR#jStart Address
* memoria
a 32 bit
…………………..
Vettore periferica N° j ISR #j Start Inizio della routine di
Address servizio dell’interrupt j
Dal BUS
DATI ………………….
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 14
La gestione delle eccezioni nel Cortex M

 I microcomputer della famiglia CortexM gestiscono le eccezioni con una tecnica


di vettorizzazione assistita da un coprocessore programmabile (NVIC) che oltre
a fornire il vettore specifico per ognuna di esse, provvede anche a:
1. Abilitare e disabilitare ogni specifica interrupt (su un totale di 240) associata
sia alle eccezioni di sistema sincrone sia alle eccezioni asincrone associabili
alle periferiche esterne
2. Assegnare ad ognuna di esse un livello di priorità programmabile basato su un
minimo di tre bit a un massimo di otto
3. Gestire la dinamica del nesting delle interrupt memorizzando sia le richieste
d’interruzione con un livello di priorità più basso di quella attualmente servita,
sia le ISR in esecuzione interrotte da una richiesta a priorità più alta e forzate in
uno stato temporaneo di inattività
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 15
NVIC : Nested Vectored Interrupt Controller

 Gestione centralizzata delle interrupt

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 16
Condizioni di generazione di una interrupt asincrona per il
Cortex M

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 17
Sequenza di “context switching” nel Cortex M

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 18
Stato delle eccezioni nel CortexM
 Ogni eccezione può trovarsi in uno dei quattro stati seguenti:

• Inactive: eccezione non attiva e non in


Inactive stato di pending

• Pending: eccezione richiesta e in attesa di


Active essere servita dalla CPU
and Pending
Pending • Active: eccezione attualmente in servizio
ma non ancora completata

Active • Active and Pending: eccezione in


servizio ma è presente un’altra richiesta dalla
stessa sorgente
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 19
Tipi di eccezioni e interrupt nel CortexM
 Nel microcomputer Cortex sono disponibili fino a 255 interrupt
 Le prime 15 sono dedicate alle eccezioni sincrone di sistema, le restanti sono
attribuibili a eccezioni asincrone interne o esterne
 Il meccanismo di gestione è un sistema di vettorizzazione tramite l’interrupt
controller NVIC (Nested Vectored Interrupt Controller)
 A ogni eccezione è assegnato via software un livello di priorità che va da 1 a
255, con “1” come livello massimo
 Le prime tre eccezioni (RESET, NMI, HARD FAULT) hanno priorità
negativa preassegnata (rispettivamente -3, -2, -1), in modo tale da non essere
mai mascherabili, tutte le altre hanno priorità programmabile
 Il meccanismo di nesting prevede che ogni interrupt a priorità più elevata può
interrompere una ISR associata a una interrupt di livello inferiori (preemption)
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 20
Eccezioni sincrone di sistema
N° Tipo Priorità Descrizione
-3
1
Reset (PIU’ ELEVATA) Reset
Interruzione non mascherabile associata
2 NMI a richieste irrevocabili: power down,
-2 watch dog.
Qualunque condizione di fault con ISR
3 Hard Fault non abilitata perché è in servizio una
-1 eccezione di priorità maggiore
Memory Management Unit fault:
4 Mem Fault violazioni di protezione o accesso a
Programmabile locazioni di memoria proibite
5 Bus Fault Accesso errato al bus
6 Usage Fault Errore di programma
7
8
Riservate
9
10
Supervisor Call: chiamata a un
11 SVC programma supervisore o al sistema
Programmabile operativo
Breakpoint, watchpoint o richiesta di
12 Debug Monitor
debug esterna
13 Riservata
Supervisor Service in corso
14 Pending SV
Programmabile
15 SYSTICK Timer di sistema per la regolazione del
tempo di esecuzione dei task

30/09/2012 Architettura dei sistemi embedded 21


Interrupt asincrone esterne: dal N° 0 al N° 239

Eccezioni asincrone esterne


N° Tipo Priorità Descrizione
16 External Interrupt #0 Periferica #0

Da Da
External Interrupt #1 Periferica #1
17 - 254 a Programmabile a
External Interrupt #238 Periferica #238

255 External Interrupt #239 Periferica #239

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 22
Esempio di posizione dei vettori per il micro Stellaris LM3Sxx
Eccezioni di sistema 1 - 15

Bit 7 - 6 - 5
Bit 15 - 14 - 13

SysPRI1
Bit 23 - 22 - 21

Reg.
Reg.
SysPRI2 Bit 31 - 30 - 29
Bit 7 - 6 - 5

SysPRI3
Bit 23 - 22 - 21

Reg.
Bit 31 - 30 - 29

30/09/2012 Architettura dei sistemi embedded 23


Esempio di posizione dei vettori per il micro Stellaris LM3Sxx
Interrupt esterne 0 - 15

Bit 7 - 6 - 5

Reg. PRI0
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29
Bit 7 - 6 - 5

Reg. PRI1
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29
Bit 7 - 6 - 5

Reg. PRI2
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29
Bit 7 - 6 - 5

Reg. PRI3
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29

30/09/2012 Architettura dei sistemi embedded 24


Esempio di posizione dei vettori per il micro Stellaris LM3S1968
Interrupt esterne 16 - 31

Bit 7 - 6 - 5

Reg. PRI4
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29
Bit 7 - 6 - 5

Reg. PRI5
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29
Bit 7 - 6 - 5

Reg. PRI6
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29
Bit 7 - 6 - 5

Reg. PRI7
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29
30/09/2012 Architettura dei sistemi embedded 25
Esempio di posizione dei vettori per il micro Stellaris LM3S1968
Interrupt esterne 32 - 43

Bit 7 - 6 - 5

Reg. PRI8
Bit 15 - 14 - 13
Bit 23 - 22 - 21
Bit 31 - 30 - 29

Bit 7 - 6 - 5

Reg. PRI9
Bit 15 - 14 - 13
Bit 23 - 22 - 21

30/09/2012 Architettura dei sistemi embedded 26


L’abilitazione delle interrupt nel CortexM

 Le interrupt non mascherabili devono essere abilitate a tre livelli

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 27
Abilitazione Globale

Il bit0 del registro PRIMASK,


se forzato a “1” maschera
le interrupt con priorità
programmabile,
se forzato a “0” le abilita (NON
maschera)

Il bit0 del registro FAULTMASK,


se forzato a “1” maschera
le interrupt legate a eccezioni di
fault, se forzato a “0” le abilita
(NON maschera)
La lettura/scrittura di questi due registri può essere fatta usando le istruzioni dedicate:
MRS{cond} Rd, spec_reg : Move register Rd to Special Purpose Register
MSR{cond} spec_reg, Rn : Move Special Purpose Register to register Rn
Dove Special Purpose Register = APSR, IPSR, EPSR, IEPSR, IAPSR, EAPSR, PSR, MSP, PSP, PRIMASK,
BASEPRI,BASEPRI_MAX, FAULTMASK, CONTROL
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 28
Abilitazione Specifica
 Nel CORTEX M3 della serie Stellaris sono utilizzate 48 interrupt delle 255
disponibili
 Ogni interrupt deve essere abilitata/disabilitata tramite i registri del NVIC
 EN0 (32 bit) + EN1 (i primi 16 bit):
EN0(0) abilita l’interrupt #0 associata alla eccezione#16
………………………………………………………….
EN0(31) abilita l’interrupt #31 associata alla eccezione#47
EN1(0) abilita l’interrupt #32 associata alla eccezione#48
…………………………………………………………..
EN1(15) disabilita l’interrupt #47 associata alla eccezione#63
 DIS0 (32 bit) + DIS1 (i primi 16 bit):
DIS0(0) disabilita l’interrupt #0 associata alla eccezione#16
………………………………………………………….
DIS0(31) disabilita l’interrupt #31 associata alla eccezione#47
DIS1(0) disabilita l’interrupt #32 associata alla eccezione#48
…………………………………………………………..
DIS1(15) disabilita l’interrupt #47 associata alla eccezione#63

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 29
Assegnazione delle priorità

 La gestione delle priorità ha due livelli di controllo

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 30
Assegnazione del livello generale di priorità
 Il registro special purpose BASEPRI imposta il livello di priorità minimo necessario
all’eccezione perché possa essere presa in considerazione
 Nei microcomputer Stellaris sono dedicati solo tre degli otto bit meno significativi del
registro

 Se BASEPRI(7-5) = “000” tutte le interrupt a priorità programmabile possono essere servite


 Se BASEPRI(7-5) = “xxx” possono essere servite solo le interrupt con priorità  “xxx” – 1
 Se BASEPRI(7-5) = “111” sono mascherate le interrupt con priorità 7
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 31
Assegnazione specifica della priorità ad ogni singola
eccezione con priorità programmabile via NVIC

 Nel NVIC dei micro Stellaris sono presenti undici registri, PRI0
– PRI10 per la definizione delle priorità, ognuno diviso in
quattro campi da otto bit cadauno, utilizzati per assegnare il
livello ad ognuna delle eccezioni comprese tra il numero 0 al
numero 43, corrispondenti ai vettori dal numero16 al numero 59
 Ogni campo utilizza solo i tre bit più significativi per assegnare
un livello di priorità compreso da 1 a 7, dove:
 1 è la priorità maggiore e 7 la minore

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 32
REGISTRI PRI0 – PRI10 dell’NVIC per l’assegnazione delle priorità per tutte le
interrupt a priorità programmabile associate a eventi relativi a
PERIFERICHE ESTERNE nel caso del microcomputer Stellaris LM3S1968
(sono utilizzati solo i tre bit più significativi di ogni byte: priorità da 1 a 7)
INTD INTC INTB INTA

31 30 29 23 22 21 15 14 13 7 6 5

PRI0 INT#3 INT#2 INT#1 INT#0

PRI1 INT#7 INT#6 INT#5 INT#4


PRI2 INT#11 INT#10 INT#9 INT#8
PRI3 INT#15 INT#14 INT#13 INT#12

PRI4 INT#19 INT#18 INT#17 INT#16


PRI5 INT#23 INT#22 INT#21 INT#20
PRI6 INT#27 INT#26 INT#25 INT#24
PRI7 INT#31 INT#30 INT#29 INT#28
PRI8 INT#35 INT#34 INT#33 INT#32
PRI9 INT#39 INT#38 INT#37 INT#36
PRI10 INT#43 INT#42 INT#41 INT#40

30/09/2012 Architettura dei sistemi embedded 33


REGISTRI PRI0 – PRI10 dell’NVIC per l’assegnazione delle priorità per tutte le
interrupt a priorità programmabile associate a eventi relativi a
PERIFERICHE ESTERNE nel caso del microcomputer Stellaris LM3S1968
(sono utilizzati solo i tre bit più significativi di ogni byte: priorità da 1 a 7)

INTD INTC INTB INTA

31 30 29 23 22 21 15 14 13 7 6 5

PRI0 INT#3 INT#2 INT#1 INT#0

PRI1 INT#7 INT#6 INT#5 INT#4


PRI2 INT#11 INT#10 INT#9 INT#8

30/09/2012 Architettura dei sistemi embedded 34


La gestione del processo d’interrupt:
1° - Definizione della ISR e sua registrazione

1. Per gestire una qualsiasi eccezione occorre innanzitutto scrivere


una routine di servizio della periferica (ISR) in grado di mettere
in atto tutte le azioni che la CPU deve effettuare per fare fronte
all’evento che ha prodotto l’eccezione stessa
(La slide seguente mostra un esempio di ISR per gestire il timer
di sistema SysTick nella generazione di una interrupt periodica
ogni millisecondo)
2. Il passo successivo, richiede la registrazione dell’indirizzo della
ISR nella tabella dei vettori d’interrupt alla posizione ad essa
associata

30/09/2012 Giulio Vitale 35


;ESEMPIO di Interrupt Service Routine per timer SysTick su Stellaris LM3S1968
.data
.align 4
ContaInt .field 32 ; Alloca variabile che conta il numero assoluto di SysTick interrupts
UnSec .field 32 ; Alloca variabile che misura il tempo relativo a un secondo
; Memorizza in area codice la ISR
.text
ContaIntPtr .field ContaInt,32
UnSecPtr .field UnSec, 32
; EXPORT SysTick_Handler
.global SysTick_Handler
SysTick_Handler:
.asmfunc
; Controlla se è trascorso un secondo PRESUPPONENDO CHE IL TIMER SysTick
; sia programmato per generare una interrupt ogni millisecondo
LDR R1, UnSecPtr; R1 = &UnSec (pointer alla variabile di misura)
LDR R0, [R1]; R0 = (UnSec) (contenuto della variabile)
ADDS R0,#-1; Decrementa il registro modificando le flag
STR R0, [R1]; Salva il contenuto di R0 in “UnSec”
BNE InCounts; Controlla se zero
; Se zero: Reload UnSec and Toggle LED
MOV R0, #1000; Conta
STR R0, [R1]
LDR R1, =GPIO_PORTG2 ; R1 = &GPIO_PORTG2 (pointer)
LDR R0, [R1] ; R0 = [R1] = GPIO_PORTG2 (value)
EOR R0, R0, #0x04 ; R0 = R0^0x04 (toggle LED su PIN e del PORT G)
STR R0, [R1] ; [R1] = R0
;Se non zero: incrementa solo ContaInt per totalizzare il numero complessivo di interrupt
InCounts:
LDR R1, ContaIntPtr ; R1 = &ContaInt (pointer al contatore assoluto)
LDR R0, [R1] ; R0 = [R1] = ContaInt (valore)
ADD R0, R0, #1 ; R0 = R0 + 1 (ContaInt = ContaInt + 1)
STR R0, [R1] ; [R1] = R0 (overflows dopo 49 giorni)
BX LR ; return from interrupt
.endasmfunc

30/09/2012 Architettura dei sistemi embedded 36


La gestione del processo d’interrupt:
1° - Definizione della ISR e sua registrazione (cont.)

; This portion of the file goes into interrupt vectors section


.thumb
.sect ".intvecs”; Vedi file .cmd: definisce una sezione “text”
; The vector table.
.global SysTick_Handler, Vectors Per REGISTRARE la ISR prima
Vectors:
.ref __STACK_TOP ;; Definisce una etichetta scritta occorre modificare il file
.word __STACK_TOP ;; Offset 00: Initial stack pointer
.word ResetISR ;; Offset 04: Reset handler
“startup.s” in cui sono memorizzati i
.word NmiSR ;; Offset 08: NMI handler vettori per la gestione di tutte le
.word FaultISR ;; Offset 0C: Hard fault handler
.word IntDefaultHandler ;; Offset 10: MPU fault handler eccezioni, inserendo l’indirizzo
.word IntDefaultHandler ;; Offset 14: Bus fault handler della ISR interessata nella tabella
.word IntDefaultHandler ;; Offset 18: Usage fault handler
.word 0 ;; Offset 1C: Reserved da cui la CPU farà il fetch per
.word 0 ;; Offset 20: Reserved
.word 0 ;; Offset 24: Reserved
individuare correttamente la
.word 0 ;; Offset 28: Reserved posizione in memoria a cui saltare al
.word IntDefaultHandler ;; Offset 2C: SVCall handler
.word IntDefaultHandler ;; Offset 30: Debug monitor handler momento della richiesta di servizio
.word 0 ;; Offset 34: Reserved
.word IntDefaultHandler ;; Offset 38: PendSV handler
.word SysTick_Handler ;; Offset 3C: SysTick handler

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 37
La gestione del processo d’interrupt:
2° – Assegnazione dei livelli di priorità
 L’assegnazione globale della priorità va fatta programmando il registro
Special Purpose BASEPRI con il livello di priorità minimo accettato più uno

; Supponendo di voler assegnare come livello di priorità globale il livello2


MOV R1, #60 ; R1 = 0x00000060
MSR R1, BASEPRI ; BASEPRI = 0x3

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 38
La gestione del processo d’interrupt:
2° – Assegnazione dei livelli di priorità

 L’assegnazione specifica della priorità va fatta programmando il registro del


NVIC associato all’evento o uno tre registri SYSPRI1, SYSPRI2, SYSPRI3,
nel caso di interrupt associate a eccezioni sincrone di sistema

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 39
(Prosegue esempio assegnazione specifica priorità)

.text
SYSPRI3_addr:
.word 0xE000ED20 ;Indirizzo del registro SYSPRI3
CLR_MASK:
.word #0x00FFFFFF ;Maschera per azzerare il byte più
;significativo (AND_ing) di SYSPRI3
SET2_MASK:
.word #0x40000000 ;Maschera per forzare a 2 i tre bit più
;significativi (OR_ing) di SYSPRI3
; Supponendo di voler assegnare all’evento SysTick il livello di priorità 2
LDR R0, CLR_MASK ;R0 = CLR_MASK
LDR R1, SYSPRI3_addr ;R1 = pointer al registro SYSPRI3
LDR R2, [R1] ;R2 = contenuto del registro SYSPRI3
AND R2, R2, R0 ;R2 = 0x00XXXXXX
LDR R0, SET2_MASK ;R0 = SET2_MASK
ORR R2, R2, R0 ;R2 = 0x40XXXXXX
STR R2, [R1] ;SYSPRI3 = 0x40XXXXXX

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 40
La gestione del processo d’interrupt:
3° - Abilitazione Specifica
 Occorre abilitare l’interrupt specifica ponendo a “1” il bit relativo associato
all’evento nel registro EN0 o EN1 nell’NVIC
 Nel caso di eccezioni sincrone non è necessario

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 41
(Esempio di abilitazione specifica)

;Supponendo di voler abilitare l’interrupt esterna associata al PORT GPIO E


;(Vector number: 20; External Interrupt number: 4; Bit di abilitazione: EN0(4)

.text
EN0_addr .word 0xE000E100 ;Indirizzo del registro di abilitazione
EN_INT4_MASK .word 0x00000010 ;Maschera per abilitare

; Si forza a uno il bit 4 di EN0


MOV R0, EN_INT4_MASK ;R0 = EN_INT4_MASK
LDR R1, EN0_addr ;R1 = pointer al registro EN0 del NVIC
LDR R2, [R1] ;R2 = contenuto del registro EN0
ORR R2, R2, R0 ;R2 = 0xXXXX.XX_1X
STR R2, [R1] ;EN0(4) = 1

30/09/2012 Architettura dei sistemi embedded 42


La gestione del processo d’interrupt:
4° - Armare la periferica
 Occorre abilitare la specifica periferica a richiedere l’interruzione quando si
verifica l’evento che richiede l’intervento della CPU per essere servito
 Esempio: volendo generare l’interrupt del SysTick bisogna abilitare nel
Timer di sistema i bit N. 16,2,1,0, dopo averne azzerato il valore corrente e
impostato il valore di reload

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 43
(Esempio di come si “arma” una periferica)
.text
NVIC_ST_CTRL_R .word 0xE000E010
NVIC_ST_RELOAD_R .word 0xE000E014
NVIC_ST_CURRENT_R .word 0xE000E018
ARMA_INT_SYSTICK .word 0x00010007

;Supponendo che R0 contenga il valore di reload del timer (meno 1)


LDR R1, NVIC_ST_RELOAD_R ; R1 = &NVIC_ST_RELOAD_R (pointer)
STR R0, [R1] ; Imposta il periodo dell’interruzione
; Azzera il valore corrente del contatore del timer
LDR R1, NVIC_ST_CURRENT_R ; R1 = &NVIC_ST_CURRENT_R (pointer)
STR R0, [R1] ; scrivendo sul contatore lo si azzera
;Abilita il conteggio, il clock e le interrupt
LDR R1, NVIC_ST_CTRL_R ; R1 = &NVIC_ST_CTRL_R
LDR R2, ARMA_INT_SYSTICK ; R2 = ARMA_INT_SYSTICK
STR R2, [R1] ; Periferica “armata”
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 44
La gestione del processo d’interrupt:
5° - Abilitazione Globale
 L’abilitazione globale delle interrupt si effettua forzando a zero il bit meno
significativo dei registri:
1. PRIMASK
2. FAULTMASK
 In effetti questi bit sono già a zero all’atto del reset
 Il significato reale è che PRIMASK(0) = 1, disabilita tutte le interruzioni
con priorità programmabile (ovvero tutte meno Reset, NMI, HardFault),
mentre FAULMASK(0) = 1, disabilita tutte le interruzioni meno quella di
Reset e NMI
 Per manipolare questi bit si possono usare, oltre alle solite MSR e MRS,
anche le istruzioni CPS (dove: i => PRIMASK, f => FAULTMASK) :
CPSIE i e CPSIE f per abilitare
CPSID i e CPSID f per disabilitare
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 45
La gestione del processo d’interrupt:
6° - Il processo di “context switching”

 Se l’interrupt è accettata si verifica il suddetto “context switching”,


ovvero la CPU effettua automaticamente le seguenti operazioni
1. Conclude l’istruzione in corso
2. Salva nello stack i registri: R0 – R3, R12, LR, PC, PSR
3. Carica il registro LR con il valore 0xFFFFFFFx (con x=9,
normalmente)
4. Accede alla tabella dei vettori d’interrupt per prelevare l’indirizzo
della ISR associata all’evento che ha richiesto servizio
5. Salta alla ISR individuata

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 46
La gestione del processo d’interrupt:
7° - Il rientro al programma interrotto

 Il rientro al programma principale avviene eseguendo alla


fine della ISR l’istruzione:
BX LR
 La procedura di rientro avviene recuperando dallo stack i
registri precedentemente salvati, iniziando dal TOS (R0)
 Con quest’ultima operazione si recupera il PC salvato dopo
la fase di “execute” dell’ultima istruzione eseguita, quindi
già aggiornato per puntare alla successiva
 Si riprende il programma interrotto

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 47
30/09/2012 Architettura dei sistemi embedded 48
Nested Vectored Interrupt Controller
 Provvede alla gestione delle interrupt esterne fornendo tutti i servizi di
abilitazione/disabilitazione, gestione delle priorità e del nesting attraverso
quattro gruppi di registri:
1. ABILITAZIONE/DISABILITAZIONE formato da due coppie di registri
 EN0 – EN1 => 48 bit (32 + 16) per abilitare ogni singola interrupt
 DIS0 – DIS1 => 48 bit (32 + 16) per disabilitare ogni singola interrupt
2. PENDING/UNPENDING
 PEND0 – PEND1 => 48 bit per abilitare ogni singola interrupt
 UNPEND0 – UNPEND0 => 48 bit per disabilitare ogni singola interrupt

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 49
30/09/2012 Architettura dei sistemi embedded 50
30/09/2012 Architettura dei sistemi embedded 51
30/09/2012 Architettura dei sistemi embedded 52
30/09/2012 Architettura dei sistemi embedded 53
Registri per l’assegnazione delle priorità alle
Eccezioni di sistema con priorità programmabile

30/09/2012
Architettura dei sistemi embedded
54
Esempio di gestione dell’interrupt SysTick
con le librerie StellarisWare
/*
* SysTick_Interrupt.h
*
* Created on: 20/set/2015
* Author: Giulio Vitale
*/
#ifndef SYSTICK_INTERRUPT_H_
#define SYSTICK_INTERRUPT_H_
//Inclusione librerie standard del compilatore
#include <stdint.h>//Libreria per tipi aritmetici C99
// Inclusione librerie standard della CPU
#include "inc/hw_memmap.h"//Indirizzi delle aree di memoria
#include "inc/hw_types.h"//Accesso ai registri hardware delle periferiche
// Inclusione driver standard relative alla scheda
// Inclusione Funzioni di livello 1
#include "driverlib/sysctl.h"
#include "driverlib/interrupt.h"
// Inclusione Gestione SysTick Control register
#include "driverlib/systick.h“
// Inclusione Funzioni di livello 2
#include "Utils/uartstdio.h"
// Inclusione delle librerie Custom
#include "Drivers/Led_driver.h"
#endif /* SYSTICK_INTERRUPT_H_ */
Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 55
“main”: preparazione e inizializzazioni generali

#include "SysTick_Interrupt.h"
extern void SysTick_Handler(void);
static uint32_t TickCounter;
static uint32_t OneSecondElapsed;
void main(void) {
// Imposta il PLL per un clock a 50MHz
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);
// Abilita l'UART0 per usarlo come "serial console".
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
// Inizializza l' UART come standard I/O.
//NB: al nome delle funzioni standard delle librerie C occorre inserire il prefisso "UART"
UARTStdioInit(0);
UARTprintf("\r\n Inizializza UART come standard I/O\r\n");
UARTprintf("\r\n Inizializza i led \r\n");
LEDsInit ();
//Azzera TickCounter e la flag “OneSecondElapsed” e spegne i LED
TickCounter = 0;
OneSecondElapsed = 0;
LED_Off(BOTH_LEDS);
uint8_t toggle=0; //Variabile per lampeggiamento LED
toggle=0:

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 56
“main”: attivazione Interrupt e timer SysTick
// Imposta il periodo per il timer SysTick pari a "system clock/50000 = 1 ms"
SysTickPeriodSet(50000);
// Abilitazione GLOBALE delle interruzioni.
IntMasterEnable();
// Abilitazione specifica della SysTick Interrupt.
SysTickIntEnable();
// Arma il timer SysTick abilitandolo a generare l'interrupt.
SysTickEnable();
while(1)
{
if (OneSecondElapsed)
{
OneSecondElapsed = 0;
if (toggle==0)
{
toggle = 0xff;
UARTprintf("\r\n LED ACCESI \r\n");
}
else
{
toggle = 0;
UARTprintf("\r\n LED SPENTI \r\n");
}
LED_Toggle (BOTH_LEDS);
}
}
} //Chiusura del Main Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 57
SysTicK handler: ISR di gestione dell’evento

//Conta mille interrupt e attiva la flag OneSecondElapsed


extern void SysTick_Handler(void)
{
if(TickCounter++ == 1000)
{
TickCounter = 0;
OneSecondElapsed = 0xFFFF;
}
}

Architettura dei sistemi embedded


30/09/2012 Giulio Vitale 58
Registrazione della ISR nella tabella dei
vettori di interrupt nel file di “StartUp.c”
extern void SysTick_Handler(void);
#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (* const g_pfnVectors[])(void) =
{
(void (*)(void))((uint32_t)&__STACK_TOP),
// The initial stack pointer
ResetISR, // The reset handler
NmiSR, // The NMI handler
FaultISR, // The hard fault handler
IntDefaultHandler, // The MPU fault handler
IntDefaultHandler, // The bus fault handler
IntDefaultHandler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
IntDefaultHandler, // SVCall handler
IntDefaultHandler, // Debug monitor handler
0, // Reserved
IntDefaultHandler, // The PendSV handler
SysTick_Handler, // The SysTick handler
IntDefaultHandler, // GPIO Port A
………………………
} Architettura dei sistemi embedded
30/09/2012 Giulio Vitale 59

Potrebbero piacerti anche