Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
Gestione delle priorità degli interrupt nell'AIC
AIC invia una richiesta di FIQ alla CPU, il PC verrà quindi caricato con il valore FVR contenuto nel registro AIC. Con tale implementazione hardware evitiamo quindi il polling dei dispositivi.
Inoltre, l'AIC gestisce le priorità dei vari livelli di interrupt, implementando un encoder a 8 livelli di priorità. Ogni sorgente di interrupt ha un livello di priorità programmabile da 0 a 7 (più alta priorità). L'AIC gestisce le priorità utilizzando uno stack interno, che contiene il livello di priorità corrente.
Essendo implementata una sola linea per il fast interrupt, non è presente nessuna implementazione di priorità per esso.
Il livello di priorità è contenuto in una tabella associata al corrispondente elemento dell'interrupt vector table. Supponiamo che venga richiesto un interrupt dal dispositivo numero 30, con livello di priorità pari a 3. Quando il processore inizia ad eseguire la routine relativa a tale interrupt, il...
- Il livello di priorità viene salvato nel
<priority stack>
, che quindi contiene il numero 3. - Supponiamo ora che arrivi l'interrupt dal dispositivo numero 29, con livello di priorità pari a 2. Prima di eseguire la richiesta, l'AIC controlla il valore del livello di priorità di tale interrupt. Se la priorità è più bassa del valore corrente salvato nello stack, l'interrupt non verrà servito e il processore non riceve la richiesta di interrupt finché l'interrupt handler del dispositivo 30 non termina.
- Supponiamo ora di avere nello stesso tempo un interrupt dal dispositivo numero 31, con livello di priorità 5. Essendo la priorità di tale interrupt maggiore del livello di priorità corrente, il valore 5 viene caricato in cima allo stack e il valore 3 viene spostato al secondo livello dello stack.
- Quindi, l'interrupt vector 31 viene copiato nel registro IVR e viene richiesta una interrupt al processore.
- Quando termina la routine relativa all'interrupt...
nu-mero 31, viene effettuato un return alla routine relativa all'interrupt numero30, e il numero 3 ritorna in cima allo stack. Quando la routine dell'interurpt30 termina, viene scritto il valore 2 all'interno dello stack, e viene richiestol'interrupt alla CPU per il dispositivo 29. Quando la routine dell'interrupt29 termina, il priority stack viene svuotato e l'esecuzione torna all'userprogram che continua la sua operazione. Il priority stack è quindi fonda-mentale per la gestione di interrupt annidati: tutti i microcontrolloriche non prevedono un priority level per gli interrupt, non possono supportare151interrupt annidati.
Analizziamo al latenza degli itnerrupt. Nel caso di interrupt ad alto livello dipriorità, la latenza dipende solo dal context switch, e quindi ha una duratarelativamente breve. Nel caso in cui non siano presenti dei livelli di prio-rità, per processare l'handler del dispositivo numero 31 deve essere
Terminata l'elaborazione dell'handler del dispositivo che ha richiesto precedentemente l'interrupt, e quindi il tempo di latenza aumenta considerevolmente. Avere dei livelli di priorità permette quindi di ridurre la latenza per interrupt di alta priorità. Nel caso in cui si hanno interrupt annidati, il tempo di latenza di un interrupt a bassa priorità aumenta in quanto prima di eseguire l'handler di tale interrupt bisogna aspettare la fine dell'esecuzione delle routine degli interrupt precedenti (a maggiore priorità). In questo caso, avere livelli di priorità fa aumentare la latenza: interrupt con più basso livello di priorità avranno più alti tempi di latenza, maggiori rispetto al caso in cui i livelli di priorità non siano presenti.
Ricorda: l'ARM interrupt controller lavora con livelli di priorità, mentre i microcontrollori ATmega e PIC che abbiamo esaminato non la implementano.
15211.11 Interrupt Controller in Cortex
ARMv7 architecture
La famiglia Cortex è una famiglia di microprocessori ARM progettati per sistemi embedded. Vediamo come viene implementato in tale architettura l'interrupt controller.
Nella architettura Cortex, non abbiamo la CPU mode, ma abbiamo solo una singola mode. Solo lo stack pointer viene replicato in differenti registri (banked): il MSP (Main Stack Pointer), progettato per lavorare con il sistema operativo, e il PSP (Process Stack Pointer), utilizzato dalle applicazioni a livello user. I registri R0-R12 sono registri general purpose, R13 è lo stack pointer, R14 è il link register e R15 è il Program Counter, è presente un solo status register.
11.11.1 ARMv7 Cortex status register
Sono presenti alcuni status bit presenti anche nell'architettura ARM analizzata nelle sezioni precedenti: il bit Negative, il bit Zero, il bit Carry ecc; inoltre, è presente un flag aggiuntivo Q chiamato DSP overflow and saturation flag. Analizziamo gli ultimi 8 bit, del field ISR
NUMBER che riguarda-no l'interrupt. Nello status register delle architteture ARM 32 bit, l'ultimo field identificava la modalità di esecuzione, i cosiddetti "mode bit". Essendo presente una sola modalità, tale parte è stata rimossa e gli ultimi 9 bit sono utilizzati per codificare una Interrupt Service Routine. Vediamone il meccanismo. È presente un controllore interno all'architettura cortex che contiene fino a 512 linee di interrupt, divise tra internal, esterne e reserved. Le linee dedicate alle periferiche esterne (dispositivi esterni) partono dalla numero 16 in su. Quando arriva la richiesta di un interrupt, NUMBER ad esempio sulla linea 16, l'interrupt controller carica nell'ISR dello status register il valore 16, il processore interrompe l'esecuzione corrente e viene caricato l'indirizzo dell'interrupt handler. Nella tabella seguente possiamo vedere a quale indirizzo della vector table corrisponde.
l'interrupt service routine numero 16: | Il valore dell'indirizzo dell'interrupt handler viene caricato nel registro ad indirizzo 0x0040, al quale corrisponde l'exception numero 16, e viene eseguito un jump dal processore alla routine contenuta all'interno di tale locazione, come avviene nell'automatic vectoring vista precedentemente. |
Gli interrupt esterni permessi sono 239. | 15411.12 Interrupt in ATmega MCU |
Vediamo come sono controllati gli interrupt nel microcontrollore Atmega328. | In questo microcontrollore non abbiamo livelli di priorità per le interrupt, di conseguenza l'interrupt controller è molto semplice. Viene implementata una grande vector table, in quanto ogni periferica può produrre diversi segnali di interrupt, mappati a indirizzi fissi in tale tabella per evitare il polling da parte della CPU per identificare la causa dell'interrupt. Anche in questo caso si tratta dunque di un meccanismo auto-vectoring. Ogni elemento della vector |
Interrupt Handler | Vettori |
table | La prima istruzione dell'interrupt handler corrispondente |
26 | Sono presenti 26 vettori |
16 bit | Ogni istruzione è lunga 16 bit |
2 byte | I vettori sono mappati a distanza di due byte |
Singola periferica | Una singola periferica viene mappata in differenti vettori in base al tipo di interrupt richiesto |
Timer numero 2 | Ha tre diverse sorgenti di interrupt e tre vettori corrispondenti nella tabella |
USART | Sono presenti tre differenti interrupt per la USART per segnalare la fine di una trasmissione, la fine di una ricezione o per segnalare che il Data Register è vuoto |
Indirizzo 0 | Riservato al reset |
Jump | Tutte le istruzioni indicate nella tabella sono dei JUMP agli interrupt handler |
Indirizzo 0-32 | La vector table, che è appunto una tabella di istruzioni |
JUMP reset | Implica un salto |
All'indirizzo 0x34, e a tal indirizzo è presente l'handler del reset. La tabella è contenuta di default all'indirizzo 0, ma può essere rimappata in un'altra locazione.
11.12.1 Program memory map and bootloader support
Nei microcontrollori ATmega, la Flash Memory è organizzata in due sezioni principali: application section e bootloader section. La bootloader section fornisce un modo per eseguire un meccanismo di self-programming per l'update del firmware del microcontrollore lanciando la boot flash section e programmando l'application flash section.
La boot flash section necessita della vector table e allo stesso tempo può dover aggiornare la flash section stessa. Per fare ciò, sono presenti dei bit programmabili all'interno della vector table che permettono di mappare la vector table all'interno della boot flash section.
Il programma contenuto all'interno della boot flash section può contenere quindi la propria interrupt.
vector table. |
Nei microcontrollori ATmegaabbiamo quindi due vector tables: una utilizzata dalle normali applicazionicaricate nella Flash Memory; alla fine della Flash Memory, è presente unaboot section che contiene del codice utilizzato per sovrascrivere le applicazio-ni (update del firmware), e il processore, per eseguire le istruzioni contenutein tale codice, necessita di una seconda vector table. |
Supponiamo che i bit della tabella precedente siano configurati come 0-1(ultima riga della tabella). Quindi, quando il reset viene inviato al micro-controllore, il PC non viene caricato con il valore 0 ma con l’indirizzo delboot reset, dove è presente una vector table che effettua un JUMP in unasezione della Boot Flash per effettuare il bootloader. Tutti gli altri interruptssono mappati in altri vettori, utilizzabili dal bootloader. |
157Capitolo 12Communication devices forEmbedded SystemsI dispositivi di comunicazione sono un gruppo molto importante di dispositi-vi utilizzati per |
In sistemi real-time distribuiti la comunicazione avviene inviando messaggi tra i vari dispositivi. Per garantire che i requisiti di timing siano rispettati, parte della progettazione consiste nel decidere il delay tra l'invio dei segnali stessi. Prima di descrivere i protocolli standard, descriviamo i principi della comunicazione.
Con layering si intende lo splittare la complessità di un protocollo di comunicazione in blocchi più semplici da progettare, in cui i blocchi di livello più basso vengono utilizzati da blocchi a livello più alto. Il livello più basso è sempre il livello fisico, ovvero il mezzo fisico utilizzato per trasportare i dati da un dispositivo ad un altro. Per quanto riguarda la trasmissione sul mezzo fisico, distinguiamo:
- Parallel communication: layer fisico in cui vengono trasportati più bit di dati, inviando un bit per linea. Vengono inviati più di un bit contemporaneamente.