ATTiny85: un microcontrollore a 8 bit capace di grandi imprese.

Quando la programmazione diventa gioco e passione, non esiste alcun esperimento che non abbia senso... In questo, Dmitry Grimberg, un geniale programmatore russo, appare pioniere ed ispiratore. Il suo nuovo esperimento, infatti, è davvero destinato a destare stupore e meraviglia. Guardate che cos'ha fatto questa volta.

Pochi giorni fa ci siamo occupati in un lavoro portato a termine da Dmitry Grimberg, eclettico programmatore russo trapiantato in California, che dal suo blog aveva mostrato le meraviglie di Ubuntu avviato su un microcontrollore a 8 bit.

Ebbene, come egli stesso dichiara apertamente, ciò che più lo diverte è scrivere emulatori. La domanda alla quale ha voluto rispondere con questo nuovo post è: “Quanto velocemente è possibile emulare una CPU ARM su un dispositivo ATMEGA?”.

Ebbene, per rispondere a questa domanda, Grimberg ha cercato di emulare un Cortex-M0 su un ATTiny 85. Tramite l'aggiunta delle istruzioni per fare “byte reversal”, oltre ad alcuni registri di stato, da lui stessi definiti “stravaganti”, il set di comandi usato è ARMv6-M.

Il ricorso a questi registri così particolari, per sua stessa ammissione, non è stato fatto fino a quando non si è reso assolutamente indispensabile.

L'emulatore in questione è stato scritto in linguaggio C, che pare essere molto gradito a Gimberg, e col quale egli pare essere molto a suo agio; uno stadio successivo ha richiesto la riscrittura direttamente nel linguaggio assembly di AVR. Questo ha l'indubbio vantaggio di essere decisamente più veloce di un emulatore per linguaggio C, il che, a ben guardare, è proprio uno degli obiettivi del programmatore: mettere in evidenza quanto effettivamente sia inadeguato il compilatore AVR-GCC.

Vediamo che risultati ha ottenuto Grimberg.

La mappa della memoria del Cortex emulato prevede allocazioni da 0x40000000 a 0x4000FFFF e permette l'accesso ai primi 64 KB della memoria, di tipo flash, dell'AVR. Questo può essere facilmente modificato per fare in modo da supportare componenti con una quantità di memoria flash disponibile molto maggiore ma in questo caso non è questa la scelta che è stata fatta perché esisteva il rischio concreto che il codice non potesse essere eseguito proprio su questo ATTiny.

Le allocazioni 0x20000000-0x2000FFFF permettono l'accesso diretto alla RAM dell'host AVR, e ciò comporta anche la possibilità di eseguire operazioni di input/output.

Il numero di dispositivi supportati è piuttosto ampio; il codice assembly, richiede che il dispositivo supporti le istruzioni LPM e MOVW.

L'emulatore che è stato scritto per questo esperimento consta di 1300 righe di codice e ciò lo rende perfetto proprio per l'ATTiny85. Uno dei problemi incontrati, però, sta nel fatto che la serie ATTiny della AVR non ha la possibilità di seguire istruzioni multiple. Per fare in modo, quindi, che il codice potesse girare sia su ATTiny sia su ATmega, e farlo ad una velocità accettabile, se non ottimale, l'esecuzione con istruzioni multiple è stata emulata da un file separato.

L'intero emulatore, peraltro, è molto contenuto in termini di dimensioni: esso, infatti, può “stare” in una memoria RAM di dimensioni pari a 61 byte. Questa cifra, piuttosto esigua, può ancora essere ridotta al prezzo di un'esecuzione certamente più lenta. Una stima di questo rallentamento è stata fatta intorno al 3%.

Il codice dell'emulatore utilizza due livelli di chiamate, in modo tale che l'AVR abbia solo bisogno di 4 byte di “stack”. Ciò comporta che la memoria RAM rimane, grosso modo, libera per poter garantire l'esecuzione del codice. All'avvio, l'emulatore “resetta” lo stack, lasciando però 12 byte liberi. Tramite questa procedura, viene garantito al codice lo “spazio” necessario per l'esecuzione.

Ovviamente, il codice emulato ha accesso “illimitato” alle periferiche dell'AVR. Ma non basta! Una delle funzioni implementate, per fare un esempio, può garantire ad un utente di accedere ai registri di lettura al fine di lavorare direttamente sui parametri è scriverli, per fare in modo, ad esempio, che questi si trasformino in valori restituiti, secondo le necessità.

Per fare una prova, è stata implementata una funzione di trasmissione UART, tramite una funzione scritta ad hoc, per scrivere su questa interfaccia.

E adesso, alcuni parametri operativi. Su ATTini85 a 16 MHz, in media, la CPU emulata gira a 200 kHz. Inutile dire che questo è un ottimo risultato, se si considera il fatto che è stato ottenuto su una CPU a 32 bit. Per fare un confronto più equo, utilizzando delle operazioni scritte a 32 bit su un ATTiny, esso ne puoi seguire circa 3 milioni al secondo; quindi l'emulatore riesce a garantire un “overhead” di 10 volte.

Un gran bell'esercizio di programmazione, non trovate?

Il risultato più interessante che ha ottenuto Grinberg sta proprio nel fatto che si riesce a far svolgere all'ATTiny anche compiti di esecuzione di programmi molto “grossi”. Ovviamente tutto questo può essere molto migliorato se si dota l'hardware di una maggiore quantità di memoria RAM.

Proprio sul suo sito, se siete curiosi, è possibile scaricare direttamente il codice al link troverete indicato nei commenti. Alcuni di questi, in particolare, esprimono pareri piuttosto tecnici e specializzati sull'argomento, per cui, sono certo, troverete la lettura piuttosto interessante.

Nel frattempo, ditemi: avete mai provato un esperimento così?

Scarica subito una copia gratis
Tags:,

Scrivi un commento

Seguici anche sul tuo Social Network preferito!

Send this to a friend