Alessandro Mannini @ 2005 - Dipartimento di Ingegneria dell

Transcript

Alessandro Mannini @ 2005 - Dipartimento di Ingegneria dell
Alessandro Mannini @ 2005
Università degli Studi di Firenze
Facoltà di Ingegneria
Nell’ambito del Corso di Informatica Industriale - Prof. A. Fantechi
eBEI – embedded Boolean Expressions Interpreter
1.
INTRODUZIONE .................................................................................... 2
1.1. Requisiti ........................................................................................ 2
1.1.1. Requisiti vincolanti ...................................................................... 2
1.1.2. Requisiti non vincolanti ................................................................ 2
1.2. Scelte progettuali............................................................................. 3
2. ARCHITETTURA.................................................................................... 4
3. ESPRESSIONI BOOLEANE: IL LINGUAGGIO .................................................. 5
4. BEI: BOOLEAN EXPRESSIONS INTERPRETER ............................................... 6
4.1. Tokenizer ...................................................................................... 6
4.2. Parser .......................................................................................... 7
4.2.1. Ricorsività (simulata) ................................................................... 7
4.2.2. Gestione stack .......................................................................... 8
4.2.3. Tabella delle variabili ................................................................... 9
4.3. Interfaccia utente............................................................................. 9
4.4. Esempi ....................................................................................... 10
5. MCU................................................................................................ 12
5.1. eBEI: Embedded Boolean Expressions Interpreter ................................... 14
5.1.1. Passaggio alla piattaforma MCU................................................... 14
5.1.2. RAM: variabili e Stack ................................................................ 14
5.1.3. Struttura di eBEI ....................................................................... 15
5.2. Tools di sviluppo: CodeWarrior e gli altri............................................... 17
5.2.1. Sviluppo ................................................................................ 17
5.2.2. Scrittura del programma in FLASH ................................................ 19
5.2.3. DEBUG.................................................................................. 20
5.3. I/O System .................................................................................. 20
5.4. Serial Monitor ............................................................................... 22
6. EBEI UPLOADER................................................................................. 23
7. CONCLUSIONI.................................................................................... 24
7.1. Miglioramenti................................................................................ 24
7.2. Sviluppi....................................................................................... 24
8. SPECIFICHE ...................................................................................... 25
9. Appendice A...................................................................................... 26
10. Appendice B ................................................................................... 27
11. Appendice C ................................................................................... 28
12. BIBLIOGRAFIA ................................................................................. 29
Alessandro Mannini @ 2005
1 di 29
eBEI – embedded Boolean Expressions Interpreter
1.
INTRODUZIONE
Il seguente lavoro tratta la realizzazione di un prototipo hardware/software capace di
interpretare equazioni booleane che assegnano un valore logico ad un certo numero di
uscite sulla base dei valori binari ricavati da alcuni ingressi.
1.1. Requisiti
Fra i requisiti prefissati nella realizzazione del sistema ne possiamo riconoscerne alcuni
imprescindibili ed altri desiderabili, ma non vincolanti, almeno in sede di realizzazione di
un prototipo.
1.1.1. Requisiti vincolanti
Queste caratteristiche sono legate essenzialmente alla natura embedded del progetto:
• dimensione del codice e delle strutture dati, a differenza di un sistema generalpurpose quale il PC, l’MCU ha una quantità limitata di RAM (4Kb in questo caso),
pertanto l’occupazione dello spazio di memoria deve essere sempre preso in
considerazione. Questo vale sia per la codifica, soprattutto se effettuata tramite
un linguaggio ad alto livello quale il C, ma ancora di più nella scelta delle strutture
dati e nel tipo dei dati;
• allocazione dinamica, è stato escluso a priori questo tipo di utilizzo per le strutture
dati per avere una maggiore affidabilità del sistema. Infatti, l’utilizzo di variabili
statiche consente un maggior controllo sulla dimensione massima dei dati in
memoria;
• modularità, la suddivisione del codice in moduli per le varie funzioni rende più
flessibile il sistema in fase di realizzazione, manutenzione ed eventuale evoluzione.
1.1.2. Requisiti non vincolanti
Trattandosi di un prototipo, alcune caratteristiche sono state considerate secondarie,
anche se in un prodotto commerciale acquisterebbero anch’esse un ruolo centrale:
• memorizzazzione delle equazioni in FLASH RAM con un tool e in zona separata dal
codice, ciò permette di memorizzare l’engine a priori sulla Flash RAM e di caricare
di volta in volta le equazioni con l’apposita utilità; il sistema viene visto come una
soluzione “in-a-box” senza aver conoscenza
della struttura o dei dettagli
implementativi dell’interprete;
• visualizzazione errori, consente di presentare all’utente informazioni circa lo stato
di funzionamento del sistema ed indicazioni più dettagliate nel caso di errore;
• editor/utility di upload delle equazioni, la possibilità di utilizzare uno strumento
appositamente creato per scrivere e trasferire le equazioni all’interno del sistema
ne rende più gradevole e semplice l’utilizzo;
• velocità di esecuzione, questo aspetto è d’interesse solo nel caso di applicazioni
reali e pertanto ha avuto peso su poche scelte.
Come risulterà più chiaro nel seguito, il prototipo realizzato, oltre a soddisfare tutte le
caratteristiche fondamentali, risponde anche alle proprietà meno importanti. L’unico
Alessandro Mannini @ 2005
2 di 29
eBEI – embedded Boolean Expressions Interpreter
aspetto per cui non sono state definite delle specifiche è la velocità di esecuzione, in
quanto questo tipo di valutazione è significativa solo in relazione ad un’applicazione
concreta.
1.2. Scelte progettuali
Vista la natura sperimentale del progetto, per la parte hardware è stata utilizzata la Demo
Board Motorola ® M68DEMO908GB60 (Figura 5.1) con a bordo il microcontrollore
MC9S08GB60 della famiglia HCS08. Il circuito comprende una sezione di alimentazione,
una sezione per la comunicazione seriale, alcuni led per visualizzare il valore delle uscite,
alcuni switches per simulare degli ingressi e l’MCU. Questa scelta ha permesso di
concentrare gli sforzi sulla realizzazione della parte software e sulle problematiche
inerenti la realizzazione di un sistema embedded. Le caratteristiche dettagliate della
Demo Board sono riportate in Appendice A.
Data la complessità del sistema da realizzare, il progetto è stato sviluppato
suddividendolo in sottoproblemi più semplici ottenendo risultati parziali intermedi:
• realizzazione di un interprete su PC in linguaggio ANSI C;
• versione embedded dell’interprete con una sola equazione hard-coded;
• realizzazione di un modulo per la rappresentazione dello stato del sistema e delle
condizioni di errore;
• integrazione del modulo di rappresentazione dello stato nell’interprete;
• interpretazione di un’equazione booleana scritta in FLASH;
• interpretazione di più equazioni booleane.
• sviluppo di un’ utility su PC capace di comunicare direttamente con l’MCU
attraverso il serial monitor;
• scrittura delle equazioni e trasferimento nella FLASH dell’MCU con apposita utility;
Nei capitoli seguenti verrà descritta l’architettura del sistema analizzando le principali
strutture che lo compongono.
Alessandro Mannini @ 2005
3 di 29
eBEI – embedded Boolean Expressions Interpreter
2.
ARCHITETTURA
Nella figura 2.1 sono rappresentate le varie parti che costituiscono il sistema.
Analizzando lo schema nello stesso ordine con cui procede il flusso informativo,
possiamo riconoscere:
• HUMAN:
o l’utente definisce le equazioni che rappresentano i legami voluti fra gli
ingressi e le uscite, utilizzando frasi riconosciute dalla grammatica che
definisce il linguaggio d’interesse;
• PC:
o attraverso l’utility eBEI Uploader (eBEIU) le equazioni sono inserite nel PC e
trasferite all’MCU tramite la porta seriale;
• Microcontrollore (MCU):
o il serial monitor è memorizzato nella FLASH dalla casa costruttrice e
sovrintende alle comunicazioni seriali fornendo varie funzionalità;
o l’eBEI ENGINE (eBEIE) costituisce l’interprete vero e proprio che elabora le
equazioni che trova memorizzate in una determinata locazione della FLASH
Memory;
o le equazioni booleane vengono memorizzate nella FLASH tramite l’eBEIU ed
elaborate dall’eBEIE;
o l’I/O System è costituito dall’insieme dei dispositivi d’ingresso e di uscita
controllati direttamente dall’MCU secondo la logica imposta dall’equazioni
elaborate dall’eBEIE. In un’applicazione reale i dispositivi sensori ed
attuatori interagiscono con il sistema attraverso questa sezione. Nel nostro
caso è l’utente che interagisce direttamente col sistema.
Pertanto, in un possibile scenario di
utilizzo reale di questo sistema, si
HUMAN
PC
può pensare l’MCU come hardware
EXPRESSIONS
BOOLEAN
in
cui
si
trova,
cablata
LANGUAGE
EXPRESSIONS
precedentemente,
l’applicazione
BOOLEAN
eBEI
capace di interpretare le nostre
EXPRESSIONS
UPLOADER
equazioni booleane ed interagire con
le risorse di I/O. Ovviamente
nell’MCU si troverà anche una
eBEI
MCU
seconda applicazione che permette
ENGINE
di
gestire
le
operazioni
di
I/O
BOOLEAN
comunicazione. A questa soluzione
SYSTEM
EXPRESSIONS
“preconfezionata”, si può imporre un
SERIAL
MONITOR
determinato
comportamento
semplicemente
scrivendo
le
opportune equazioni booleane con Figura 2.1 – Architettura del sistema
l’apposita utility (eBEIU) che ne
permette il trasferimento direttamente nella FLASH dell’MCU. A questo punto non resta
che avviare il sistema per iniziare la computazione.
Alessandro Mannini @ 2005
4 di 29
eBEI – embedded Boolean Expressions Interpreter
3.
ESPRESSIONI BOOLEANE: IL LINGUAGGIO
La grammatica che definisce il linguaggio delle espressioni booleane sintatticamente
corrette, può essere descritta utilizzando il metalinguaggio EBNF, nel modo seguente:
<bool_equation>
<bool_conjuction>
→
→
<bool_disjunction> →
<bool_elementary>
<bool_atomic>
<identifier>
<costant>
<alpha>
<digit>
→
→
→
→
→
→
<identifier>’=’<bool_conjuction>
<bool_conjuction> ‘OR’ <bool_disjunction>|
<bool_disjunction>
<bool_disjunction> ‘AND’ <bool_elementary>|
<bool_elem_exp>
<bool_atomic>|‘NOT’ <bool_atomic>
<identifier>|<constant>|‘(’<bool_conj>‘)’
<alpha><identifier>|<alpha>|<digit>
‘0’|‘1’
‘a’..’z’|‘A’.. ‘Z’ |‘_’
‘0’|‘2’|‘3’|‘4’|‘5’|‘6’|‘7’|‘8’|‘9’
Figura 3.1 – Linguaggio riconosciuto in notazione EBNF
o in modo più sintetico:
U→i=C
C→C+D|D
D→D*E|E
E→A|~A
A→i|k|(C)
Figura 3.2 – Linguaggio riconosciuto (forma sintetica)
Si tratta di una grammatica di tipo LL(1) che comprende:
• identificatori di variabile;
• simbolo di assegnazione ‘=’;
• simboli ‘(’ e ‘)’, per modificare le precedenze fra operatori;
• operatori logici ‘AND’, ‘OR’, ‘NOT’ che in alternativa possono essere
specificati con i simboli ‘*’, ‘+’, ‘~’ rispettivamente;
• costanti 0 e 1, con significato di falso e vero rispettivamente;
Per costruzione la grammatica prevede che gli operatori soddisfino le seguenti
precedenze:
‘NOT’ > ‘AND’ > ‘OR’
Alessandro Mannini @ 2005
5 di 29
eBEI – embedded Boolean Expressions Interpreter
4.
BEI: BOOLEAN EXPRESSIONS INTERPRETER
Per l’interprete delle equazioni booleane, è stato utilizzato un analizzatore sintattico a
discesa ricorsiva, con la struttura classica reperibile in un qualunque testo riguardante la
progettazione di compilatori ed interpreti (cfr. G. Bruno, Linguaggi Formali e Compilatori,
UTET Torino). In questo tipo di analizzatore ad ogni produzione del linguaggio viene
associata una funzione e, partendo da quella relativa al simbolo unico, tali funzioni si
richiamano una dopo l’altra ricorsivamente.
Per l’applicazione di questa tecnica di tipo TOP-DOWN, la grammatica deve essere
trasformata in forma adatta a questo tipo di analisi; pertanto le produzioni effettivamente
implementate sono:
U→i=C
C→DC’
C’→+DC’|ε
D→ED’
D’→*ED’|ε
E→A|~A
A→i|k|(C)
Figura 4.1 – Linguaggio riconosciuto in forma adatta all’analisi TOP-DOWN
In Appendice B sono riportati in dettaglio gli schemi utilizzati per determinare gli insiemi
FIRST e FOLLOW utilizzati dalle procedure dell’analizzatore sintattico.
Ogni equazione viene presentata all’interprete sotto forma di stringa. La suddivisione in
token rappresentanti le costanti, gli identificatori e gli operatori, viene eseguita dal
modulo tokenizer. Il tokenizer è pilotato dal parser che si occupa dell’analisi sintattica
vera e propria e, nel nostro caso, anche della valutazione del valore di verità
dell’espressione.
4.1. Tokenizer
All’interno del linguaggio delle
espressioni booleane, a sua
volta, la struttura dei vari
simboli
rappresenta
una
grammatica di tipo regolare a
sinistra ed il riconoscimento
avviene attraverso un automa
a stati finiti. Lo schema di
funzionamento di massima è
riportato in figura 4.2. Nella
figura, i cerchi con il doppio
bordo rappresentano gli stati
finali in cui un token è stato
riconosciuto
attraverso
la
other
0,1
INIT
K
alpha
ERR
alpha, digit
blank
ID
eos
~,*,+
OP
EOS
Figura 4.2 – Principio funzionamento tokenizer
Alessandro Mannini @ 2005
6 di 29
eBEI – embedded Boolean Expressions Interpreter
transizione pilotata dai caratteri in ingresso. Con le linee tratteggiate sono rappresentate
le transizioni che avvengono quando si verifica una condizione di errore in seguito ad un
simbolo riconosciuto che non soddisfa le specifiche. Infine, sempre con la linea
tratteggiata, è indicata la transizione che dall’ID porta all’OP; infatti, una volta
riconosciuta una sequenza compatibile con un identificatore, si accede ad una tabella
per verificare se si tratta di uno degli operatori predefiniti. Il tokenizer e l’interprete sono
case-insensitive.
4.2. Parser
In questo progetto l’implementazione della discesa ricorsiva differisce leggermente da
quella classica in modo da permettere il calcolo del valore dell’espressione
contestualmente all’analisi sintattica. Quest’ultimo risultato si ottiene facendo in modo
che ciascuna funzione di cui il metodo è composto, ritorni il valore parziale calcolato,
fino a risalire all’assegnazione del valore alla variabile.
Nei paragrafi seguenti analizzeremo alcune delle problematiche principali affrontate nello
sviluppo del progetto.
4.2.1. Ricorsività (simulata)
Com’è noto, l’analisi a discesa ricorsiva prevede la definizione di una routine per ciascun
simbolo non terminale e la chiamata ricorsiva fra le varie procedure. A partire dal
simbolo distinto, le funzioni si richiamano a vicenda per arrivare fino alle foglie dell’albero
sintattico e risalire di nuovo al simbolo distinto via via che l’esecuzione di ciascuna
routine termina. L’annidamento di queste chiamate e l’esecuzione ricorsiva in modo
particolare, richiedono implicitamente l’allocazione dinamica di memoria, pertanto è
stata scelta una via alternativa per simulare lo stesso comportamento.
Proc A {
istruzioni A.1
call Proc B
call Proc C
istruzioni A.2
}
Proc B {
istruzioni B.1
call Proc C
}
Proc C {
istruzioni C.1
}
Figura 4.3 – Esempio chiamate routine
stack.init
stack.push(“A”)
while not stack.isempty {
etichetta=stack.pop
switch etichetta {
case “A”
istruzioni A.1
stack.push(“V”)
stack.push(“C”)
stack.push(“B”)
case “V”
istruzioni A.2
case “B”
istruzioni B.1
stack.push(“C”)
case “C”
istruzioni C.1
}
}
Figura 4.4 – Schema ricorsività simulata
Alessandro Mannini @ 2005
7 di 29
eBEI – embedded Boolean Expressions Interpreter
Si utilizza uno stack per tener traccia delle chiamate di procedure aperte, cioè la lista
ordinata delle routine che sono state richiamate ognuna identificata da una propria
etichetta. Si esegue un ciclo che termina solo quando lo stack delle chiamate è vuoto.
Ad ogni iterazione si preleva l’identificatore della routine da attivare e si eseguono le
istruzioni relative. Tali istruzioni a loro volta possono prevedere l’inserimento di nuove
etichette(routine) nello stack.
In figura 4.3 è riportato un semplice esempio che contiene tutti gli elementi utili alla
comprensione. La routine A, una volta richiamata, esegue le istruzioni A.1, richiama la
procedura B, poi la C e, al ritorno da B e C, esegue altre istruzioni A.2. A loro volta B e
C contengono altre chiamate a funzioni ed Proc. eseguita
Stack
istruzioni.
In figura 4.4 è riportata una schematizzazione del
codice necessario per simulare queste chiamate,
mentre in figura 4.5 è rappresentata la sequenza
di utilizzo dello stack durante l’esecuzione del
codice stesso.
A
---
A
B
C
V
B
C
C
V
Nell’esempio, oltre al funzionamento standard
illustrato, viene messo in evidenza anche un
C V
C
particolare comportamento che è possibile
ottenere estendendo questa tecnica. Infatti, nella
procedura A, dopo aver eseguito le procedure B e
V
C
C, si deve ritornare ad A per eseguire le istruzioni
A.2. Questo effetto si ottiene introducendo un
identificatore virtuale di routine V da pensare
V
come una chiamata alla procedura V posta
appena prima delle istruzioni A.2. Così, allo
stesso modo dei sottoprogrammi “normali”, V Figura 4.5– Sequenza esecuzione codice e stack
viene inserita in stack e richiamata al momento opportuno. Questo è molto importante
nel nostro caso in quanto la procedura di analisi in discesa ricorsiva presenta questa
necessità.
4.2.2. Gestione stack
La necessità di gestire delle strutture dati di tipo stack si ha sia nella ricorsione simulata
che nella memorizzazione dei risultati intermedi che avviene parallelamente all’avvio e al
terminE di ciascuna routine.
Lo stack nasce come struttura dinamica, ma in questo caso è stato implementato con
un vettore statico con numero prefissato (e massimo) di elementi. La prima componente
del vettore è stata utilizzata come “puntatore” al primo elemento memorizzato. Pertanto
contiene l’indice dell’elemento di testa, se presente, o zero se lo stack è vuoto.
Questa soluzione ha permesso di raccogliere tutte le definizioni e le routine di gestione di
un generico stack di signed char, in un unico modulo.
Alessandro Mannini @ 2005
8 di 29
eBEI – embedded Boolean Expressions Interpreter
L’unico limite dell’utilizzo di un vettore è la dimensione prefissata per il numero di
elementi, ma questo è al contempo anche una garanzia, rendendo l’utilizzo massimo di
RAM, noto a priori.
4.2.3. Tabella delle variabili
La tabella delle variabili è una struttura caratteristica di ogni compilatore ed interprete. I
fattori da considerare nella sua progettazione sono la velocità e l’occupazione di spazio.
L’accesso alle variabili avviene ogni volta che se ne incontra una nel testo
dell’espressione in esame per testarne l’esistenza, recuperarne o aggiornarne il valore. Il
numero di accessi alla tabella delle variabili può essere anche molto elevato ed
influenzare notevolmente le prestazioni dell’interprete, pertanto la scelta si è orientata
verso tecniche hash.
D’altra parte la necessità di conoscere a priori la memoria utilizzata ha escluso tecniche
di allocazione dinamica per la memorizzazione degli elementi e la gestione delle relative
collisioni.
Per tutte queste ragioni è stato adottato un double-hashing che, com’è noto, prevede
l’allocazione in un unico vettore di lunghezza prefissata, consente tempi di accesso
molto ridotti ed ha un buon comportamento rispetto ai fenomeni di clustering primario e
secondario.
Per semplicità, il linguaggio delle equazioni booleane non prevede istruzioni di
dichiarazione, dunque, le variabili sono autodefinite con valore 0, nel momento stesso in
cui vengono richiamate per la prima volta.
4.3. Interfaccia utente
Nella versione PC dell’interprete l’interfaccia utente è di tipo a linea di comando. Al
prompt è possibile digitare:
• un’espressione booleana, in questo caso viene stampata la lista dei token
identificati e le variabili coinvolte, definite e/o aggiornate;
• un comando fra:
o .about, fornisce una breve descrizione sul software in uso;
o .clear, re-inizializza l’ambiente svuotando la tabella delle variabili;
o .var, elenca la lista delle variabili definite specificando il loro nome e valore
attuale;
o .quit, termina l’esecuzione del programma.
Nella figura 4.6 è riportato un esempio di possibile utilizzo.
Alessandro Mannini @ 2005
9 di 29
eBEI – embedded Boolean Expressions Interpreter
=> .about
bei - Boolean Expression Interpreter
/\. /\/\annini @ 2005
=> _o01=_o01 OR
Identificatore:
Operatore =
Identificatore:
Operatore OR
Identificatore:
_i01
_O01
_O01
_I01
=> .var
_O01 -> 0
_I01 -> 0
=> _i01=1
Identificatore: _I01
Operatore =
Costante: 1
=> .var
=> _o01=_o01 OR
Identificatore:
Operatore =
Identificatore:
Operatore OR
Identificatore:
_O01 -> 0
_I01 -> 1
_i01
_O01
_O01
_I01
=> .var
_O01 -> 1
_I01 -> 1
=>
Figura 4.6 – Esempio di possibile utilizzo di BEI
4.4. Esempi
Nelle figura 4.7 sono riportati alcuni esempi di equazioni booleane appartenenti al
linguaggio definito. In esse sono coinvolte le costanti, le variabili e tutti gli operatori.
Come descritto nel seguito, la particolare struttura del nome di alcune variabili, fa
riferimento agli ingressi e alle uscite dell’MCU.
L’esempio 4.7a mostra un esempio in cui la prima uscita è fissa accesa mentre le uscite
2 e 3 sono in esclusione fra di loro e il loro stato è regolato dall’ingresso 1.
Nell’esempio 4.7b la variabile a è vera se sono premuti lo sw1 o lo sw2, l’uscita 1 si
attiva se è premuto sw1 oppure sw2, ma non è premuto lo sw4. Al contrario se si preme
sw4 assieme a sw1 o sw2, l’uscita 1 si disattiva e si attiva la 4. La stessa uscita 4 si
attiva anche se si preme lo sw3.
Alessandro Mannini @ 2005
10 di 29
eBEI – embedded Boolean Expressions Interpreter
A
B
_o01=1
_o02=_i01
_o03=NOT _i01
a=_i01 OR _i02
_o01=a AND NOT _i04
_o04=(a AND _i04) OR _i03
C
D
_o01=_o01 OR _i01
o=_o01 OR _o02 OR _o03 OR _o04
_o04=_o03
_o03=_o02
_o02=_o01
_o01=a OR (_i01 AND NOT o)
a=_o04 AND NOT _o01
dummy=(b OR c) AND (b OR c)
dummy=(b OR c) AND (b OR c)
dummy=(b OR c) AND (b OR c)
dummy=(b OR c) AND (b OR c)
Figura 4.7 – Alcuni semplici esempi di equazioni booleane riconosciute
L’esempio 4.7c realizza un’autoritenuta in quanto l’uscita 1, una volta attivata
dall’ingresso 1, rimane attiva per mezzo di se stessa.
Infine, nel’esempio 4.7d, si realizza un effetto di sliding attivato dalla pressione dello
sw1. Le equazioni dummy servono solo per rallentare l’elaborazione.
Alessandro Mannini @ 2005
11 di 29
eBEI – embedded Boolean Expressions Interpreter
5.
MCU
La demo board utilizzata in questo progetto è mostrata in figura 5.1; le caratteristiche
complete sono riportate in Appendice A, insieme ad uno schema a blocchi dell’MCU.
In questo capitolo vedremo solo alcune caratteristiche dei dispositivi coinvolti nel
progetto. In particolare:
• PTF0-PTF3, sono i primi quattro bit della porta F di tipo general-purpose highcurrent Parallel Input/Output; nella nostra applicazione questi pin sono usati in
output per accendere e spegnere altrettanti leds;
• PTD0, è un bit condiviso fra general-purpose I/O e il channel 0 del TPM1; il TPM1
è uno dei due moduli di Timer/PWM, capace di generare un’onda PWM di periodo
pari alla durata del timer e
vari tipi di interrupt; anche
a questo pin è collegato
un led;
• PTA4-PTA7, sono gli ultimi
quattro bit della porta A
condivisa
fra
generale
KBI
purpose
I/O
(Keyboard Interrupt input);
in questo caso sono usati
in input per leggere lo
stato dei micro-switches
ad essi collegati;
• SCI1, porta seriale 1 in
standard RS232 DB9-S
utilizzata
per
la Figura 5.1 – Motorola M68DEMO908GB60 demo board
comunicazione con l’MCU;
• 4Kb RAM , utilizzata per i registri e le variabili del programma;
• 60Kb FLASH RAM, utilizzata per memorizzare dati e programmi da conservare
anche a circuito spento.
• COP, acronimo di Computer Operating Properly, è un sistema di watch-dog che
provoca il reset dell’MCU se l’applicazione non ha il comportamento atteso e non
provvede all’zzeramento del timer prima che questo scada; è disattivabile e
prevede due possibili soglie di timeout;
Merita un approfondimento l’analisi della struttura della memoria e dell’indirizzamento.
Infatti, sviluppando in un linguaggio di alto livello quale il C, tante operazioni sono
automatizzate, ma in certe situazioni è necessario interagire con i dispositivi e con la
memoria in particolare, e pertanto
è richiesta una conoscenza approfondita
dell’hardware.
In figura 5.3 è illustrata una mappa della memoria e il modo in essa viene utilizzata nella
nostra applicazione. L’indirizzamento è lineare su tutto lo spazio di memoria e
comprende sia la zona RAM sia la FLASH. In particolare:
Alessandro Mannini @ 2005
12 di 29
eBEI – embedded Boolean Expressions Interpreter
•
•
•
•
$0000-$007F Direct Page Register, si tratta delle prime 128 locazioni di memoria,
sono accessibili in modo efficiente con indirizzamento diretto, su di esse è
possibile utilizzare le istruzioni assembler per la manipolazione dei singoli bit;
contiene i registri più utilizzati;
$0080-$107F 4K Ram, si tratta dell’area di memoria disponibile per le variabili e lo
stack dei programmi; i bytes $0080-$0100 godono degli stessi vantaggi di della
Direct Page Register;
$1800-$182B High-Page Register, contiene i registri utilizzati meno
frequentemente che pertanto sono collocati fuori dalla zona ad indirizzamento
diretto lasciando il posto a registri e variabili utilizzate più frequentemente;
$1080-$17FF e $182C-$FFFF 64k FLASH Ram, si tratta della memoria non volatile
da utilizzare per memorizzare i programmi oltre ad alcune locazioni contenenti i
valori dei registri non volatili; può essere letta, cancellata e riscritta, consente
inoltre funzioni di protezione dalla cancellazione/modifica e sicurezza.
$0000
$007F
$0080
DIRECT PAGE
REGISTERS
RAM
4096 Bytes
$107F
$1080
$17FF
$1800
$182B
$182C
FLASH
1920 Bytes
HIGH-PAGE
REGISTERS
$0000
$007F
$0080
$0100
$0693
$0694
$0E93
$107F
$1080
$17FF
$1800
$182B
$182C
$2920
DIRECT PAGE
REGISTERS
RAM
4096 Bytes
1428 byte
2048 byte
FLASH
1920 Bytes
HIGH-PAGE
REGISTERS
4341 byte
Non allocata
Variabili
globali
$3200
Stack
FLASH
59348 Bytes
FLASH
59348 Bytes
Codice eBEI
Espressioni
booleane
Serial Monitor
$F9FF
$FFFF
$FC00-$FFFF
51200 byte
1024 byte
Figura 5.2 - Mappa della memoria dell’MCU e utilizzo nel prototipo
Nei paragrafi successivi verranno forniti dettagli circa l’utilizzo della memoria da parte del
prototipo.
Alessandro Mannini @ 2005
13 di 29
eBEI – embedded Boolean Expressions Interpreter
5.1. eBEI: Embedded Boolean Expressions Interpreter
eBEI è la versione finale ed embedded dell’interprete di equazioni booleane descritto nel
capitolo 4. Questa parte è stata sviluppata partendo dal codice implementato su PC ed
utilizzando il tool di sviluppo Codewarrior© fornito da Motorola.
5.1.1. Passaggio alla piattaforma MCU
La conversione del codice Ansi C dalla piattaforma PC all’MCU ha richiesto poche
modifiche. Ad esempio nella versione PC era presente l’istruzione strdup che snelliva
alcune routine su stringhe, ma implicitamente richiedeva allocazione dinamica di
memoria e non era riconosciuta dal compilatore. Questo comando è stato evitato
utilizzando vettori di caratteri allocati a priori.
Il tool di sviluppo e simulazione risulta più rigoroso riguardo la necessità d’inizializzazione
delle variabili, rispetto a quanto richiesto dall’ambiente su PC. In particolare non è
possibile leggere il contenuto di una zona di memoria se questa non ha ricevuto prima
almeno un’assegnazione.
Un’altra differenza fra i due compilatori è emersa anche nel valutare le espressioni
booleane all’interno del codice sorgente. Infatti, mentre su PC il calcolo del valore di
verità si arresta nel momento in cui da un risultato parziale si può dedurre la veridicità o
meno di tutta l’espressione, in Codewarrior la valutazione è esaustiva. In certi casi
questa differenza nel valutare le espressioni booleane, impone, o la scomposizione di
una condizione complessa in più condizioni annidate, rendendo meno leggibile il codice,
o l’azzeramento di variabili anche laddove, pur rimanendo una buona norma di
programmazione, non sarebbe strettamente necessario.
5.1.2. RAM: variabili e Stack
Per quanto riguarda l’indirizzamento delle variabili è stato scelto il modello di memoria
SMALL, in cui ogni riferimento viene fatto a 16 bit e quindi il codice e i dati devono
risiedere in uno spazio d’indirizzi di 64k.
La RAM allocata dal compilatore è pari 3476 bytes di cui1428 per le variabili globali e
2048 per lo stack. Queste informazioni possono essere ricavate in Codewarrior dai files
.map e .mrp del progetto, come illustrato in dettaglio nel paragrado 5.2.1.
Come si vede dalla figura 5.3 la quota maggiore di spazio è occupata dalle tre strutture
dati principali descritte nel paragrafo 4.2. Come già detto, si tratta di strutture statiche ,
pertanto la loro dimensione è predeterminata. Inoltre, essendo state definite tramite
variabili globali, il compilatore le alloca in RAM riservando lo spazio ad esse necessario.
Al contrario, tutte le altre variabili locali definite all’interno delle varie routine (compresi i
parametri passati), sono allocate/disallocate a run-time nello stack. Ovviamente le
variabili globali hanno il pregio di rendere noto a priori lo spazio utilizzato in memoria ma,
per contro, lo occupano per tutta l’esecuzione dell’applicazione. Viceversa, le variabili
che utilizzano lo stack, hanno il vantaggio di essere allocate solo per il tempo
Alessandro Mannini @ 2005
14 di 29
eBEI – embedded Boolean Expressions Interpreter
Variabile
bytes
op
ed_state
ed_substate
ed_err
recursion
6
101
values
101
variables
1214
6
Descrizione
Vettore di puntatori alle stringhe degli operatori definiti
Variabili utilizzate dal modulo di rappresentazione dello
stato del sistema
Stack per la ricorsione simulata
Stack per il passaggio dei risultati intermedi fra le varie
funzioni
Tabella hash per la memorizzazione delle variabili
Figura 5.3 – Tabella occupazione RAM delle variabili globali
effettivamente necessario, ma le operazioni necessarie all’allocazione/disallocazione,
introducono un ritardo nell’esecuzione e non hanno esito certo, non essendo noto lo
spazio massimo necessario a run-time.
Lo stack pointer (SP), di default, viene impostato a $00FF dopo il reset in modo da
allocare lo stack nella pagina ad indirizzamento diretto. Questa soluzione, pur essendo
performante, impone una dimensione massima dello stack di 128 bytes, mentre
Codewarrior predispone uno stack di 256 bytes allocato in RAM dopo le variabili globali.
La dimensione dello stack è un fattore determinante per il corretto funzionamento del
sistema perché lo SP viene inizializzato all’indirizzo più alto riservato allo stack e si
sposta verso indirizzi più bassi, via via che lo stack si riempie. Né nel simulatore nè tanto
meno nell’hardware, sono previsti controlli di collisione fra SP ed area di memoria per le
variabili globali. Questo può portare a comportamenti impredicibili.
In questo progetto lo stack viene utilizzato solo per le poche variabili locali definite
all’interno delle funzioni e per il passaggio dei parametri. Comunque, vista l’esigua
quantità di memoria utilizzata dall’applicazione per le variabili globali, nella restante parte
è stato definito uno stack di 2048 bytes.
5.1.3. Struttura di eBEI
L’interfaccia utente presente nella versione su PC è stata eliminata nel passaggio alla
demo board. Al suo posto è stato impiantato un ciclo infinito, tipico dei sistemi
embedded, all’interno del quale sono state attivate le varie parti del sistema. Ad ogni
iterazione vengono richiamate le seguenti funzioni:
• lettura ingressi, vengono letti i valori presenti sui pin di ingresso e memorizzati in
corrispondenti variabili interne del sistema;
• elaborazione delle equazioni, il parser analizza e valuta tutte le equazioni booleane
che gli vengono sottoposte, leggendo e aggiornando i valori presenti nelle variabili
interne del sistema;
• aggiornamento delle uscite, si impostano i valori da attribuire ai pin di uscita sulla
base di quelli presenti nelle corrispettive variabili interne del sistema.
Da osservare che durante tutta la fase di elaborazione delle equazioni, per i valori degli
ingressi e delle uscite, si fa riferimento alle relative variabili interne. Quindi il valore
impostato sulle uscite è quello risultante alla fine del calcolo di tutte le equazioni
Alessandro Mannini @ 2005
15 di 29
eBEI – embedded Boolean Expressions Interpreter
presenti, mentre non vengono portati in uscita gli eventuali valori intermedi attribuiti
durante l’elaborazione. Inoltre, il valore delle uscite (come degli ingressi), può essere
utilizzato all’interno delle espressioni booleane semplicemente facendo riferimento alla
relativa variabile interna. In questo caso, il valore acquisito è quello della variabile in
quell’istante e pertanto comprende i valori intermedi derivanti dalle eventuali attribuzioni
fatte dalle equazioni che precedono quella in esame.
Le variabili interne associate agli ingressi e alle uscite sono:
• _Ixx per gli ingressi, dove xx indica il numero di ingresso;
• _Oxx per le uscite, dove xx indica il numero di uscita.
L’acquisizione delle equazioni da elaborare, dopo un primo test fatto con una singola
equazione “hardcoded” , è stato realizzata facendo riferimento ad una locazione di
MC9S08GB60 using AN2140 Monitor. Device ID = D8 00 02
Target type 68HC08. Target buffer 256 bytes
Breakpoint instruction: 83
3200
3210
3220
3230
3240
3250
3260
3270
3280
3290
32A0
32B0
32C0
32D0
32E0
32F0
5F
69
00
69
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
6F
30
5F
30
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
30
31
6F
32
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
31
20
30
00
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
3D
41
33
1A
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
5F
4E
3D
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
69
44
5F
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
30
20
69
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
31
4E
30
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
00
4F
31
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
5F
54
20
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
6F
20
41
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
30
5F
4E
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
32
69
44
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
3D
30
20
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
5F
32
5F
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
FF
_o01=_i01._o02=_
i01 AND NOT _i02
._o03=_i01 AND _
i02..ÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
Figura 5.4 – Dump della memoria Flash nella locazione delle equazioni
memoria in Flash in cui vengono memorizzate precedentemente le espressioni.
Come si osserva dalla figura 5.4 a partire dalla locazione $3200 si trovano le equazioni
memorizzate sotto forma di testo. Ogni equazione termina con il carattere ASCII $00,
mentre la lista di equazioni termina con il carattere ASCII $1A.
La ripetizione delle fasi descritte in precedenza si interrompe solo se uno dei moduli
segnala un errore. In questo caso il sistema entra in uno stato fail-safe (che è stato
supposto essere quello con tutte le uscite a zero) ed attiva soltanto il modulo di
segnalzione di errore descritto in dettaglio nel paragrafo 5.3.
Come accennato in precedenza, l’MCU prevede anche un dispositivo di tipo watch-dog
che resetta il chip se il contatore arriva al valore limite prima che venga richiesto un
azzeramento periodico. Nel nostro caso, oltre ad un azzeramento del COP all’interno del
ciclo infinito principale, è stato necessario forzarne uno anche nel ciclo di iterazione del
Alessandro Mannini @ 2005
16 di 29
eBEI – embedded Boolean Expressions Interpreter
parser; infatti, in certi casi, la complessità del riconoscimento e della valutazione delle
espressione faceva scattare il watch-dog nel simulatore.
5.2. Tools di sviluppo: CodeWarrior e gli altri
5.2.1. Sviluppo
Codewarrior è il tool di sviluppo fornito assieme alla demo-board e utilizzato per la
realizzazione della parte embedded di questo
progetto. Si tratta di un tool che comprende tutte le
principali funzioni di sviluppo e debugging presenti
in tutti gli ambienti di programmazione per linguaggi
ad alto livello. Permette l’editing, la compilazione e
il trasferimento in Flash di sorgenti nei linguaggi C e
C++.
Figura 5.5 – Progetto Codewarrior
Alessandro Mannini @ 2005
Quando
si
crea
un
nuovo
progetto,
automaticamente, vengono creati tutta una serie di
files. In figura 5.5 è possibile vedere la struttura del
progetto di questo prototipo. Vediamo alcuni dei file
più importati:
• main.c è il programma principale in cui l’IDE
inserisce lo scheletro del ciclo infinito
principale;
• start08.c è la procedura di inizializzazione
richiamata
all’avvio
dell’esecuzione;
si
occupa di inizializzare lo stack, gli interrupt e
poi passa il controllo al main;
• MC9S08GB60.c contiene la definizione di
ciascun registro, secondo la nomenclatura
riportata nel dasheet dell’MCU;
• MC9S08GB60.h contiene la definizione e il
mapping di tutti I registri con le eventuali
scomposizioni nei singoli bit;
• ansis.lib è il file di libreria essenziale per
l’esecuzione del codice C;
• *.cmd è costituito dall’insieme di file di
comandi associati alle azioni di ciascun
metodo di connessione al target per il debug;
• *.prm per ciascun target definisce il modo in
cui lineare i segmenti codice e dati;
• *.map per ciascun target riporta tutte le
informazioni di allocazione prodotte dal
linker.
17 di 29
eBEI – embedded Boolean Expressions Interpreter
/* This is a linker parameter file for the GB60 */
NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here
you may add your own files too. */
SECTIONS
Z_RAM
RAM
ROM
ROM2
END
/* here all RAM/ROM
= READ_WRITE 0x0080
= READ_WRITE 0x0100
= READ_ONLY 0x182C
= READ_ONLY 0x1080
areas of the device are listed. Used in PLACEMENT below. */
TO 0x00FF;
TO 0x107F;
TO 0xFEFF;
TO 0x17FF;
PLACEMENT /* here all predefined and user segments are placed into the SECTIONS defined above. */
DEFAULT_ROM
INTO ROM/*, ROM2*/; /* in case you want to use ROM2 here as well,
add option -OnB=b to the compiler. */
DEFAULT_RAM
INTO RAM;
_DATA_ZEROPAGE, MY_ZEROPAGE
INTO Z_RAM;
END
STACKSIZE 0x800
VECTOR 0 _Startup /* reset vector: this is the default entry point for a C/C++ application. */
//VECTOR 0 Entry /* reset vector: this is the default entry point for a Assembly application. */
//INIT Entry
/* for assembly applications: that this is as well the initialisation entry
point */
Figura 5.7a – File Monitor_linker.prm
***************************************************************************************
******
SECTION-ALLOCATION SECTION
Section Name
Size Type
From
To
Segment
-------------------------------------------------------------------------------------------.text
4069
R
0x18CC
0x28B0
ROM
.data
6
R/W
0x100
0x105
RAM
.abs_section_50
1
N/I
0x50
0x50
.absSeg0
.abs_section_54
1
N/I
0x54
0x54
.absSeg1
.
.
.
.abs_section_63
2
N/I
0x63
0x64
.absSeg141
.abs_section_64
1
N/I
0x64
0x64
.absSeg124
.abs_section_60
1
N/I
0x60
0x60
.absSeg125
.abs_section_ffee
2
R
0xFFEE
0xFFEF
.absSeg142
.bss
6
R/W
0x106
0x10B
RAM
.rodata1
96
R
0x28B1
0x2910
ROM
.startData
17
R
0x18BB
0x18CB
ROM
.init
143
R
0x182C
0x18BA
ROM
.common
1416
R/W
0x10C
0x693
RAM
.stack
2048
R/W
0x694
0xE93
RAM
.copy
12
R
0x2911
0x291C
ROM
.vectSeg143_vect
2
R
0xFFFE
0xFFFF
.vectSeg143
ROM size:
RAM size:
10F5 (dec:
E22 (dec:
4341)
3618)
Figura 5.7b – File Monitor.map
In figura 5.7a è riportato il file prm del progetto relativamente al target monitor. In esso
vediamo le seguenti dichiarazioni:
• SECTIONS, per la definizione delle aree di memoria nel device;
• PLACEMENT, permette di assegnare ciascun segmento, predefinito o utente, ad
una delle sections sopra definite;
• STACKSIZE, consente di definire la dimensione dello stack;
Alessandro Mannini @ 2005
18 di 29
eBEI – embedded Boolean Expressions Interpreter
•
VECTOR 0, definisce la locazione di avvio dell’applicazione che nel caso del C è
l’indirizzo della procedura Startup.
Per quanto riguarda lo stack è importante osservare che, mentre il reset pone lo SP a
$FF, la procedura di inizializzazione Startup pone lo SP pari all’indirizzo ottenuto
sommando alla locazione dell’ultimo byte occupato dalle variabili globali allocate la
dimensione dello stack secondo quanto definito nel prm.
Il file .map contiene molte informazioni interessanti sull’allocazione della memoria per le
variabili e le funzioni, sulle interdipendenze etc. In figura 5.7b è riportata una parte del
file relativamente al nostro progetto. Per ogni sezione viene specificato il segmento di
allocazione e in fondo viene presentato il totale allocato in RAM e in ROM. Ad esempio si
evince che il codice + le varie costanti occupano un totale di 4341 bytes. In Ram,
invece, vengono utilizzati 3618 bytes di cui, 2048 bytes per lo stack, 1416 bytes per le
variabili globali nella sezione common, 6 bytes per le variabili globali della sezione bss nel
modulo di rappresentazione dell’errore, 6 bytes per le variabili globali della sezione .data
nel vettore degli operatori ed infine 142 bytes per la definizione dei registri nelle varie
sezioni abs_section_xxx.
Oltre a Codewarrior sono presenti altri strumenti di sviluppo analoghi, ognuno dei quali
ha delle peculiarità che lo rendono particolarmente indicato per un determinato compito,
secondo l’aspetto che s’intende privilegiare. Fra questi è stato utilizzato NoICE che
permette di collegarsi alla demo-board tramite il Serial Monitor ed accedere facilmente
al contenuto della Flash.
5.2.2. Scrittura del programma in FLASH
La scrittura del programma in Flash Ram viene effettuata direttamente da Codewarrior.
Se come target è stato selezionato Monitor (menù Project->Select Default Target),
premendo il tasto F5, il codice viene compilato, linkato e si avvia la connessione con la
demo-board tramite la seriale. La demo board deve essere predisposta tenendo
premuto lo sw4 durante l’accensione. L’IDE apre direttamente la finestra di Debug da
cui è possibile fare tutte le operazioni descritte nel paragrafo successivo. In questa
finestra nel menù MONITOR+HCS08->Monitor communication è possibile impostare la
porta seriale del PC da utilizzare per la comunicazione.
Ogni operazione di aggiornamento della Flash è preceduta da una fase di erasing della
stessa. In particolare Codewarrior non cancella solo la zona oggetto della successiva
scrittura, ma tutta la Flash, escluso, ovviamente, le zone protette. Quindi eventuali
informazioni memorizzate in Flash, come ad esempio le nostre equazioni, vengono
perse. Al contrario, il codice rimane memorizzato anche se l’IDE di Codewarrior viene
chiuso e la demo-board scollegata dalla seriale. Quindi, accendendo il circuito
normalmente, viene eseguito il codice memorizzato in precedenza.
Il codice eseguibile e le relative costanti definite nel sorgente sono memorizzate nella
Flash RAM a partire dalla prima locazione di ROM definita nel file .prm corrispondente al
Alessandro Mannini @ 2005
19 di 29
eBEI – embedded Boolean Expressions Interpreter
target. Nel nostro caso si parte dalla locazione $182C fino alla locazione $2920 per un
totale di 4341 bytes. Per questo motivo le equazioni sono state scritte in Flash a partire
dalla locazione $3200 per 50k bytes.
5.2.3. DEBUG
L’IDE di Codewarrior prevede anche un potente debug che consente tutte le funzioni più
avanzate quali:
• esecuzione passo-passo con Single Step, Step Over, Step Out, Assembly Step,
Reset;
• dump della memoria;
•
•
•
•
visualizzazione
visualizzazione
visualizzazione
visualizzazione
del valore delle variabili;
del codice sorgente ed assembler;
dello stato della CPU con i valori dei registri;
della lista di funzioni richiamate.
Il debug può essere di vario tipo:
• ICS: In Circuit Simulation, utilizzabile solo tramite l’interfaccia BDM (Background
Debug Mode), consente l’esecuzione del codice direttamente sul chip, consente di
effettuare tutti i tipi di operazione sulla flash (anche la cancellazione delle aree
protette), non richiede codice specifico in esecuzione sull’MCU e pertanto non
risente di eventuali bug di qualunque tipo presenti nel codice in prova;
• FCS: Full Circuit Simulation, permette di simulare il comportamento del chip per
via software, è utilizzabile senza la presenza del chip e può essere utile per trovare
bug quando l’esecuzione sul chip o il debug tramite Monitor si bloccano;
• MONITOR, utilizzabile con il collegamento seriale, richiede la presenza sul chip del
Motorola Serial Monitor di cui sfrutta le funzionalità; essendo basato su un
secondo software in esecuzione sul chip, alcuni tipi di bug o di operazioni (quali il
cambio di clock), possono far perdere la connessione con il chip e quindi, rendere
impossibile questo tipo di debugging.
Infine, vale la pena osservare che la possibilità di eseguire il codice sorgente a step
facilita molto il debugging ad alto livello, viceversa, in certi casi risulta molto utile anche
l’esecuzione a step del codice assembler, perché consente di capire in dettaglio certi
meccanismi a stretto contatto con l’hardware che sovrintendono a certe funzioni di alto
livello. Così, ad esempio, è possibile vedere come la procedura Startup inizializza l’MCU,
lo SP in particolare, e rilascia il controllo alla funzione main.
5.3. I/O System
Il sistema di I/O è l’insieme dei dispositivi d’ingresso ed uscita che interfacciano l’MCU
con l’esterno e che in un’applicazione reale sarebbe costituito da sensori ed attuatori.
Per semplicità, nel nostro prototipo, sono stati utilizzati i leds e micro-switches presenti
sulla demo board.
Per gli ingressi sono utilizzati gli switches sw1, sw2, sw3 e sw4 ai quali è possibile far
riferimento nelle equazioni tramite le variabili _I01, _I02, _I03, _I04. Quando lo switch è
Alessandro Mannini @ 2005
20 di 29
eBEI – embedded Boolean Expressions Interpreter
rilasciato il corrispondente assume valore falso, mentre diventa vero quando lo switch
viene premuto.
Per le uscite sono usati i leds led1, led2, led3, led4 alle quali è possibile far riferimento
nelle equazioni tramite le variabili _O01, _O02, _O03, _O04. Il led è acceso quando la
corrispondente variabile èvera e spento quando la relativa variabile è falsa.
Sequenza led stato
Code2
Code10
Descrizione
0001
1
Invalid character
0010
2
Identifier too long
0011
3
Generic error
0100
4
Missing variable identifier
0101
5
Equal operator required
0110
6
OPERATOR required
0111
7
Missing right bracket
1000
8
Missing argument
1001
9
Expression required
1010
10
Unattended character
1011
11
--- N.D. ---
1100
12
Recursion stack overflow
1101
13
Values stack overflow
1110
14
Hash table overflow -> too much
variables
1111
15
Hash table -> variable not found
Figura 5.8 – Tabella degli errori
Fra le uscite troviamo anche il led5 utilizzato come led di stato del sistema. Normalmente
il led è acceso fisso ad indicare che il sistema è in stato running, ovvero opera
correttamente. In caso di errore, dopo aver messo il sistema in uno stato fail-safe (tutte
le uscite a zero), il led segnala il codice di errore attraverso una sequenza di 4 lampeggi,
ognuna delle quali può essere breve o lunga. Si tratta di un sistema simile al Codice
Morsei, ma in questo caso ogni accensione corrisponde ad un bit della codifica binaria
del codice di errore, con la convenzione che un’accensione lunga corrisponde a 0 e
un’accensione breve corrisponde ad 1. Dopo la sequenza di errore c’è una pausa in cui il
led rimane spento e poi la rappresentazione del errore viene reiterata. I possibili errori
sono riportati nella figura 5.8.
Alessandro Mannini @ 2005
21 di 29
eBEI – embedded Boolean Expressions Interpreter
Questo tipo di segnalazione è realizzato utilizzando l’onda PWM generata dal canale 0
del TPM1 con un duty-cycle del 100% o dello 0%. Se non vi sono errori viene impostato
il duty-cycle 100% e disabilitato l’interrupt di overflow del timer 1 (TOIE), quindi il led
rimane acceso fisso. In caso di errore le accensioni breve e lunga del led vengono
realizzate con un numero minore o maggiore di periodi a duty-cycle 100%, mentre le
pause vengono realizzate con un numero fisso di periodi a duty-cycle 0%. Adottando il
periodo come unità base per costruire gli altri segnali, si ha la possibilità di generare
pause di durata costante indipendentemente dal tipo di accessione (breve o lunga) che
precede o segue.
5.4. Serial Monitor
Il Serial Monitor è un programma sviluppato da Motorola che mette a disposizione 19
primitive che consentono di programmare la Flash RAM ed effettuare operazioni di debug
tramite un PC collegato all’MCU con l’interfaccia seriale RS232.
Il programma è memorizzato sulla demo-board da Motorola
al momento della
produzione. Occupa un 1K byte di Flash RAM in un blocco protetto da $FC00 a $FFFF. Il
contenuto di questo blocco di memoria è alterabile solo tramite un tool basato
sull’interfaccia BDM, pertanto non vi è pericolo di cancellare accidentalmente il
programma neppure durante operazioni di erasing.
All’accensione della demo-board viene verificata lo stato di sw4, se premuto viene
attivato il serial monitor che si mette in attesa di stabilire una comunicazione, altrimenti si
avvia il programma utente.
Fra le primitive messe a disposizione troviamo Reset, Lettura e Modifica della memoria
(compresa la Flash), Lettura e Modifica Registri CPU, Go, Halt e Trace di una singola
istruzione.
Per maggiori dettagli è possibile far riferimento al documento Motorola AN2140/D, Serial
Monitor per MC9S08GB/GT.
Alessandro Mannini @ 2005
22 di 29
eBEI – embedded Boolean Expressions Interpreter
6.
EBEI UPLOADER
eBEI Uploader è un’utility che, oltre alle normali funzioni di un editor di testo, integra la
possibilità di comunicare con l’MCU tramite il Serial Monitor.
Nella figura 6.1 viene riportata una parte dello screen-shot del programma, da cui si
vedono i menù presenti. Le funzioni all’interno dei menù File e Modifica sono quelle
classiche per la creazione, apertura e salvataggio di un file .ebei nel primo, e per
copiare, tagliare e incollare del testo, nel secondo. Più interessante, invece, il contenuto
del menù MCU:
• Upload, consente di caricare nella Flash RAM le equazioni visualizzate nell’editor;
• Download, consente di visualizzare nell’editor le equazioni attualmente
memorizzate nella Flash RAM dell’MCU;
• Opzioni, permette di scegliere la porta seriale da utilizzare per la comunicazione
seriale, scegliendo fra quelle presenti nel computer;
• Esegui, manda in esecuzione l’eBEI Engine precaricato nell’MCU;
Queste funzioni vengono realizzate utilizzando le primitive del serial monitor. Per prima
cosa si stabilisce una connessione seriale e ci si sincronizza con il serial monitor
secondo
il
semplice
protocollo che ne regola le
comunicazioni
e
ne
determina lo stato.
In
seguito
è
possibile
mandare vari comandi. Per
si
utilizza
la
l’Upload
primitiva Write_Block che
consente di scrivere blocchi
di byte, fino ad un massimo
di 256 caratteri. Per il
Download, non essendo
nota a priori la lunghezza
del set di equazioni in Flash, Figura 6.1- Screen-shot dell’utilità eBEI Uploader
si utilizza Read_Byte, che
permette di leggere un byte alla volta. Infine, per Esegui si utilizza la primitiva Reset, che
appunto provoca il reset dell’MCU e, in assenza dello sw4 premuto, produce l’avvio del
programma.
Come già accennato nei paragrafi precedenti, lo spazio utilizzato per la memorizzazione
delle equazioni booleane in Flash, è pari a 50K bytes nell’intervallo $3200-$FA00, fra il
codice dell’eBEIE e quello del Serial Monitor.
Alessandro Mannini @ 2005
23 di 29
eBEI – embedded Boolean Expressions Interpreter
7.
CONCLUSIONI
Le scelte progettuali fatte si sono dimostrate valide per la realizzazione del prototipo con
le specifiche richieste. Il sistema progettato e realizzato consiste in una soluzione
preconfezionata in cui l’MCU può essere pensato come una black-box dove è prememorizzato l’engine e si possono fornire equazioni sotto forma di testo e con un
linguaggio semplice. Si tratta quindi di un semplice sistema PLC-like che permette di
implementare una determinata logica sugli ingressi e sulle uscite, senza dover conoscere
i particolari di funzionamento dell’hardware che la ospita.
Per quanto riguarda l’MCU, si può dire che esso ha dimostrato di avere delle grosse
potenzialità; infatti, le risorse messe a disposizione sono risultate più che sufficienti per
questa applicazione. Dobbiamo tener presente che l’interpretazione di un linguaggio,
seppur semplice, è un compito non banale, che solitamente viene riservato per
macchine general-purpose con molte più risorse. Inoltre, il codice ottenuto occupa poco
spazio, soprattutto se consideriamo che lo sviluppo in un linguaggio ad altro livello non
ottimizza certamente le dimensioni dell’eseguibile prodotto.
7.1. Miglioramenti
Di seguito vengono proposti alcuni possibili miglioramenti:
• ottimizzazione del codice in velocità ed spazio occupato per applicazioni reali,
magari scrivendolo direttamente in assembler;
• ottimizzazione del uso della memoria e dello stack in particolare;
• variazione della frequenza di clock per ottenere migliori prestazioni;
7.2. Sviluppi
Nell’elenco che segue sono forniti alcuni spunti per possibili sviluppi futuri:
• validazione del codice, permetterebbe di avere una black-box valicata e con
determinati criteri di affidabilità, per la programmazione logica;
• determinazione del worst-case per l’utilizzo dello stack;
• utilizzo del TPM2 per realizzare un timer che blocchi l’esecuzione se il tempo di
ciclo supera una soglia prefissata;
• spostamento della fase interpretativa sul PC, in questo modo l’interpretazione non
sarebbe ripetuta ad ogni iterazione dell’MCU ma verrebbe fatta solo una volta dal
PC, il quale trasmetterebbe all’MCU un codice intermedio sicuramente corretto e
direttamente utilizzabile per la valutazione delle espressioni;
• realizzazione della parte di interfacciamento con sensori ed attuatori per
applicazioni reali.
Alessandro Mannini @ 2005
24 di 29
eBEI – embedded Boolean Expressions Interpreter
8.
SPECIFICHE
Nella tabella sottostante sono elencati alcuni valori caratteristici del prototipo realizzato.
EQUAZIONI
Caratteri ammessi
Case sensitive
# max equazioni
Lunghezza max identificatori
Lunghezza max singola equazione
‘a’ .. ‘z’,’A’ .. ‘Z’
‘0’ .. ‘9’
‘_’
NO
50K bytes di testo in Flash
10 bytes
200 bytes
eBEI ENGINE
# max variabili
# max chiamate ricorsive
# max risultati intermedi funzioni
# ingressi
# uscite
# led stato
Alessandro Mannini @ 2005
101
100
100
4
4
1
25 di 29
eBEI – embedded Boolean Expressions Interpreter
9.
APPENDICE A
Le caratteristiche della demo-board, secondo quanto riportato dalla documentazione
ufficiale Motorola ®, sono le seguenti:
Features:
• M9S08GB60 CPU
o 60K bytes Flash
o 4K bytes Ram
o 56 I/O lines (64 pins)
o 5 channel TPM 2 Timer
o 3 channel TPM 1 Timer
o 8 channel 10 bit A/D
o SPI and IIC Serial Ports
o 2 x SCI Serial Ports
o Keyboard Wake-up Ports
o BDM DEBUG Port
o Clock generator w/ FLL
o up to 30Mhz operation
• 32Khz Crystal
• Regulated +3.3V power supply
• SCI1 Serial Port w/ RS232 DB9-S Connector
o SCI1 Serial Port
• SCI2 Serial Port w/ RS232 DB9-S Connector
o SCI2 Serial Port
• Power ON/OFF switch
• User Components Provided:
o 5 LED Indicators (PTF0-3,PTD0)
o 4 Push Switches (PTA4-7)
o Digital to Analog (PTD2, PTB1)
o 1.8Volt reference
• MCU I/O Port connector provides all digital I/O
• Analog or PTB I/O Port connector provides analog inputs or PTB I/O
• Prototype Area
• 2 x AA Battery Holder
• Supplied with DB9 Serial Cable, Documentation (CD), Manual and Batteries or
Wall plug type power supply
Specifications:
Board Size 4” x 4.5”
Power Input: +6 to +12V DC, 9V DC typical
Current Consumption: 30ma @ 9V DC input
Alessandro Mannini @ 2005
26 di 29
eBEI – embedded Boolean Expressions Interpreter
10. APPENDICE B
PRIMA
U→i=C
C→C+D
C→D
DOPO
U→i=C
C→DC’
C’→+DC’
C’→ε
D→ED’
D’→*ED’
D’→ ε
E→A
E→~A
A→i
A→k
A→(C)
D→D*E
D→E
E→A
E→~A
A→i
A→k
A→(C)
Figura 10.1 - Trasformazione per l’analisi TOP-DOWN
U
=
U
$
U
=
+
C
+
C
C
*
C’
*
C’
C’
D
D
D’
D’
~
~
D
(
(
D’
)
)
i
E
i
E
E
k
A
k
Figura 10.2- Schema determinaz. Insiemi FIRST
FIRST(U)={i}
FIRST(C)={~,i,k,(}
FIRST(C’)={+}
FIRST(D)={~,i,k,(}
FIRST(D’)={*}
FIRST(E) ={~,i,k,(}
FIRST(A) ={i,k,(}
A
A
Figura 10.3 – Schema determinaz. Insiemi FOLLOW
FOLLOW(U)={$}
FOLLOW(C)={$,)}
FOLLOW(C’)={$,)}
FOLLOW(D)={$,+,)}
FOLLOW(D’)={$,+,)}
FOLLOW(E)={$,+,),*}
FOLLOW(A)={$,+,),*}
Figura 10.4 – Insiemi FIRST e FOLLOW relativi ai simboli non terminali del linguaggio utilizzato
Alessandro Mannini @ 2005
27 di 29
eBEI – embedded Boolean Expressions Interpreter
11. APPENDICE C
Principali cartelle contenute nel CD allegato:
eBEI_V1
|
|----->
|
|----->
| |----->
| |----->
| |----->
|
|----->
| |----->
| |----->
| |----->
| |----->
| |----->
| |----->
| |----->
| |----->
| |----->
| |----->
| |----->
| |----->
|
|----->
| |----->
| |----->
| |----->
| |----->
| |----->
|
|----->
|----->
|----->
|----->
autorun
files di avvio del CD
bin
bei
ebei
ebei_uploader
eseguibili delle varie applicazioni
doc
AN2140.pdf
AN2616.pdf
GSM68DEM.pdf
HCS08RM1.pdf
IDE_Users_Guide.pdf
M68DEMS.pdf
M68DEMS.zip
Manual_Compiler_HC08.pdf
Manual_Engine_HC08.pdf
Manual_SmartLinker.pdf
MC9S08DB.pdf
relazione.pdf
documentazione dell’applicazione e dell’MCU
samples
autoritenuta.ebei
sample1.ebei
sample2.ebei
sample3.ebei
sliding5.ebei
esempi di set di equazioni booleane riconosciute da eBEI
source
bei
ebei
ebei_uploader
sorgenti e progetti delle varie applicazioni
Alessandro Mannini @ 2005
eseguibile dell’interprete PC a linea di comando
immagine memoria Flash dell’interprete embedded
eseguibile dell’utility di upload e relative librerie necessarie
Serial Monitor for MC9S08GB60 (AN2140/D)
Getting Started with HCS08 and CodeWarrior using C
Getting Started with the M68DEMO908GB60
HCS08 Reference Manual (HCS08RMV1/D)
CodeWarrior™ development tools IDE 5.1 User’s guide
M68DEMO908GB60 User's Manual
M68DEMO908GB60 Software Files
Motorola HC08/HCS08 Compiler
CodeWarrior Debugger
Smart Linker
MC9S08GB/GT Technical Data Book (MC9S08GB60/D)
descrizione del progetto eBEI
autoritenuta innescata dallo sw1
esempio 1 descritto nella relazione
esempio 2 descritto nella relazione
esempio 3 descritto nella relazione
scorrimento led innescato dallo sw1
progetto e sorgenti per Visual C++ di BEI
progetto e sorgenti per Codewarrior di eBEI
progetto e sorgenti per Visual Basic di eBEIU
28 di 29
eBEI – embedded Boolean Expressions Interpreter
12. BIBLIOGRAFIA
Linguaggi Formali e Compilatori, G. Bruno, UTET Torino
Getting Started with HCS08 and CodeWarrior using C (AN2616), Motorola
[AN2616.pdf]
MC9S08GB/GT Technical Data Book (MC9S08GB60/D), Motorola
[MC9S08DB.pdf]
HCS08 Reference Manual (HCS08RMV1/D), Motorola
[HCS08RM1.pdf]
Serial Monitor for MC9S08GB60 (AN2140/D), Motorola
[AN2140.pdf]
M68DEMO908GB60 User's Manual, Motorola
[M68DEMU.pdf]
M68DEMO908GB60 Software Files, Motorola
[M68DEMS.zip]
Getting Started with the M68DEMO908GB60, Motorola
[GSM68DEM.pdf]
CodeWarrior™ development tools IDE 5.1 User’s guide, Metrowerks
[IDE_Users_Guide.pdf]
Smart Linker, Metrowerks
[Manual_SmartLinker.pdf]
Motorola HC08/HCS08 Compiler, Metrowerks
[Manual_Compiler_HC08.pdf]
CodeWarrior Debugger, Motorola
[Manual_Engine_HC08.pdf]
Alessandro Mannini @ 2005
29 di 29