Teoria elettronica
Componenti fondamentali del microcontrollore
1) Core: regione dove vengono eseguite fisicamente le istruzioni. Comprende la circuiteria dell’ALU e la parte dei registri. Alcuni processori più complicati sono anche dotati di una memoria cache, una piccola memoria ad accesso veloce che serve per migliorare le performance in termini di accesso alle istruzioni e ai dati di esecuzione.
2) Memoria: dove abbiamo una memoria volatile ed una non volatile. Nella memoria principale vengono conservati i dati di esecuzione del programma (memoria volatile) e vengono conservate le istruzioni da eseguire (memoria non volatile).
3) Interfaccia I/O: sono tutte le periferiche, sia esterne che interne al nostro microcontrollore che non sono parte né della memoria né del core (es. modulo Bluetooth, DMA). Tutti i componenti sono collegati tramite la bus interface, bus di comunicazione, che consiste in una parte di indirizzi, di dati e di segnali di controllo.
Memory mapped vs I/O mapped
Memory Mapped: Tutto viene mappato nello stesso spazio di indirizzamento (es. ARM).
I/O Mapped: Alcune famiglie di processori hanno due spazi di indirizzamento.
Architetture di un processore
1) Von Neumann
- Viene usato solo un bus per i dati e le istruzioni di fetch.
- Semplifica molto l’architettura dell’hardware e le istruzioni e i dati sono allocati nello stesso spazio di memoria.
2) Harvard (ARM)
- Il processore riesce indipendentemente ad accedere sia ai dati che alle istruzioni grazie all’utilizzo di bus di istruzioni e bus di dati separati.
- Questo causa una complessità nell’architettura dell’hardware.
Il core del Cortex M4 è basato sull’architettura Harvard con bus separati per istruzioni e dati.
Allocazione dati (data endianness)
Endianness, in informatica, è l’ordine o la sequenza di byte di dati nell’allocazione in memoria. Per allocare in memoria i dati abbiamo 3 modalità:
- Little Endian: memorizza il byte meno significativo (LSB) all’indirizzo più piccolo e il byte più significativo (MSB) all’indirizzo più grande.
- Big Endian: memorizza il MSB all’indirizzo più piccolo e il LSB all’indirizzo più grande.
- Bi-endian: modalità commutabile utilizzata da alcuni processori come l’ARM.
Registri
- Consentono un accesso molto veloce ai dati.
- È l’area di archiviazione più importante e vicina del processore.
- Sono di quantità limitata (tipicamente inferiore a 100).
- La maggior parte sono di tipo generico (general purpose) e possono memorizzare qualsiasi tipo di informazione (es. dati, timer value, costanti, indirizzi, stack…)
- Alcuni sono riservati per scopi specifici (specific purpose):
- Program counter (PC) (R15 in ARM)
- Program status register (PSR).
Nel Cortex M4 i registri sono a 32 bit.
Istruzioni
Immaginando di avere un processore a 32 bit, un’istruzione è formata nel seguente modo:
CISC e RISC
Sono i 2 approcci fondamentali del set computing (design dell’istruction set di un calcolatore):
Complex Instruction Set Computing (CISC)
- Instruction set complesso;
- Sono presenti tante istruzioni e sono complesse (fatto e pensato per ridurre il gap che si crea tra il linguaggio macchina, di basso livello e i linguaggi di programmazione di alto livello) di lunghezza variabile;
- Approccio adottato per processori di fascia alta (PC, server…);
- Consumo energetico alto;
Reduced Instruction Set Computing (RISC)
- Instruction set semplice;
- Istruzioni semplici (prevalentemente di lunghezza fissa);
- Alto numero di registri rispetto al CISC per via delle istruzioni più semplici;
- Metodo di indirizzamento più semplice, basato sulle istruzioni load/store;
- Approccio adottato per processori di fascia bassa (smartwatch,…);
- Consumo energetico basso;
Esecuzione dell’istruzione
- Fetch dell’istruzione (lettura);
- Decodifica dell’istruzione;
- Esecuzione dell’istruzione.
Quando queste 3 operazioni sono scollegate, possono essere messe in una pipeline. Possono essere sfasate in un blocchetto in modo da consentire l’esecuzione, ad ogni ciclo di clock, di una nuova istruzione.
Pipeline
Le 3 parti fondamentali della pipeline sono: FETCH, DECODE e EXECUTE. Questo succede in campo ideale. Nel campo reale vedremo anche istruzioni che hanno bisogno di più di un ciclo di clock, perché magari devono accedere a parti particolari in memoria oppure alcune istruzioni richiedono che sia finita l’istruzione precedente o successiva. La pipeline ha uno stallo, c’è un momento in cui non abbiamo output di esecuzione per ogni ciclo. La minimizzazione degli stalli sta alla bravura del programmatore.
Advantage RISC Machine (ARM)
È un’azienda che fornisce il design di diverse architetture basate su instruction set risc. L’architettura utilizzata da noi è la Cortex-M4.
Caratteristiche processori Cortex della famiglia M
Cortex M0 (ARMv6-M):
- Numero gates logici molto basso (12 k);
- Consumo energetico molto basso (3 µW/Mhz);
- Architettura a 32 bit.
Cortex M1 (ARMv6-M):
- Il primo processore disegnato specificamente per implementazioni in FPGA;
- Facile migrazione da FPGA a ASIC.
Cortex M3 (ARMv7)
- È il processore mainstream della famiglia, molto simile all’M4, dove abbiamo l’espansione per le istruzioni DSP, un clock un po’ più veloce e un po’ più di spazio nella memoria.
- Instruction set Thumb e Thumb-2 (lunghezza variabile a 16 o 32 bit).
- Ha un hardware per la divisione e vi è la possibilità di fare la moltiplicazione in un solo ciclo di clock.
- Ha una BUS MATRIX che ha un’interfaccia sia per i codici che per i dati che si collega a 2 bus:
- AHB bus: bus per periferiche che richiedono una certa velocità (es. memorie interne)
- APB bus: protocollo molto snello che permette di gestire bene periferiche, come quelle di comunicazione, più lente e semplici e permettono di avere una circuiteria più leggera.
- Il processore Cortex M3 è basato sull’architettura Harvard, ha 2 bus separati, uno per code e uno per dati e può abilitare il fetch e lo store in parallelo.
- La PIPELINE di questo processore è a 3 stadi:
- Fetch;
- Decode: vengono codificate le istruzioni e vengono letti i registri;
- Execute: comprende la parte di indirizzamento, ALU, shift di operazioni.
Cortex M4
- Rispetto un M3 ha un core che comprende un set di istruzioni più avanzato (orientato a un calcolo più digitale, DSP);
- Supporta l’I.S. (Thumb/Thumb 2);
- Abbiamo il supporto della FPU (Floating Point Unit) che permette di gestire i numeri con la virgola mobile;
- Pipeline a 3 stadi + branch specilation;
- Guadagno prestazionale più alto (soprattutto nel calcolo di istruzioni complesse)
- Esistenza MTU (Memory Protection Unit): regioni di memoria che non possono essere sovrascritte per errore;
- Sistema ottimizzato per applicazioni low power tramite l’utilizzo della sleep mode;
- Manipolazione di alcuni bit: in alcune zone è possibile usare il bit banding.
Cortex M7
- Più potente e complicata della M4;
- Gestisce una data cache;
- Ha una pipeline più lunga;
- Ha un guadagno di performance di 2 volte della M4;
- Possono essere usate applicazioni a 64 bit.
Cortex M4 vs M3
- Nell’ M4 sono presenti le estensioni per le istruzioni DSP (Digital Signal Processing);
- È anche presente l’FPU.
Codifiche ARM, Thumb e Thumb2
Una delle caratteristiche fondamentali dell’architettura ARM è la codifica delle istruzioni. Vi sono 3 tipologie di codifica:
- ARM: istruzioni codificate e 32 bit;
- Thumb: istruzioni codificate a 16 bit. È un tipo di codifica che permette di raddoppiare la quantità di istruzioni che possiamo immagazzinare in memoria. Non può però immagazzinare tutto l’instruction set perché alcune istruzioni sono a 32 bit e quindi viene introdotta la codifica
- Thumb 2: permette di switchare la codifica da 16 a 32 bit.
Programmer’s model
Sono le risorse disponibili al programmatore per eseguire le istruzioni. È definita da 2 parti fondamentali:
- Modalità d’esecuzione del processore;
- Registri;
Processore modes
Nella modalità del processore possiamo distinguere:
- Modalità non privilegiata: è la modalità di esecuzione classica in cui generalmente viene eseguita un’operazione. È una modalità nella quale non vengono concesse all’utilizzatore, al codice da eseguire, alcuni privilegi, come quello di poter modificare alcune zone di memoria o di accedere ad alcuni registri speciali.
- Modalità privilegiata: viene utilizzata per gestire le eccezioni.
L’ARM ha 7 modalità di funzionamento, che si suddividono in 2 macrocategorie: PRIVILEGIATA e NON PRIVILEGIATA. Operativamente allo start siamo in THREAD MODE e quando il processore parte, essendo nel main dell’esecuzione e abbiamo tutti i privilegi. Non vi sono problemi nello switchare dalla modalità privilegiata alla non privilegiata. Invece passare dalla modalità non privilegiata a quella privilegiata non è possibile, se non attraverso un interrupt. Es. eseguiamo un’eccezione, un interrupt, il processore entra in modalità privilegiata e quando usciamo dall’eccezione possiamo scegliere in quale modalità proseguire. Nello STATO DI DEBUG il processore viene congelato e possiamo accedere ai registri.
Registri
Nell’architettura ARM, nel Cortex-M3 e M4 abbiamo 31 registri general purpose a 32 bit, di questi 16 sono visibili: R0-R15. Gli altri registri sono nascosti e servono, durante l’esecuzione delle varie istruzioni, per aumentare l’efficienza del processore.
- R0-R12 -> General purpose (esecuzione delle istruzioni)
- Tra R0-R12 abbiamo una distinzione:
- R0-R7 -> LOW REGISTER, sono i registri che vengono usati nell’ I.S., utilizzati da Thumb e Thumb2;
- R8-R12 -> HIGH REGISTER, sono quelli utilizzabili solo da Thumb2 ;
- R13 -> STACK POINTER (SP) che ha:
- MSP (Main Stack Pointer), può essere usato sia in Thread mode, che in Headermoden (ovvero sia in gestione degli interrupt che in gestione normale);
- PSP (Process Stack Pointer), può essere usato solo in Thread Mode.
- R14 -> LINK REGISTER (LS)
- Viene usato per mantenere il return address (indirizzo di ritorno) quando chiamiamo una funzione. Alla fine dell’esecuzione della funzione presente nel codice, il programma automaticamente carica il valore del LR all’interno del PC. Quindi permette di poter riprendere l’esecuzione del programma dal punto dove si era interrotto per permettere l’esecuzione della funzione.
- R15 -> PROGRAM COUNTER (PC)
- Registro che contiene l’indirizzo del quale vengono fetchate le istruzioni. È un registro particolare che possiamo sia leggere che scrivere.
- Registi speciali
- Servono principalmente per il controllo del processore, come es. la modalità nella quale ci troviamo, in particolare questi registri sono:
- XPSR;
- PRIMASK;
- FAULTMASK;
- BASPERI;
- CONTROL.
XPSR: È un registro 32 bit che contiene 3 campi: APPLICATION (APSR), execution (EPSR), interrupt (IPSR). Fondamentalmente questo registro fornisce e mantiene i flag per il processing logico/aritmetico (es. carry, riporto).
Control register: È il registro che dai 32 bit vengono usati solo gli ultimi 3 bit (0,1,2):
- Il bit 2 ci dice se l’FPU viene usata;
- Il bit 1 ci dice quale dei registri SP (se Main o process) viene usato;
- Il bit 0 ci dice se siamo in modalità privilegiata o non.
PRIMASK: Disabilita tutti gli interrupt per i processi time critical. Possiamo disabilitare tutti i registri tramite il non mascherabile.
BASEPRI: Consente di mascherare eccezioni e interrupt in base al livello di priorità.
Pipeline
La pipeline di Cortex-M4 è a 3 stadi:
- FETCH: l’istruzione viene letta dalla memoria e piazzata all’interno del registro della pipeline. È una semplice operazione di accesso alla memoria.
- DECODE: interpretano il dato (istruzione). Il core viene predisposto all’esecuzione dell’istruzione.
- EXECUTE: viene letto il register bank e tutti gli operandi che sono stati sistemati nella fase di decode vengono spostati nell’ALU dove vengono eseguite le istruzioni delle operazioni.
Ad ogni istante potremmo avere 3 istruzioni differenti, ognuna delle quali occupa uno stadio differente della pipeline, sapendo che ogni istruzione dura un ciclo. Detto ciò, sappiamo la latenza = 3 cicli. Ci sono delle eccezioni, perché non tutte le istruzioni possono essere eseguite in un singolo ciclo, alcune più complesse richiedono istruzioni multiciclo e di branches dove la pipeline viene svuotata e poi riempita con la nuova istruzione.
Prefetch unit (PFU)
All’interno dello stadio di fetch della pipeline è molto importante perché ha due funzioni fondamentali:
- Rileva quale tipo di instruction set stiamo usando (Thumb/Thumb2, 16 o 32 bit);
- Gestire il caricamento delle istruzioni preparandola per la fase di decode.
Un altro importante compito della FPU è quella che definiamo branch speculation. La nostra prefetch quando incontra un’istruzione di branch deve fare una scelta e lei automaticamente prende per vero che il branch sia vero e carica la pipeline con le relative istruzioni successive. Nel caso non sia vero la pipeline viene svuotata e vengono caricate le istruzioni del caso non vero del branch.
Con questa modalità, se io ho un ciclo for di 100 cicli, avrò che in 99 cicli la prefetch ci becca e 1 volta no.
Istruzioni
In un instruction set ci sono 3 tipi fondamentali di istruzioni:
- Data processing (add, mul): sono istruzioni che vengono svolte normalmente in un singolo ciclo di clock;
- Data transfer (MEM -> processore, processore -> MEM): questo tipo di operazioni vengono svolte invece in due cicli di clock. Nel primo ciclo viene letto l’indirizzo e nel secondo viene svolta l’operazione di load o store del dato;
- Branch (jump, call): in questa tipologia di istruzione solitamente occorrono 3 cicli di clock per essere completata. Nel 1° ciclo viene caricato il branch target. Nel 2° ciclo viene caricato il return address e nel 3° ciclo bisogna portare la pipeline all’esecuzione del caso in cui il branch non sia stato preso ed effettuare le correzioni al link register.
Memoria stack
È un tipo di memoria LIFO (Last in- first out) utilizzata tipicamente per lo storage di dati locali e possiamo immagazzinare i 16 registri general purpose all’interno. Possiamo usarlo per congelare lo stato del processore nel caso della gestione di un interrupt. Lo stack viene gestito tramite le istruzioni assembly che usa solo le istruzioni push e pop. La politica di gestione dello stack è FULL DESCENDING:
- PUSH: è l’istruzione che carica qualcosa sullo stack;
- POP: è l’istruzione che toglie un valore dallo stack.
Tecnicamente:
- PUSH -> decrementa lo SP e carica il valore alla cella puntata dello SP;
- POP -> legge l’indirizzo puntato dello SP, il valore a quell’indirizzo lo mette all’interno di un registro interno suo e poi incrementa lo SP.
Bit banding
Programmando nei sistemi embedded è utile poter accedere e modificare i singoli bit. Quando accediamo a dati a 32 bit nei registri non abbiamo nessun problema, utilizzando l’indirizzamento della memoria. Però può capitare di dover settare, per esempio il control register, il quale dispone di bit singoli che ci dicono ad esempio se stiamo operando in modalità privilegiata o meno. In questi casi abbiamo 2 approcci: operazioni bit a bit (standard) e bit banding.
- Le operazioni bit a bit (formate dall’&, |, ~), che sono tutte le operazioni logiche che si possono eseguire nel nostro microcontrollore. L’unico problema è la scarsa versatilità di questo approccio, perché ogni volta bisogna cercare una maschera, al singolo bit;
- Bit banding: tecnica applicata ai microcontrollori, dove fondamentalmente ci consente di accedere con lo spazio di indirizzamento classico al singolo bit.
La bit band region (presente sia nella memoria SRAM, che in quella delle periferiche) è una parte della memoria in cui funziona il bit banding dove in quel Mb di memoria è possibile gestire il singolo bit. In pratica, per poter gestire ogni singolo bit della memoria da 1 MB (bit band region) sfrutto una memoria da 32 MB (bit band alias) dove ogni cella rappresenta un alias del bit della memoria da 1MB. Per usare il bit banding bisogna trovare la mappatura tra il bit del bit band region e il suo alias.
Instruction Set Architecture (ISA)
Il design dell’ISA è una delle parti più importanti dell’architettura di un processore. Inizialmente ARM aveva il suo instruction set, chiamato ARM. Era inizialmente un buon instruction set, che supportava esecuzioni e branch condizionali e forniva un buon livello di performance per un buon processore a 32 bit. Il problema principale nell’utilizzo di questo i.s. era lo spazio di memoria occupato, perché essendo basato su 32bit, occupava molto spazio in memoria.
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.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.