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