Il microcontrollore Propeller è un dispositivo della Parallax inc. contenente otto processori RISC a 32 bit e può gestire direttamente un’uscita video VGA, video composito, tastiera, mouse ed altro ancora. La programmazione del chip è notevolmente semplificata grazie all’ambiente di sviluppo integrato Propeller Editor/Development System.
Introduzione
L’architettura interna del Propeller è costituita da otto processori di tipo RISC a 32 bit indipendenti, tutti uguali, sincronizzati dallo stesso clock che può arrivare alla frequenza massima di 80MHz. Gli otto processori, chiamati COG, condividono le risorse comuni del Propeller quali registri di I/O e timer, mentre l’accesso alla memoria RAM/ROM avviene tramite un HUB che sincronizza le richieste dei singoli COG. Per questo motivo, per definire il Propeller, è più appropriato il termine multicontrollore. I vantaggi di questa architettura sono molteplici. L’assenza di vincoli o di strutture predefinite lascia ampio spazio al progettista che può costruire l’applicazione con la massima libertà. In questo modo si può ridurre drasticamente la complessità suddividendo le funzioni tra gli otto COG ed utilizzando la RAM dell’HUB per la condivisione dei dati. Si può attuare, cioè, una sorta di parallelismo a livello di istruzioni. Per la programmazione del dispositivo sono sufficienti pochi componenti esterni, come mostrato in Figura 1.
Il Propeller Plug deve essere necessariamente utilizzato con l’ambiente di sviluppo per la programmazione ed il debug. Esso provvede a trasformare l’interfaccia seriale del micro in una USB collegabile al PC. La Figura 2 riporta, invece, un kit di sviluppo proposto da Parallax.
Si nota, tra l’altro, la presenza del connettore video VGA per interfacciare semplicemente il micro ad un dispositivo compatibile.
Linguaggio di programmazione
Per ottenere le prestazioni migliori con questi dispositivi è necessario ricorrere al linguaggio assembly. La difficoltà di sviluppare progetti in assembly ha portato la casa produttrice a creare un linguaggio interpretato di più alto livello: lo Spin. Nella ROM del Propeller c’è una copia dell’interprete simile al basic che però presenta alcune caratteristiche di linguaggi più evoluti come la definizione di oggetti. Non si tratta di un linguaggio ad oggetti vero e proprio ma si possono realizzare dei moduli in cui sono definite le strutture dati, le funzioni pubbliche e l’insieme delle funzioni private scritte sia in linguaggio SPIN che in assembly. Ogni oggetto avrà la sua interfaccia pubblica e può a sua volta includere altri oggetti. La definizione degli oggetti è uno dei punti di forza dello Spin, poiché è possibile creare dei moduli per le funzioni base riutilizzabili facilmente in nuovi progetti. La stessa Parallax per incoraggiare la condivisione dei vari moduli ha creato un’area apposita nel proprio sito: il Propeller ObjectExchange. Nell’IDE di sviluppo ci sono delle funzioni particolari per facilitare lo scambio e la condivisione dei moduli. Ad esempio, grazie ad un font true type, appositamente sviluppato dalla Parallax, è possibile aggiungere al listato dei commenti con disegni e piccoli schemi hardware. In questo modo si può integrare la documentazione completa nel listato del codice. Tramite un’opzione dell’IDE è possibile generare un file zip che include tutto il progetto attuale e una copia dell’IDE stesso evitando così eventuali problemi di compatibilità tra versioni differenti del sistema di sviluppo.
UTILIZZO DEL PROPELLER TOOLS
La finestra principale
L'ambiente di sviluppo integrato Propeller Tools (PT) rappresenta una piattaforma unica per la programmazione ed il testing dei dispositivi Propeller. Il PT è stato progettato con l’idea di fornire quante più funzioni utili al programmatore, pur rimanendo semplice e permettendo un rapido apprendimento da parte di chi si avvicina a questi chip per la prima volta. La schermata principale del software è suddivisa in quattro pannelli principali (come mostrato in Figura 3).
I pannelli 1, 2, 3 sono parte integrante dell’Integrated Explorer. Esso fornisce indicazioni circa il progetto su cui si sta lavorando. Il pannello 4 rappresenta l’area in cui scrive il codice sorgente. Tramite la combinazione di tasti Ctrl+E si può espandere l’area di codice e nascondere quella relativa all’Explorer. Il pannello 1 (Object View) permette la visualizzazione degli oggetti definiti nel codice sorgente. Infatti, il linguaggio Spin è di tipo object-based ed un progetto può essere costituito da più oggetti. L’elenco completo degli oggetti sarà visualizzato in questa sezione. Nella Figura 3, per esempio, è presente l’oggetto VGA che serve per gestire la porta video. Il pannello 2 (Recent Folder e Folder List) serve per semplificare la navigazione tra le directory ed i file di progetto Propeller, molto simile al Risorse del computer di Windows. Il pannello 3 (File List e Filter Field) è utilizzato in combinazione con il precedente pannello per visualizzare la lista completa dei file disponibili nella directory selezionata. È possibile visualizzare l’intera lista dei file oppure filtrare solo particolari estensioni come spin, binary, eeprom. Il pannello 4 (Editor) visualizza il codice sorgente del file con estensione spin.
La sezione Editor può visualizzare il codice sorgente in differenti modalità:
- Full Sorce
- Condensed
- Summary
- Documentation
Poiché un progetto può essere costituito da molti oggetti, può essere difficoltoso per il programmatore scorrere continuamente il listato. Per questo motivo è possibile trascinare e spostare in qualunque parte della finestra ciascun tab e sistemarlo come meglio si crede. La barra di stato (presente nella parte bassa della finestra) è suddivisa in sei pannelli. Ciascuno dei quali visualizza utili informazioni relative ai diversi step del progetto.
Compilazione e download del codice
Per la compilazione e donwload del codice selezionare RunxCompile CurrentxLoad RAM oppure usare il tasto di scelta rapito F10. Se, invece, si vogliono visualizzare le informazioni di progetto selezionare RunxCompile CurrentxView Info. Sarà visualizzata la schermata mostra in Figura 4.
Essa riporta utili informazioni relative al progetto, tra cui dimensione del codice oggetto, occupazione di memoria RAM, frequenza operativa e rappresentazione esadecimale del codice. Nell’esempio di Figura 4 si utilizza un clock di 5MHz, portato a 80MHz grazie al PLL integrato. Tramite i pulsanti Load RAM e Load EEPROM si carica nelle rispettive aree di memoria il codice sorgente. Ovviamente, per eseguire questa operazione è necessario connettere, tramite il Prop Plug (Figura 5), il micro Propeller. Per verificare la corretta connessione è possibile fare click su RunxIdentify Hardware oppure utilizzare lo shortcut F7. Sarà mostrata una figura simile a quella riportata in Figura 6.
I commenti con Propeller Tools
Una funzionalità che aiuta il programmatore in fase di documentazione è rappresentata della finestra Character Chart. Quando si installa il software, infatti, viene aggiunto un nuovo tipo di font (chiamato Propeller) che serve per la rappresentazione di simboli circuitali come quelli in Figura 7.
Questo particolare tipo di commento può essere inserito in qualunque parte del codice per meglio chiarirlo. Per accedere alla suddetta finestra, selezionare HelpxView Character Chart (Figura 8).
La programmazione ad oggetti
Il linguaggio di programmazione Spin è di tipo object-based. Per oggetto si intende un porzione di codice, scritto in modo tale che:
- Rappresenta una unità a se stante;
- Esegue un compito specifico;
- Può essere riutilizzata da altre applicazioni.
Ad esempio, l’oggetto Keyboard (fornito con il software Propeller Tools) è un programma che consente al chip Propeller di interfacciarsi con una tastiera PS/2. Analogamente, l’oggetto Mouse serve per gestire un mouse. In Figura 9 è riportato il firmware per la cattura dei tasti digitati da tastiera e la relativa visualizzazione a monitor.
Come si nota tra gli oggetti definiti nella sezione OBJ si trova kb che è di tipo “keyboard”. Tale oggetto sarà dotato di metodi e proprietà, esattamente come accade in qualunque linguaggio di programmazione ad oggetti. Per avviare l’oggetto tastiera bisogna richiamare il metodo start usando la sintassi:
kb.start(26,27)
I parametri passati al metodo start rappresentano il data signal e il clock signal per l’inizializzazione della tastiera. Per la lettura, invece, del tasto premuto da tastiera si deve utilizzare il metodo getkey con la sintassi:
kb.getkey()
Per ulteriori informazioni su tutti i metodi dell’oggetto è sufficiente selezionare l’oggetto nell’Object File e selezionare la visualizzazione Documentation nel pannello Editor.
ESEMPI PRATICI CON PROPELLER TOOLS
Il Listato 1 è un semplice esempio di codice scritto in Spin che effettua, ripetutamente, il toggle di un pin I/O. Si fa notare che il linguaggio Spin non è case-sensitive.
CON Pin = 16 { pin I/O su cui effettuare il toggle } Delay = 3_000_000 PUB Toggle dira[Pin]~~ { Impostazione pin di uscita } repeat { Loop infinito } !outa[Pin] { Toggle del pin } waitcnt(Delay + cnt) { Ritardo/Attesa }
Listato 1 |
Per compilare ed effettuare contemporaneamente il download è sufficiente premere il tasto F10. Se non ci sono errori. Il codice sarà caricato in RAM (Figura 10).
Con il tasto F11 si procede, invece, al download in EEPROM. La possibilità di scegliere tra il download in RAM e in EEPROM non è proprio di tutti i microcontroller. Ovviamente, scegliendo la prima soluzione il firmware è cancellato dopo lo spegnimento del micro. Ci si potrebbe chiedere perché allora utilizzare la prima soluzione anziché la seconda? Se si prova ad effettuare il download in EEPROM ci si rende conto che il processo di programmazione risulta molto più lento: quindi in fase di sviluppo del firmware è consigliabile scaricare il firmware in RAM, mentre quando il codice è pronto si può utilizzare l’altra soluzione. Una EEPROM, inoltre, dispone di un numero finito di riscritture: quindi questo è anche un modo per preservare la durata del dispositivo di memorizzazione permanente. Il Propeller dispone di 8 identici processori chiamati COG. Ciascuno di essi può essere avviato oppure arrestato a run-time, eseguire un task indipendenti oppure processi cooperativi con altri COG. Nell’esempio del Listato 1 non è stato specificato nessun processore e quindi sarà utilizzato in automatico il COG 0, secondo lo schema a blocchi in Figura 11.
Sempre con riferimento all’esempio del Listato 1 gli altri sette COG resteranno in uno stato “dormiente” e la corrente assorbita da questi sarà praticamente nulla. Ma la potenza del Propeller si può apprezzare non tanto nella programmazione seriale (1 solo COG attivato), ma piuttosto con la programmazione parallela: quando cioè si utilizzano più COG per eseguire più task. Un esempio è riportato nel Listato 2, in cui si effettua il toggle contemporaneo su due pin del micro (il pin 16 ed il 17) con frequenze e periodi differenti.
{Output.spin} VAR long Stack[9] ‘Stack space for new cog PUB Main cognew(Toggle(16, 3_000_000, 10), @Stack) ‘Toggle P16 ten… Toggle(17, 2_000_000, 20) ‘Toggle P17 twenty… PUB Toggle(Pin, Delay, Count) {{Toggle Pin, Count times with Delay clock cycles in between.}} dira[Pin]~~ ‘Set I/O pin to output direction repeat Count ‘Repeat for Count iterations !outa[Pin] ‘ Toggle I/O Pin waitcnt(Delay + cnt) ‘ Wait for Delay cycles
Listato 2 |
Tra i comandi più interessanti di questo esempio sicuramente bisogna citare COGNEW. Esso consente di attivare un nuovo COG. Il primo parametro rappresenta il task da eseguire, mentre il secondo indica al COG di utilizzare la Main RAM a partire da quell’indirizzo. In questo caso sono stati riservati 36 byte (9 × 4 byte). Lo schema a blocchi dell’applicazione appena descritta è riportata in Figura 11.
La parallax ha sempre fatto ottimi dispositivi, in particolare ho utilizzato un modulo GPS implementato con un PIC.