I microcontrollori
I sistemi meccatronici integrano all’interno del dispositivo meccanico/fisico di interazione una parte
di elettronica analogico digitale che ne consente l’utilizzo/controllo ad alto livello (sistema
embedded). La particolare integrazione di meccanica/elettronica realizzata in un sistema di questo
tipo consente di ottimizzare ulteriormente i vincoli di progettazione in maniera da produrre sistemi
compatti altamente performanti.
Definizione di microcontrollore
Un controllore è una dispositivo logico utilizzato per i processi di regolazione dei sistemi
nell’ambiente. Applicazioni tipiche possono essere sistemi di servoguida in automobile, il controllo
delle testine e dei motori in un videoregistratore, termostati di ambiente o altro. Nel passato i
controllori erano costruiti tramite componenti discreti, dapprima meccanici, poi elettromeccanici,
quindi con dispositivi semielettronici (ad esempio relé a stato solido). In seguito con l’avvento dei
microprocessori, e grazie alla loro flessibilità molti sistemi di controllo sono stati realizzati con
piccole schede di controllo composte dall’integrazione della logica di calcolo offerta dal
microprocessore con le relative componenti necessarie al suo funzionamento (memoria, dischi,
clock,...) ed alla sua interazione con l’ambiente (periferiche di acquisizione dati, di attuazione, e di
comunicazione e controllo remoto). Man mano che questo processo di inegrazione e
miniaturizzazione è continuato, tutte queste componenti sono state integrate in un unico dispositivo.
Un microcontrollore è un chip integrato che include in sè molte delle componenti necessarie per la
realizzazione di un sistema di controllo. Da un punto di vista computazionale, un microcontrollore è
analogo ad un mocroprocessore (possiede una Central Processing Unit ed esegue istruzioni a
controlloo di programma su una memoria dati), ma rispetto a quest’ultimo esso si differenzia per un
certo numero di funzionalità integrate:
• Integrazione della memoria di programma: spesso in forma di EEPROM, ma sempre più di
frequente in PROM, ROM o FLASH, questi dispositivi hanno tutti una memoria statica di
lunga durata, che sopravvive agli spegnimenti e riaccenzioni ed in grado di conservare il
processo/programma di controllo da eseguire per tutto il tempo necessario. L’integrazione
della memoria programma nel dispositivo consente la rimozione delle memorie fisse esterne
(Dischi, ROM, altro) riducendo l’ingombro ed il costo del sistema di controllo ed
accelerando in tal modo la prontezza del sistema ad eseguire i propri compiti.
•
•
•
Integrazione della memoria dati: la memoria dati, di più frequente accesso, anche se ridotta
in dimensioni (considerati i compiti piuttosto semplici demandati ai microcontrollori) viene
integrata in tutti i microcontrollori. Questa memoria in venere varia da poche decine di byte
a qualche migliaio ed è sufficiente a memorizzare tutti i dati dinamici alla esecuzione dei
processi di controllo.
Integrazione servizi di timing: molti micro integrano degli oscillatori interni in maniera da
poter funzionare anche in assenza di un sistema di oscillazione esterna e richiedere quindi
soltanto la connessione con l’alimentazione ed i dispositivi da controllare.
Integrazione delle periferiche: il numero di periferiche implementate in un microcontrollore
varia tantissimo da caso a caso, tutti i micro comunque integrano almeno delle porte digitali
per il controllo (TTL) di alcune linee esterne. Il numero di periferiche integrate varia con i
piedini disponibili nel package e molto spesso sono riconfigurabili in prospettiva della
applicazione preposta.
E` quindi immaginabile che rispetto ad una archiettura di controllo di sistema organizzata con
microprocessori e periferiche, una architettura equivalente basata su microcontrollori consente di
ridurre notevolmente la complessità dello schema circuitale in quanto molti dei servizi (memoria,
I/O,...) sono inclusi nelle funzionalità base dei micro.
L’integrazione delle funzionalità non è comunque soltanto limitata ad un aspetto fisico (più sistemi
in uno stesso chip) ma molto spesso integrata nella struttura di controllo in maniera da rendere
semplice l’accesso ed il controllo di tutte le periferiche di I/O riducendo in tal modo non solo la
complessità di progettazione elettronica ma anche quella di programmazione digitale.
Resistenza Elettrica
Motore
Valvole
Pompa
Cestello
I-6
I-7
8
a4
b4
7
b3
a3
3
6
b2
2
a2
V c c1
a1
0
mV
10-50
1
Power
Drivers
I-5
MC U Mic r o co n t ro l le r
b1
5
I-3
P-10
I-8
4
0-100
deg
I-9
Struttura di funzionamento di una Lavatrice
In figura viene rappresentato l’impego di un sistema a microcontrollore per il controllo della
elettronica di potenza e non in una lavatrice. Tutti gli elementi di controllo e display (manopole e
led/display) sono connessi direttamente ad un microcontrollore centrale, mentre la parte di
elettronica di potenza (motora, valvole, scaldatore, pompa) sono interconnesse allo stesso
processore tramite un sistema di condizionamento dei segnali che consente di governare le singole
componenti tramite l’I/O disponibile nel microcontrollore (Nello schema sono stati tralasciate le
alimantazini dei sistemi).
Compito del microcontrollore in questo caso sarà quello di coordinare gli elementi necesari per il
lavaggio in funzione delle opzioni regolate nei controlli (tipo di lavaggio, temperatura, velocità
della centrifuga e così via).
Per la realizzazione del sistema di controllo sarà necessario:
1. definire il comportamento del sistema in funzione della programmazione espressa tramite le
manopole e dello stato corrente del lavaggio
2. Codificare il comportamento del sistema in base ad un insieme di regole temporali.
3. Definire le operazioni e la relativa sincronizzazione delgi elementi di potenza che
effettueranno il lavaggio
4. Implementare la sequenza di stimoli necessaria per ottenere la sincronizzazione
5. Scrivere il programma di controllo da eseguire sul microcontrollore perché tale sequenza di
stimoli sia correttamente prodotta ai piedini del microcontrollore.
Struttura di un Microcontrollore
La struttura di un microcontrollore (Micro Control Unit = MCU) è per certi versi simile a quella dei
microprocessori (MPU) con i quali condividono la struttura logica di calcolo base.
Il cuore dell’unità di calcolo di una MCU è costituito da:
• Registri
•
•
•
•
•
•
Unità logico aritmetica
Contatore di programma
Unità di fetch
Decodificatore di istruzioni
Memorie (dati, programma e dati statici)
Moduli di I/O
In figura è rappresentata una possibile organizzazione generale di un microcontrollore (sebbene
molte poi siano quelle reali) da cui si intravede come queste componenti siano interconnesse.
In un microcontrollore, tutte le unità principali comunicano mediante un BUS (4,8,16,32 bit) le cui
dimensioni sono poi connesse con quella che vedremo sarà la tipologia di microcontrollore. Questo
bus, essendo l’unità di trasferimento base per tutti i dati, è collegato alla capacità di manipolare le
informazioni all’interno del microcontrollore.
Quando ci riferiermo a microcontrollori a 8 bit, intenderemo che la capacità di gestione dati del
microcontrollore è organizzata su strutture delle stesse dimensioni e quindi anche il BUS interno
dovrà possedere le medesime linee.
Le componenti in figura sono divise in due gruppi: alla destra del BUS tutte le componenti I/O
modulari che offrono le funzionalità di controllo, alla sinistra la parte dedicata all’elaborazione delle
informazioni.
La divisione non è solo grafica ma anche funzionale nel senso che ogni periferica comunica con la
parte di calcolo tramite una porzione di memoria accessibile sul BUS e visibile nello spazio di
memoria del processore.
Programmare un dispositivo di IO diventa pertanto accedere in forma, modi e tempi particolari a
determinate zone di memoria.
Il funzionamento dei moduli di elaborazione è invece analogo a quello di un microcontrollore, con
la differenza che le memorie necessarie al funzionamento sono già incluse nella architettura base
(sebbene memorie aggiuntive possono essere connesse dall’esterno). In questo modo il
microcontrollore può divenire un elemento indipendente che funziona quando alimentato e
connesso ad un oscillatore che ne genera il clock (talvolta incluso nel chip stesso).
Il microcontrollore non ha la complessità di un computer, non ci sono firmware e/o sistemi
operativi che ci aiutano a sviluppare il codice, ma si offrono al programmatore semplicemente con
le loro caratteristiche hardware.
Non è pertanto immaginabile di poter scrivere in un microcontrollore codice analogo a quello che
scriveremo per un microprocessore, ad esempio la libreria base del linguaggio “C”, la stdio, in
questo caso non ci servirebbe a nulla, perché non esistono schermi, file o quant’altro necessario per
il funzionamento.
All’accensione un microcontrollore provvede ad eseguire il codice programmato a partire da una
determinata locazione di memoria (usualmente 0x0000) in accordo con il proprio codice
mnemonico di istruzioni (identificato dalla unità di decodifica).
Sebbene il meccanismo di funzionamento sia alquanto universale, per una migliore facilità di
comprensione del funzionamento sembra opportuno specializzarne i contenuti su di una architettura
particolare. Pertanto, per la descrizione dettagliata di come questa fase di esecuzione esecuzione ha
luogo si rimanda al capitolo specifico sui processori ATMEL che introdurranno il problema su
quella determinata tipologia di processore.
Principi di programmazione di un Microcontrollore
I microcontrollori vengono in generale programmati in moltissimi modi: talvolta direttamente
tramite lo sviluppo in codice oggetto, talvolta utilizzando linguaggi di programmazione più
sofisticati (C, C++, pascal, basic,...) e alcune volte addirittura in alcuni casi in linguaggi visuali,
come ad esempio consentono alcuni tools sofisticati di sviluppo.
Programmazione di microcontrollori
Codice Oggetto (Variabile da MCU a MCU)
Linguaggio C/C++
Basic
Linguaggi grafici
Altri
Nonostante l’elevata disponibilità di tools di sviluppo sofisticati, la moggior parte del codice di
programmazione viene sviluppata direttamente in codice oggetto. Ciò è maggiormente dovuto a due
caratteristiche: l’esiguità delle risorse disponibili all’interno di un microcontrollore e la maggior
efficacia (in termini di dimensioni del codice, ottimizzazione dei processi, velocità e consumi) dello
sviluppo del software quando questo viene condotto direttamente nel codice oggetto dei
microcontrollore; analogamente la semplicità dei compiti cui tali microcontrollori sono
generalmente preposti rende semplice lo sviluppo di software in codice oggetto. Inoltre, per i
programmatori esperti, la dimistichezza con lo sviluppo del codice, affiancata alla esperienza ed alle
librerie che gli stessi sviluppatori via via si sviluppano, rendono relativamente poco complicata, la
complessità aggiunta dallo sviluppo in un linguaggio di basso livello come il codice oggetto.
A prescindere dal tipo di linguaggio utilizzato e dal tipo specifico di microcontrollore tutti i sistemi
di questo tipo consentono due tipologie fondamentali di programmazione: la programmazione ad
interruzione e la programmazione a controllo di programma: la programmazione a controllo di
interruzione è associata a delle procedure che il sistema è in grad di eseguire in presenza di eventi
segnalati dalle periferiche predisposte sul microcontrollore. La programmazione a controllo di
programma viene invece svolta ordinariamente dal microcontrollore appena questo viene acceso.
Vale la pena sottolineare che questi tipi di programmazione, sebbene simili a quelle che
ordinariamente siamo abituati a conoscere per i sistemi operativi differiscono profondamente per
semplicità di meccanismo, rendendo quindi possibile la descrizione dei principi di funzionamento
almeno in linea generale. Nessun microcontrollore viene infatti provvisto con un sistema operativo
come nel caso dei personal computer ed ogni tipo di esecuzione sullo stesso verrà dettagliatamente
programmata dal suo sviluppatore.
Appena alimentato tutti i microcontrollori eseguono una porzione di codice predefinita, procedendo
nella sua esecuzione esaminando linearmente lo spazio di istruzioni del programma fino
all’occorrenza di eventi particolari. L’esecuzione del codice può differire leggermente da
microcontrollore ad un altro ed anche all’interno di uno stesso microcontrollore in funzione del tipo
particolare di programmazione effettuata. In tutti i casi, in base a questo principio risulta possibile
definire (codificare) gli algoritmi di controllo del microcontrollore memorizzando le istruzioni in
codice oggetto, a partire dal primo indirizzo di esecuzione per il microcontrollore.
Qualora abilitate (via software o via programmazione), le interruzioni possono sospendere
l’esecuzione ordinaria del programma andando a richiamare delle procedure collocate in indirizzi
specifici e ritornando alla esecuzione dello stesso al temine delle routine di servizio.
Questo meccanismo consente la gestione delle operazioni di controllo collegate ai segnali ricevuti
dalle periferiche minimizzando l’attenzione che è richiesta per sorvegliare le stesse (si parla in
questo caso di controllo attivo tramite polling).
Controllo di programma
Controllo di interruzione
Sleep mode
Meccanismi di controllo esecuzione
L’esecuzione del codice di programma avviene ad eventi specifici
(accensione, risveglio, reset), e prosegue in maniera non continuativa
(in quanto le interruzioni possono sospenderla temporaneamente)
fino a eventi specificati: interruzioni, spegnimento, reset, sleep
L’esecuzione del codice di interruzione non avviene finché alcuni
eventi (interrupt) specifici non vengono segnalati dalle periferiche
L’esecuzione del codice di programma è sospesa mentre alcune
perfieriche (il cui funzionamento è scollegato dal processore)
continuano a lavorare ed eventualmente segnalare la necessità di un
risveglio al processore centrale.
Alcuni microcontrollori (ad oggi quasi tutti) consentono inoltre di far “addormentare” il dispositivo
e risvegliarlo solo in presenza di alcuni eventi da interruzione. Una tale funzionalità consente infatti
di risparmiare energia in tutte quelle applicazioni di controllo dove la stessa è un bene prezioso
(dispositivi portatili, orologi, telefoni, oppure mobili, spaziali, volanti,...).
Lo sviluppo di software per microcontrollori
Lo sviluppo del software per sistemi di questo tipo è molto delicato, l’impossibilità di accedere con
programmi specifici al software ed alla diagnostica del funzionamento dei sistemi integrati rende
critico il processo di sviluppo.
E’ importante rilevare che sviluppare codice per un microcontrollore richiede inizialmente un
grosso impegno in termini di bagaglio di conoscenze da acquisire per la gestione dei dispositivi
integrati e della struttura del codice di esecuzione.
Come per i processori e per i computer in generale, ogni microcontrollore presenta infatti un
“microcosmo” di informazioni che è necessario conoscere per l’esatta generazione del codice di
funzionamento, la sua programmazione ed il suo debug.
In quest’ottica diventare uno sviluppatore di applicativi meccatronici potrebbe apparire un lavoro
immane a prima vista, ma come vedremo (e come sarà meglio chiaro durante il corso), ci sono molti
elementi che ci aiuteranno in questo compito:
1. In primo luogo, ogni produttore di microcontrollori, cerca di sviluppare i propri sistemi in
base ad una famiglia di architetture. Utilizzare il termine famiglia significa che, sebbene
taluni microcontrollori possono risultare differenti, ci sono una serie di elementi “genetici”
che accomunano i diversi membri della famiglia stessa e che facilitano lo sviluppo ed il
porting di applicazioni tra i “parenti”. L’utilizzo di una famiglia è di comodità sia per lo
sviluppatore che in questo modo può apprendere i principi base di programmazione e
muoversi facilmente attraverso tutta la gamma dei prodotti disponibili, sia per il produttore
che può ottimizzare la struttura della famiglia confidando in un ampia gamma di utilizzatori
e che migliorie in un prodotto si riflettono automaticamente su tutta la linea. Tra gli elementi
“genetici” che vale la pena sottolineare: il linguaggio di programmazione e l’architettura
della parte di microprocesso, le periferiche principali, la loro collocazione in memoria ed il
loro utilizzo, l’ambiente semplificato di sviluppo omogeneo per tutti gli elementi della stessa
famiglia;
2. Talvolta come è successo per alcuni microcontrollori particolarmente diffusi, l’architettura
di sviluppo è aperta, consentendo la costituzione di una famiglia che non è più limitata ad un
solo produttore ma diffusa largamente tra più fornitori;
3. Inoltre, come verrà descritto in seguito, ogni famiglia di microcontrollori viene supportata
da una serie di tools di sviluppo, molto spesso forniti dallo stesso produttore e talvolta
provvisti da compagnie di supporto. Tali strumenti consentono un accesso ed uno sviluppo
semplificato del codice e delle infrastrutture necessarie per integrare un sistema
microcontrollato, consentendo la simulazione, il debug, e lo sviluppo in un ambiente
facilitato (talvolta in C, C++ o strumenti grafici) e lasciando che lo sviluppatore si concentri
esclusivamente sugli obiettivi funzionali che gli interessa perseguire senza curarsi dei
dettagli dell’implementazione software.
Al fianco degli ambienti integrati di sviluppo (IDE) che comprendono simulatori, compilatori ad
alto livello, e talvolta anche tool di sviluppo grafico (ad icone, simile a quanto disponibile per
Matlab), risulta spesso utile la disponibilità di un sistema di verifica rapida. Le schede di sviluppo
sono dei sistemi elettronici assemblati che includono al fianco di un microcontrollore un numero
ampio e variegato di interfacce di interazione connesse con le periferiche del microcontrollore. Ad
esempio led e puldanti possono essere connessi alle porte digitali, le porte seriali sono adattate per
la comunicazione con personal computer, gli ingressi analogici sono forniti di connettori di
semplice utilizzo. Le schede di sviluppo in sostanza consento no di sperimentare il funzionamento
del proprio codice anche in assenza di un vero e proprio progetto hardware di sistema.
Le schede di sviluppo possono essere offerte dalla stessa casa produttrice (come avviene nel caso
microchip, atmel, oppure possono essere offerte da produttori di terze parti come nel caso
thompsom ad esempio).
Anche per ciò che concerne il software di sviluppo una buona parte delle case produttrici si
impegnano per corredare i proprio prodotti con compilatori, assemblatori e debugger, anche se
spesso questo tipo di lavoro richiede lo sviluppo di competenze e la manutenzione di prodotto che
molto spesso possono andare oltre le specifiche competenze del produttore. Per questo motivo molti
produttori si affidano ad aziende di terze parti che per i loro sistemi producono la linea di sviluppo
più idonea. Detti produttori (come la keil, la IAR ed altri) possono infatti trarre valore aggiunto
dalla specializzazione ottenuta sull’ambiente di sviluppo a prescindere dal tipo particolare di
microcontrollore di riferimento. Altri produttori ancora si affidano all’adozione di particolari
standard di architetture che possono usufruire di prodotti di sviluppo già presenti sul mercato
(philips, atmel, toshiba, siemens, samsung) e facendo così affidamento sulla possibilità per gli
sviluppatori di riutilizzare sistemi di sviluppo e standard ormai acquisiti.
La programmazione dei processori ATMEL
La scelta di utilizzare il microcontrollore ATMEL come riferimento nel corso di meccatronica è
attualmente legata alla relativa disponibilità di un’ampio insieme di strumenti di sviluppo, ad
un’attivo gruppo di interesse di riferimento di accesso pubblico per la ricerca di informazioni, al
costo relativamente ridotto dei sistemi e del ambiente di sviluppo.
In particolare per noi sarà di rilevante interesse la possibilità di accedere al microcontrollore a tre
differenti livelli: architettura di sistema a microcodice di programmazione, programmazione in
linguaggio C, programmazione tramite il real time workshop di matlab.
La struttura e le caratteristiche generali sono rappresentate in figura. Nella struttura AVR a otto bit
ogni processore possiede 32 registri di otto byte ciascuno sui quali si può operare mediante un set di
133 istruzioni. La maggior parte di queste istruzioni esegue in un unico ciclo di processore
consentendo in tal modo un elevato flusso di operazioni.
Le principali periferiche comprendono:
1) due timer/contatori a 8 bit dotati di prescaler separati e di comparatori
2) due timer separati a 16 bit con prescaler e comparatori separati
3) 6 canali modulabili in PWM con risoluzione variabile da 2 a 16 bit
4) 8 convertitori Adc a 10 bit ciascuno
5) Porta seriale SPI
6) Interfaccia seriale a due linee
7) 2 USART bidirezionale
8) Watchdog Timer
9) Comparatore analogico
In più l’atmega 128 offre le seguenti caratteristiche particalri: memoria di programma 128KB, 4KB
EEPROM, 4KB SRAM, 53 linee di IO.
I registri di sistema
Il comportamento del processore (come macchina a stati di tipo complessa) è regolato non solo
dalle istruzioni in codice macchina che esso incontra ma anche da un insieme di registri particolari.
Trentadue registri utente sono a disposizione dell’utente, ogni volta che il programmatore avrà
bisogno di manipolare dei dati egli potrà farlo tramite l’utilizzo dei dati nei registri del
microcontrollore. I registri sono corrispondenti alle prime trentadue locazioni di memoria ram ma
sono indirizzabili direttamente dal linguaggio assembler. I trentadue registri possono essere
utilizzati come registri di input/output indipendenti per operazioni a 8 bit, oppure, in maniera
combinata come registri di IO su operazioni a 16 bit. Gli ultimi sei registri possono inoltre essere
utilizzati come puntatori a 16 bit per le operazioni di accesso indiretto in memoria.
I core dei microcontrollori si dividono in due grandi categorie, quelli basati sull’accumulatore e
quelli basati sui registri. Nei core basati sull’accumulatore esiste un registro di tipo particolare,
denominato accumulatore appunto in gradi di effettuare un numero più esteso di operazioni, in
particolare le operazioni matematiche. Nelle altre categorie invece tutti i registri sono equivalenti in
termini di programmazione (approccio risc based). Tutte le operazioni possono essere effettuate
tramite la memoria, la ALU ed i registri a disposizione del programmatore.
A seconda del tipo di operazione i registri X, Y, Z, possono essere dotati di funzioni particolari
come ad esempio l’incremento automatico oppure il decremento automatico.
Il registro di stato (STATUS REGISTER) contiene le informazioni relative al risultato delle
istruzioni eseguite più di recente ed è aggiornato ogni volta che la ALU effettua qualche
elaborazione tra i registri.
Gli otto bit del registro di stato hanno le seguenti caratteristiche:
bit
Name
POV
7
I
RW
0
6
T
RW
0
5
H
RW
0
4
B
RW
0
3
V
RW
0
2
N
RW
0
1
Z
RW
0
0
C
RW
0
• Bit 7 – I: Global Interrupt Enable: quando questo bit viene messo a zero nessuna interruzione potrà
sospendere il flusso di programma del processore, il bit viene messo a zero automaticamente durante
l’esecuzione delle procedure di interrupt e ripristinato a 1 dall’istruzione RETI, ma può anche essere
controllato manualmente con le istruzioni SEI e CLI.
• Bit 6 – T: Bit Copy Storage Il bit T viene utilizzato in tutte le istruzioni del processore che operano con un
bit implicito (sorgente o destinazione) di riferimento (BLD e BST).
• Bit 5 – H: Half Carry Flag E il bit di semiriporto, utilizzato per vedere se un riporto è stato generato da o
verso il nibble basso del registro su cui si effettua l’operazione. Utile spesso nelle operazioni che richiedono
l’uso di Binary Coded Decimal.
• Bit 4 – S: Sign Bit, S = N . V Bit del segno
• Bit 3 – V: Two’s Complement Overflow Flag Overflow in modalità di complemento a due
• Bit 2 – N: Negative Flag Bit di risultano negative
• Bit 1 – Z: Zero Flag Bit di zero, settato ogni volt ache il risultato dell’ultima operazione è zero
• Bit 0 – C: Carry Flag Bit del riporto
Nota: il set di istruzioni di processori che operano a 8 bit è molto elementare, esso prevede, somme
sottrazioni e shift di elementi tutti a 8 bit. Per la estensione delle operazioni pensate su 8 bit a
formati matematici più complessi risulta necessario provvedere alcuni bit (N, S, V, Z, C) che
indicano (operazione per operazione) ogni volta che durante una operazione un’evento di tipo
particolare sia accaduto (riporto, zero,...).
Come vedremo tra le operazioni di un microprocessore, oltre alle operazioni matematiche
esisteranno alcune operazioni di controllo flusso molto elementari (salti condizionati) che
consentono la gestione del flusso ogni volta che ho un riporto, un risultato nullo o altro.
Lo stack, anche detta pila, è una porzione di memoria utilizzta per la conservazioni di tati
temporanei, ad esempio memorizzare il valore di rientro di una procedura oppure le variabili da
ritornare al chiamante. Il puntatore allo stack è un registro che punta sempre alla cima dello stack
(si noti che in questo caso lo stack è implementato come crescente dalla direzione più alta verso la
più bassa, questo impleca che l’inserimento di qualcosa nello stack faccia diminuire il valore del
puntatore).
La memoria dello stack viene collocata nella memoria SRAM del MCU e il suo valore è
inizializzato dal programmatore in funzione delle proprie esigenze. Ovviamente esso dovrà puntare
come valore minimo di partenza sopra l’ultima delle locazioni riservate al processore (0x60). Il
puntatore allo stack è implementato come una coppia ri registri (SPH, SPL) ad otto bit, nei
microcontrollori con meno di 256 byte di memoria solo SPL sarà utilizzato. Il valore iniziale di
questi registri è posto a zero e sarà cura del programmatore inizializzarli come dovuto.
La piedinatura di alcuni AVR
La piedinatura dei microcontrollori Atmel cambia da dispositivo a dispositivo, ed anche all’interno
dello stesso dispositivo essa può variare in funzione del tipo particolare di package adottato per il
sistema. In aprticolare vedremo di seguito due dei microcontrollori base della famiglia AVR: l’8515
(probabilmente il più usato) e l’Atmega 128, attualmente il TOP della gamma disponibile.
L’Atmega128 è attualmente disponibile in un package di 64 piedini a montaggio superficiale,
mentre l’8515 è disponibile nel classico (e più maneggevole) DIL40.
I relativi piedini corrispondono a porte digitali di ingresso uscita (nel casopiù semplice), ovvero a
delle funzioni ausiliarie, configurabili porta per porta in funzione delle funzionalità necessarie. Più
avanti verrà mostrato come sia possibile configurare le porte singolarmente oppure abilitare le
funzionalità desiderate.
Descrizione della piedinatura
L’Atmega 128 è un dispositivo dotato di 64 piedini corrispondenti a 7 porte (A, B, C, D, E, F, G)
per la gestione dei segnali di controllo e alcuni piedini con finalità differenti descritti di seguito:
VCC (2)
GND (3)
Porta A (PA7..PA0)
Porta B (PB7..PB0)
Porta C (PC7..PC0)
Porta D (PD7..PD0)
Porta E (PE7..PE0)
Porta F (PF7..PF0)
Porta G (PG4..PG0)
Avcc
Aref
PEN
XTAL1
XTAL2
RESET
Tensione di alimentazione
Massa
La porta A è una porta di IO digitale comprensiva di resistori di
pullup (selezionabili separatamente bit per pbit). La porta A ha
caratteristiche di DRIVING completamente simmetriche con
alte correnti di sinking e sourcing. Quando sono ingressi i pin
della porta A condotti a zero genereranno corrente fino a
quando i relativi resistori di pull up non saranno disabilitati. I
PIN della porta A sono in alta impedenza (TRISTATE) al reset
anche se il clock non fosse attivo.
La porta B ha caratteristiche analoghe alla porta A.
La porta C ha caratteristiche analoghe alla porta A.
La porta D ha caratteristiche analoghe alla porta A.
La porta E ha caratteristiche analoghe alla porta A.
La porta F serve per il convertitore AD, alternativamente se il
convertitore è disabilitato essa può servier come le porte di IO
digitali. Quando l’interfaccia JTAG è attiva i suoi pin possono
essere utilizzati per la programmazione ed il debug.
La porta G ha caratteristiche analoghe alla porta A.
Alimentazione Analogica, viene usato per i piedini del
convertitore analogico, e deve essere connesso a Vcc con un
filtro passa basso, anche quando il convertitore non viene
utilizzato.
Alimentazione di riferimento convertitore Analogico
Programming ENAble
Piedino di alimentazione del quarzo esterno
Piedino di alimentazione del quarzo esterno
Segnale per il ripristino del funzionamento del processore
Tutti i piedini delle varie porte, oltre ad avere la funzionalità base di servire come terminali di IO
digitale possono essere utilizzati per altre funzioni specifiche come spiegato più avanti.
La programmazione in codice oggetto
Per la programmazione in codice oggetto, bisognerà fissare alcune convenzioni riportate nella
seguente tabella e che saranno utilizzate nello spiegare le istruzioni di sistema:
Rd
Rd
R
K
k
b
s
X,Y,Z
A
q
Registro di destinazione (o sorgente) nel file dei registri
Registro sorgente nel file dei registri
Risultato a seguito della operazione
Dato costante
Indirizzo costante
Bit nel file dei registri oppure registro di I/O (3bit)
Bit nella parola di stato
Registri utilizzati per l’indirizzamento indiretto dei dati, su 16 bit ciascuno, consistono
di due registri ciascuno: X=R27R26, Y=R29R28, Z=R31R30
Indirizzo nello spazio di I/O
Indirizzo diretto 6bit
I registri RAMPX, RAMPY e RAMPZ (X,Y,Z) si possono utilizzare come puntatori ad una ram
esterna ed abilitano l’indirizzamento indiretto all’intero spazio di dati sui microcontrollori con più
di 64KB di spazio dati oppure la raccolta delle costanti sui microcontrollori con più di 64KB di
spazio memoria per i programmi. In particolare, ad esempio, l’Atmega128 è il primo dei MCU Avr
con più di 64Kb, essendo i registri puntatore di 16 bit essi possono indirizzare soltanto 64KB di
memoria per volta. Il registro di paginazione della memoria programm RAMPZ nel suo bit più
basso viene utilizzato per identificare se si interessa accedere ai primi 64KB oppure alla pagina di
memoria flash seguente. Gli altri bit (1-7) sono attualmente riservati, essi si leggono come 0 e
vanno scritti a 0. In futuro potranno essere usati per gestire quantità ancora più grosse di memoria.
Sui processori AVR, esistono differenti categorie di istruzioni a seconda di come questi operano sui
registri e/o sulla memoria. I tipi di istruzione sono definiti invece dalla seguente tabella:
Tipo di istruzione
Organizzazione
Istruzioni dirette a registro singolo (OP,Rd)
Istruzioni dirette a dure registri (Op, Rr, Rd)
Istruzioni dirette nello spazio di I/O (Op, Rd/Rr, A)
Indirizzamento dati diretto (Op, Rr,Rd, DataAddr)
Indirizzamento dati indiretto, con disp (Op, Rr,Rd,q)
Indirizzamento diretto dati memeotia (Op, MSB, LSB)
Salti indiretti in memoria
Salti relativi: Opcode, k
11 bit di opcode e 5 bit per il registro
6 bit di opcode e 5+5 bit per identificare i due registri
5 bit opcode, 5 bit registro, 6 bit indirizzo memoria
11 bit di opcode, 5bit registro, 16 bit indirizzo
5 bit opcode, 5 bit Reg, 6 bit q
10 bit opcode, 22 bit indirizzo
Z è usato come nuova locazione
PC=PC+1+k, k è di 12 bit, complemento 2
Durante le istruzioni, una serie di queste possono avere un indirizzamento indiretto implicito, in
questo caso una serie di regole viene utilizzata per determinare sia la corretta locazione della cella
indirizzata, sia l’aggiornamento dello stato dei registri in funzione del tipo di opcode utilizzato. La
seguente tabella riassume le relazioni principali nel controllo dell’indirizzamento:
Tipo di istruzione
Organizzazione
Indirizzamento dati indiretto
Indirizzamneto indiretto con predecremento
Indirizzamento indiretto con post-incremento
X,Y,Z vengono usati come indirizzi (?)
A(T) = (R(T)-1) , R(T+1) = R(T)-1 R=X,Y,Z
A(T) = R(T), R(T+1) = R(T) + 1
R=X,Y,Z
Indirizzamento costante in memoria programma
Indirizzamento costante memoria e post incremento
Si usa RAMPZ, Z in maniera indiretta
A(T) = R(T), R(T+1) = R(T) + 1
R=RAMPZ,Z
NOTA1: Istruzioni dirette nello spazio di I/O, nei microcontrollori come l’Atmega128 aventi più di
64 byte di I/O memory (6 bit) il restante spazio di I/O potrà essere acceduto come se fosse un
indirizzamento dati (e non memoria).
NOTA2: nell’indirizzamento dati indiretto con displacement il valore nello spazio dati viene
sommato (a seconda dell’opcode) al valore contenuto nella memoria indirizzata dai registri Y o Z,
consentendo in tal modo un indirizzamnto indiretto parametrico
NOTA3: come detto in precedenza, nell’indirizzamento indiretto (con il registro Z) nello spazio di
memoria, quando configurato il bit di memoria estesa (ELPM) il registro RAMPZ estenderà
(completera) l’insirizzo.
Di seguito verrà analizzato sommariamente l’elenco delle istruzioni in codice oggetto (codice
assembler) che può essere utilizzato nell’ambiente di sviluppo (per essere precisi, ciò che viene
riportato è il codice assembler, che è collegato al codice oggetto dalle tabelle di conversione deglio
OPCODES in codic macchina).
L’elenco riportato distingue le istruzioni assembler in categorie a seconda della tipologia di
operazioni che essi effettuano:
•
•
•
•
•
Operazioni aritmetiche
Operazioni di salto condizionato
Operazioni di trasferimento dati
Operazioni sui bit
Operazioni di controllo del microprocessore.
Le operazioni aritmetiche comprendono somma (ADX), sottrazione (SBX), AND e OR logici,
operazioni di complemento, operazioni sui bit, incremento e decremento ed un ampio numero di
moltiplicazioni tra numeri con segno e senza segno, con frazioni o senza frazioni.
Non tutti i registri possono essere utilizzati in tutte le operazioni, ed in particolare, mentre le
istruzioni di accesso nello spazio di I/O sono generalmente scritte per funzionare bene solo sulle
locazioni di memoria di I/O più basse e risultano inadeguate per gli ultimi processori Atmega con
256 byte di spazio di input output.
A piede di ogni tabella di istruzioni sono riportate le istruzioni con limitazione sui registri e/o sui
valori indirizzati. Nella legenda d,r saranno utilizzati per indicare i registri consentiti, A gli spazi di
indirizzamento nello spazio dei dati, K lo spazio di indirizzamento nello spazio di indirizzi di
programma.
Le istruzioni matematiche che riportano una qualche limitazione sui registri e/o gli indirizzi
possibili sono le seguenti:
LDI, CBR, CPI, ANDI, ORI, SBR, SBCI, SUBI,
d
= [16, 31] , K=8bit
FMUL, FMULS, FMULS, MULSU,
d,r = [16, 23]
SBIW, ADIW
d
= 24, 26, 28, 30, K=6bit
SER
d
= [16, 31]
MULS
d,r = [16, 31]
Quasi tutte le istruzioni aritmentiche che supportano l’indirizzamento diretto degli operandi sono
limitate ai registri da 16 a 31. Tali registri sono preferibili per l’utilizzo di operazioni di
elaborazione matematica, mentre i restanti sono utilizzabili come supporto nelle operazioni e/o per
il controllo e trasferimento da e verso memoria e da e verso lo spazio di ingresso/uscita.
Analogamente le istruzioni con limitazioni sui valori di indirizzamento possibili sono:
BRBC, BRBS, BRCC, BRCS, BREQ, BRGE, BRHC, BRHS, BRID,
BRIE, BRLO, BRLT, BRMI, BRNE, BRPL, BRSH, BRTC, BRTS,
BRVC, BRVS
K = 7Bit
RCALL, RJMP
K = 12bit
JMP, CALL
K = 16, 22bit
Limitazioni:
LDS, STS
IN, OUT
LPM
LD, ST
MOVW
k = 16bit
A = 6bit
register = Z
register = X, Y, Z
consente lo spostamento solo tra registri pari
Le limitazioni sulle operazioni sono relative agli indirizzi assumibili da A:
SBI, SBIC, SBIS, CBI
A = 5bit
NOTE:
1. Questa istruzione non è disponibile in tutti I dispositivi, per controllare se l’istruzione è disponibile bisognerà
consunltare l’help specifico del relative dispositivo.
2. Non tutte le varianti di questa istruzione sono disponibili in tutti i dispositivi. Come per la prima nota, controllarne la
presenza nel manuale specifico del dispositivo.
3. Non tutte le varianti dell’istruzione LPM sono disponibili in tutti I dispositivi. Il modulo LPM non è in particolare
implementato nel AT90S1200.
4. I tempi di calcolo per l’accesso in memoria assume che la memoria utilizzata sia quella interna, e non sono validi
qualora l’accesso sia effettuato ad una memoria esterna. Per cio che concerne le istruzioni LD, ST, LDS, STS, PUSH,
POP, bisognerà aggiungere un ciclo per ogni stato di attesa. Per le istruzioni CALL, ICALL, EICALL, RCALL, RET, RETI
in tutti I dispositivi a 16bit bisognerà aggiungere tre cicli più due per ogni stato di attesa. Analogamente, per le istruzioni
CALL, ICALL, EICALL, RCALL, RET, RETI nei dispositivi a 22bit bisognerà aggiungere cinque cicli più tre per ogni stato
di attesa.
Le istruzioni di confronto tra registri (CP, CPI, SUB, SUBI) aggiornano tutti i flag della parola di
stato e può essere utilizzata per determinare le relazioni tra I valori confrontati. Essa può essere
utilizzata, in congiunzione con le istruzioni di salto condizionate per determinare l’ordine di
esecuzione del programma (controllo di flusso).
La seguente tabella facilita la codifica del codice di salto in funzione del risultato di test.
Test
Opcode
Test
Opcode
Commento
Rd>Rr
BRLT
Rd <= Rr
BRGE
Signed
Rd>=Rr
BRGE
Rd < Rr
BRLT
Signed
Rd=Rr
BREQ
Rd<>Rr
BRNE
Signed
Rd<=Rr
BRGE
Rd>Rr
BRLT
Signed
Rd<Rr
BRLT
Rd>=Rr
BRGE
Signed
Rd>Rr
BRLQ
Rd<=Rr
BRSH
Unsigned
Rd>=Rr
BRSH/BRCC
Rd<Rr
BRLQ/BRCS
Unsigned
Rd=Rr
BREQ
Rd<>Rr
BRNE
Unsigned
Rd<=Rr
BRSH
Rd>Rr
BRLQ
Unsigned
Rd<Rr
BRLQ/BRCS
Rd>=Rr
BRSH/BRCC
Unsigned
BRCC
Carry
BRCS
No carry
Negative
BRMI
Positive
BRPL
Overflow
BRVS
No Over
BRVC
Zero
BREQ
Nonzero
BRNE
Nota: 1. Scambiare Rd e Rr nell’operazione prima di effettuare il test, ovvero eseguire, CP Rd,Rr −> CP Rr,Rd
La programmazione dei “fusibili”
I microcontrollori mettono a disposizione un area di memoria eeprom in cui programmare un
insieme di configuazioni di default che regolano il successivo funzionamento del micro.
Detti bit (generalmente nominati fuses) consentono di configurare alcuni comportamenti
particolarmente rilevanti. Se abbiamo a disposizione l’AVRstudio potremo configurare questi bit
direttamente tramite la loro interpretazione logica e senza interessarci del valore da impostare. In
particolare questi bit consentiranno di:
• Blocchi di programmazione della memoria (LB2,LB1) sia flash che eeprom;
• Blocchi di programmazione ed esecuzione nel settore delle applicazioni (BLB02,BLB01);
• Blocchi specifici di programmazione ed esecuzione nel settore di boot (BLB12, BLB11);
• Abilitazione OCD: default NO
• Abilitazione JTAG: default SI
• Abilitazione programmazione tramite seriale: default SI
• Watchdog ON: default NO
• EEPROMSAVE: salva eeprom su un erase, default NO
• Dimensione Boot sector: 1K default
•
•
•
•
•
BOOT reset: usa il settore di boot al reset, default NO
Clock divide: divedel il clock per 8, default NO
Start up time
Sorgente del Clock
Clock calibration byte
La gestione delle interruzioni
L’AVR ha a disposizione numerosi sorgenti di interruzione, ognuna di queste può essere collegata
ad una procedura differente mediante una tablella in indirizzamento delle procedure di interruzione.
Inoltre ogni interruzione può essere singolarmente mascherata o abilitata tramite un apposito
insieme di registri maschera.
Inoltre utilizzando alcune opzioni di compilazione BLB02, BLB12 è possibile disabilitare in
maniera sicura gli interrupt. Ci sono due tipi fondamentali di interrupt nell’AVR: gli interrupt si
evento (soglia) e gli interrupt su condizione (valore). I primi sono sollevati ogni volta che una
condizione si presenta e segnalano la loro condizione su un bit di interrupt che va ripristinato prima
di uscire dalla procedura di gestione dell’interruzione.
I secondi invece sollevano l’interrupt solo se la condizione persiste al momento in cui l’interrupt
andrebbe servito. Questo significa che se la CPU era occupata durante le condizioni di interrupt e
queste cessano prima che essa sia libera, nessun interrupt handler verrà eseguito anche quando il
controllore sarà di nuovo disponibile per servirla.
Quando il processore esce da una interruzione esso ritorna sempre al flusso principale di
programma ed esegue almeno una o due istruzioni prima che un nuovo interrupt possa essere
eseguito (sebbene questo possa essere già in attesa). Il registro di stato non viene salvato
automaticamente all’esecuzione di una procedura ad interruzione. Questo compito va gestito
manualmente.
Il tempo di risposta ad un interrupt corrisponde ad un minimo di 4 cicli di clock, dopo tale periodo
le istruzioni puntate dal relativo vettore di interruzione verranno eseguite. Ill vettore viene trattato
come se fosse una istruzione jump al codice dell interrupte questo può richiedere tre cicli di clock
per un primo servizio. Se un interrupt occorre mentr il processore sta eseguendo una istruzione che
richiede più di un ciclo l’istruzione verrà completata prima che l’interrupt possa essere eseguito.
Il return da un interrupt richiede 4 cicli di clock, in questa fase il program counter viene estratto
dallo stack e lo stack vinene aggiornato propriamente.
La struttura della memoria
In una MCU Atmega128 ci sono tre tipi di memoria lineari e regolari: la memoria programma,
costituita da una FLASH riprogrammabile elettricamente di dimensioni pari a 128Kbyte, la
memoria dati costituita da una SDRAM di dimensioni pari a 4Kbyte e la meomoria EEPROM,
durevole tra diverse accensioni e di dimensioni pari a 4Kbyte.
Descrizione dell’ambiente di sviluppo
L’ambiente di sviluppo fornito nel corso consiste nelle seguenti componenti:
•
•
AVRstudio
WinAVR-XXXXXXX-bin-install.exe
Tutte le componenti software fornite nel corso sono disponibili come software di pubblico (GPL o
simili) dominio e sono correntemente scaricabili tramite rete internet seguendo gli opportuni link
software a partire dal sito www.AVRFreaks.org che colleziona tutto il materiale disponibile per i
processori Atmel della famiglia AVR.
L’AVRstudio è un ambiente di sviluppo distribuito dalla Atmel corporation in grado di gestire
progetti di sviluppo scritti in linguaggio assembler (AVR appunto). L’ambiente dispone delle
seguenti funzionalità che lo rendono molto interessante per gli scopi del corso: gestione di progetti
anche complessi, disponibilità di operare su tutti i prodotti della gamma Atmel, assemblatore,
linker, e simulatore/debugger integrato nel ambiente di sviluppo. Possibilità di simulare tutti i
processori della gamma e di controllare il flusso del programma agendo via software sui pin virtuali
dei piedini del microcontrollore simulato. Inoltre per coloro che sono interessati alle fasi
implementative dello sviluppo il sistema consente di integrarsi con diversi dispositivi di sviluppo
rapidi (STK 200/500/501).
L’AVR consente inoltre di importare e “debuggare” codice oggetto in un formato COFF, esteso
dalla Atmel stesso. In tal modo, utilizzando le funzionalità offerte dal WinAVR sarà possibile
interagire con i sistemi AVR e sviluppare codice anche in linguaggi di alto livello, ed eseguire la
loro simulazione nell’ambiente di sviluppo prima di provarli sul microcontrollore.
Il software WinAvr è infatti un progetto di pubblico dominio (disponibile su sourceforge) che
integra diverse funzionalità aggiuntive e parzialmente complementari a quelle offerte dal
AVRstudio, ed in particolare: un meta-compilatore per architettura AVR in grado di eseguire in
ambiente windows, un simulatore compatibile con debugger GDB su IP, alcuni tools per la
programmazione, un editor sensibile al contesto (CSE) denominato programmer Notepad.
Nell’installare i software per lo sviluppo se l’ambiente AVR studio verra’ installato
successivamente al WINavr esso trovera’ l’installazione del compilatore GNU (AVR-GCC) sulla
macchina in oggetto e preparera’ l’ambiente stesso per sviluppare programmi direttamente in codice
C.
Nell’ambito di questo corso faremo raramente riferimento alla programmazione in assembler e la
utilizzeremo soprattutto per capire i meccanismi di base del funzionamento del processore ed
analizzare cosa succede nel sistema quando la diagnostica del programma in codice C non sara’
sufficiente per comprendere il comportamento del microcontrollore (in particolare per la gestione
dei vettori di interruzione ed il passaggio dei parametri).
Installazione e configurazione dei programmi
L’istallazione del codice è alquanto semplice, l’AVRstudio è fornito di un programma di
installazione integrato analogo a quelli già disponibili per tutti i programmi windows, l’utente
rimane libero di scegliere il percorso e le opzioni di installazione in accordo con le caratteristiche
del proprio computer.
A termine installazione una apposita voce aggiunta al menù di avvia consente l’esecuzione del
programma. Alla sua esecuzione il progrmma apparirà con una finestra analoga alla seguente:
L’ambiente di sviluppo (IDE) è analogo per certi versi ai prodotti di sviluppo software disponibili
per il sistema windows. E’ possibile gestire sia file di codice che progetti complessi. Questi ultimi
consentono l’esecuzione di codice sviluppato per tutta la linea di prodotti Atmel. L’uso del
programma verrà mostrato durante le lezioni e sarà più chiaro in seguito quando verranno discusse
le procedure di compilazione simulazione e debug dei software sviluppati.
L’istallazione di WinAVR è per certi versi simile a quella dell’AVRstudio, nel senso che una
procedura di installazione guidata ci aiuterà a configurare le opzioni più idonee per il nostro
calcolatore. A termine installazione tuttavia non sarà disponibile nessun ambiente integrato per lo
sviluppo ma una serie di tools preconfigurati ed installati nella directory scelta per l’installazione.
L’ambiente di sviluppo include le seguenti componenti: il GCC3.3.1 (o seguente) configurato per la
compilazione di codice C,C++ in oggetti di tipo AVR; le Binutils 2.1.4 che consentono la
conversione tra il formato ELF standard del GCC nel formato ECOFF supportato da AVRstudio; le
avr-libc che offrono un ampia libreria di funzioni C standard disponibile al microcontrollore;
l’AVRdude un programma che consente di programmare gli AVR tramite molti dispositivi
compreso l’interfaccia per porta parallela; AVRice, un debugger compatibile JTAG (sconsigliato a
questo livello di sviluppo, per il grosso lavoro ancora in corso di reverse engineering sui protocolli
ATMEL) esso può essere utilizzato per interfacciare il GDB con le interfacce JTAG della AVR;
SimulAVR è un simulatore di architetture AVR esso può essere configurato per eseguire il debug
via rete e quindi essere utilizzato in congiunzione con le funzionalità offerte dal GDB; Insight
5.3.91 è una interfaccia grafica per il GDB; UISP è un ISP (in serial programming) tool; il GDB
5.3.91 in grado di connettersi con SimulAVR e AVRdude ed eseguire il debug del codice
sviluppato; TkInfo per accedere a tutta la documentazione in linea disponibile;alcuni programmi
Win32 per la gestione dell’ambiente di compilazione “make, bash,...”; Programmers Notepad è un
editor sensibile al contesto e riconfigurabile come un IDE; alcuni esempi che mostrano come
utilizzare l’ambiente di sviluppo in congiunzione con AVR studio.
Dopo aver eseguito l’installazione la prima cosa che è opportuno fare è quella di prendere visione
dei tools installati (eseguendo le demo nel albero delle directory). Il programmer notepad non è
nell’albero delle directory di default, per coloro che trovassero utile il programma possono inserirlo
per averlo disponibile ovunque. Nelle directory di documentazione sono disponibili help files che
spieganocome configurare i singoli programmi per avere una integrazione ottimale tra i tools (di
WinAvr) e verso l’AVRstudio offerto dalla atmel.
In particolare converrà analizzare i makefile di esempio in grado di compilare file in C/C++ e
convertirli nel particolare formato COFF esteso supportato dal’AVRstudio. Tutti i progetti in
linguaggio di alto livello possono infatti a richiesta venire convertiti nel formato COFF che
AVRstudio può importare. In questo modo risulta possibile eseguire il debug di codice C all’interno
del ambiente di AVRStudio e pertanto utilizzando tutte le funzionalità offerte dall’IDE.
In particolare vale la pena osservare che non esiste in WinAvr un unico tool grafico da cui è
possibile controllare tutte le funzionalità offerte dal pacchetto ma che, viceversa, molte di queste
sono accessibili solo da linea di comando o con l’esecuzione simultanea di più applicazioni. A tal
fine appare opportuno suggerire di preconfigurare una finestra di comando con le variabili di
ambiente opportune per l’accesso a tutti i tools disposti nel pacchetto.
Sebbene tutte le funzionalità siano eseguibili tramite i tools predisposti, alcuni makefile di esempio
possono aiutare i novizi a eseguire le procedure fondamentali: compilazione, conversione in
formato ECOFF. Nonostante sia possibile configurare l’ambiente di sviluppo AVR per compilare
automaticamente e ricaricare il codice ottenuto di nuovo all’interno dell’IDE si suggerisce di
eseguire a mano le operazioni necessarie in maniera da prendere confidenza più approfondita con i
singoli tools. Una volta che questa pratica sia stata ottenuta a livello approfondito lo studente potrà
consultare gli help files forniti con la documentazione per studiare come automatizzare tutte le
operazioni