EEPROM e FLASH

Salve a tutti,
uso da poco arduino, e nel cercare di spulciare la documentazione che lo riguarda, ho notato che l'ATmega328 presenta oltre che una memoria flash da 32KB, anche una memoria eeprom da 1KB...
Ora da quanto mi è parso di capire, gli sketch vengono caricati sulla memoria flash (nonostante ci sia il modo di scrivere e leggere su/da eeprom...); a cosa serve quindi la eeprom?? Al suo interno è presente un qualche eseguibile vitale per il microcontrollore, oppure è solo un'altra memoria messa a disposizione?

Inoltre mi chiedevo, il bootloader si occupa solo del trasferimento dei dati tra pc e flash, o anche tra flash e ram al momento dell'esecuzione?? Se no, sarebbe possibile reperire informazioni riguardo a "chi" si occupa del trasferimento dei dati in ram per l'esecuzione?

Mi scuso in anticipo per la mole di quesitiche ho concentrato in questo unico post, ma qualche settimana con arduino e mi si è aperto un mondo! Ne vorrei sapere di più nello specifico!

Ringrazio tutti anticipatamente!

In merito alla eeprom posso risponderti. Serve per salvare dati che intendi mantenere tra una sessione e l'altra di lavoro.
In parole povere, mettiamo che tu abbia un progetto e che in qualche modo puoi fare una configurazione, questa configurazione la vuoi salvare in modo che il tuo sketch utilizzi quei dati anche quando avrai spento arduino. In questo caso puoi utilizzare quella eeprom.

Intanto grazie per la risposta celere!!
Quindi la eeprom in un contesto come quello da te citato diventa necessaria perchè uno sketch in esecuzione non potrebbe scrivere su memoria flash giusto?

Precisamente. A quanto ne so il compilatore puo' scrivere sulla memoria flash (ma immagino ci sanno hack varii per eludere queste cose). Tieni conto che la memoria eeprom dovrebbe avere "vita breve" percui va utilizzata con intelligenza!

La EEPROM non ha vita breve, "regge" 100.000 riscritture, a differenza della Flash che ne regge "solo" 10.000 (http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf).

La EEPROM, come ha detto Federico, serve per salvare dati. Tutti gli Atmega sono basati sull'architettura Harvard che prevede una separazione fra la memoria del programma (la Flash) e quella dei dati, che è un terzo tipo di memoria contenuta nel microcontrollore, cioè la SRAM. Questa è volatile ma permette un numero di scritture praticamente infinito.

Gli Atmega168/328 non hanno però la possibilità di eseguire un programma che non risieda nella Flash, per cui il tuo sketch, a differenza dei dati, può risiedere solo al suo interno. Invece, puoi usare la memoria Flash per contenere i dati, usando la direttiva PROGMEM durante la dichiarazione delle variabili. Ma, a mio avviso, è bene provvedere ad usare una memoria esterna dato che, come detto, i cicli di riscrittura della Flash non sono molti per cui andresti ad intaccare la vita della memoria. Invece un Atmega può comandare un chip EEPROM I2C esterno oppure anche una schedina SD per memorizzare dati voluminosi (tipo log).

Altri due piccoli appunti:

  • le funzioni che leggono e scrivono sulla eeprom agiscono direttamente sulle celle della memoria, quindi possono scrivere solo un byte alla volta.
  • la scrittura è relativamente lenta, va bene per salvare il valore di variabili che non vuoi che vadano perse, come ha detto federico

Nel playground ci sono parecchi esempi io ne ho usato una che salva una struct in eeprom e non mi è sembrata lenta, comunque si di base un byte alla volta.

@leo72

Invece, puoi usare la memoria Flash per contenere i dati, usando la direttiva PROGMEM durante la dichiarazione delle variabili. Ma, a mio avviso, è bene provvedere ad usare una memoria esterna dato che, come detto, i cicli di riscrittura della Flash non sono molti per cui andresti ad intaccare la vita della memoria. Invece un Atmega può comandare un chip EEPROM I2C esterno oppure anche una schedina SD per memorizzare dati voluminosi (tipo log).

Qui però mi è venuto il dubbio, io avevo capito che non è possibile scrivere a run-time nella memoria di programma (flash), ma è solo possibile leggere dalla flash delle variabili tramite un puntatore ad indirizzo in flash dove abbiamo mappato la variabile. Cioè il programma quando è in esecuzione non può scrivere nella flash come se si trattase di un disco.

Comunque al momento sto studiano il C/C++ bene bene, a PROGMEM e una macro che sotto mentite spoglie forse ricorre a #pragma e questa si che un direttiva del preprocessore.

Inoltre mi chiedevo, il bootloader si occupa solo del trasferimento dei dati tra pc e flash, o anche tra flash e ram al momento dell'esecuzione?? Se no, sarebbe possibile reperire informazioni riguardo a "chi" si occupa del trasferimento dei dati in ram per l'esecuzione?

Non devi preoccuparti di chi si occupa di trasferire il programma in ram perchè questo non avviene, il compilatore trasforma il codice in assembler il quale usa i 32 registri temporanei detti general purpose per elaborare il programma, questo non risiede mai completamente in ram come avviene con i microprocessori, come dice leo questo dipenda da l'architettura Harvard.

Trovi maggiori info sul sito di atmel, vedi le application note.

Ciao.

Grazie per le risposte!
L'ultima domanda invece mi interessa molto, in quanto sto cercando di estendere la memoria flash con una SD esterna, gestendo il tutto con un piccolo sistema operativo che dovrebbe risiedere in memoria flash (sono un laureando in informatica)
Ho letto il manuale dell'atmega328, ed ho notato che la memoria flash è divisa in due zone, ma solo la zona finale è dedicata al bootloade. Ne segue che in effetti la memoria flash si comporta come se fosse una ram estesa; infatti la prima istruzione eseguita è quella che risiede all'indirizzo 0x0000 della flash. Quindi vengono eseguite le istruzioni seguenti sino al blocco indicante il bootloadr, per poi ricominciare da capo (ecco la necessità della funzione loop() negli sketch...). Ne segue che la ram viene utilizzata solo per procedure di storage temporaneo di dati per calcoli e giù di lì... infatti viene usata anche come stack per le operazioni tra registri, e nel caso si usi un indirizzamento indiretto della flash a 16bit invece che a 8bit.
Questo è quello che mi pare di aver capito... magari se mi sbaglio mi piacerebbe essere corretto da chi ne sa più di me...

Arrivederci!

Io dico che devi rileggere il datasheet del 328 integrandolo con le application note sull'architettura Harvard.
Leo72 voleva usare della ram esterna dove caricarci un programma (nel suo caso un gioco) e poi dire al 328 ora esegui il programma in ram, nè è venuto fuori che non si può fare.
Estendere la flash idem penso che non si possa fare.
Quello che posso dire con certezza è :
La divisione della flash in due sezione è opzionale ed è attivata tramite fuse.
La funzione loop di arduino ha lo scopo di facilitare la programmazione al principiante come già stato detto anche da Massimo Banzi un milione di anni fà, il non principiante capisce che se il programma non ha un loop principale la cosa non può funzionare, se consideri anche il sistema operativo ha un loop principale solo che non si vede, ma questo lo sai benissimo.

Nella funzione loop puoi benissimo non fargli fare nulla, ed usare la programmazione ad eventi, ho scoperto che se imposti un pin in uscita e su quel pin attivi l'interrupt cambiando stato a quel pin generi quello che chiamano interrupts software. A seguito di un interrupts il programma salta alla routine di interrupt che hanno macro predefinite con nomi che iniziano con ISR. Anche i timer hanno delle routine di interrupt, così come la USART, ma sai che le hanno tutte le "periferiche" un interrupts.

Cosa vuoi fare RTOS? (Real Time Operating System).

C'è già peccato che non ho tempo mi piacerebbe leggere il codice di uno di questi RTOS.

Ciao.

Si esatto, un sistema operativo real time a quanto di tempo, così da cercare di eseguire più di un programma alla volta, a parte il sistema operativo avviamente...
L'idea, per ora teorica, è quella di usare la flash e la eeprom come memoria per il sistema operativo a basso livello; questo dovrà permettere un indirizzamento tramite offset per una memoria esterna, che sia una SD o una penna USB. Una interfaccia con display lcd permette la scelta del software da eseguire.
Come detto da te, il sistema operativo è ciclico nel controllo degli eventi, e permette l'indirizzamento della periferica esterna, cosa che non potrebbe avvenire altrimenti, visto che lo spazio di indirizzamento fisico è limitato da registri ad 8 bit, o nell'indirizzamento indiretto da 3 registri a 16 bit (6 registri da 8 bit collegati); in sostanza il SO ricreerebbe un bus dati verso una periferica di massa esterna...

Per il momento comunque l'idea è nascente e di certo non ancora applicabile... Ma almeno ora ho più dati su cui fare affidamento!

Un attimo.
Quando si parla di memoria del programma, si intende la Flash.
Un Atmega168/328 (quelli delle ultime schede di Arduino) hanno 3 tipi di memoria:
FLASH: è usata per memorizzare il bootloader ed il programma dell'utente (sketch)
SRAM: è usata per creare le variabili durante l'esecuzione del programma
EEPROM: memoria di appoggio, che è possibile utilizzare per memorizzare valori che l'utente vuole mantenere anche con l'alimentazione scollegata.

Detto questo, per un Atmega168/328 NON è possibile utilizzare nessun tipo di memoria esterna (sia essa RAM, Flash o altro) per memorizzare codice eseguibile perché tali uC non hanno un'interfaccia di memoria per poter indirizzare il puntatore delle istruzioni in uno spazio di memoria esterno a quello inglobato nel microprocessore. L'unico Atmega (che io sappia) capace di utilizzare memoria esterna come espansione della SRAM è l'Atmega128.

La direttiva PROGMEM serve, in fase di compilazione, ad indicare al compilatore che le variabili indicate da tale direttiva devono essere create in Flash piuttosto che in SRAM. Tale funzione può essere utile nel caso di Atmega con molta Flash (ad esempio i 328 con 32 KB o i 644 con 64 KB) per creare, ad esempio, dei buffer molto ingombranti. Considera che nella SRAM viene creato anche lo stack e l'heap ed i registri sono anch'essi tenuti in SRAM.

Come RTOS, devi considerare che gli Atmega non hanno il multitasking nativo, per cui un RTOS sarebbe comunque sempre limitato.
Googlando ho trovato questo:

Potrebbe essere interessante

Cmq, ripeto: NON puoi memorizzare programmi esterni ed eseguirli dal loro supporto. Il codice deve sempre trovarsi nella Flash interna. Qualcuno ha trovato una soluzione. Se cerchi la console Uzebox su Google, vedrai che stanno lavorando ad un bootloader capace di caricare un file binario da una SD esterna e riprogrammare la Flash del uC.

EDIT:
segnalo anche questa pagina:

Ci sono link ad altri RTOS:
http://www.drtak.org/develops/RTK/
http://www.lancos.com/mthreads.asm.html
http://www.atmanecl.com/EnglishSite/opex.htm
http://www.nbb.cornell.edu/neurobio/land/STUDENTPROJ/2000to2001/greenblattCOMATOS/intro.html

http://www.chris.obyrne.com/yavrtos/

La soluzione al problema da te esposto è nella progettazione di uno sketch-sistema-operativo, che permetta una indirizzazzione software verso il supporto esterno; quindi semplicemente il microcontrollore non si accorgerebbe di andare a pescare istruzione all'esterno... infatti verrebbe indirizzato fisicamente sempre un blocco di istruzioni in flash, responsabile della lettura dei dati dall'esterno... l'idea può funzionare, si tratta di creare un programma che esegue programmi in sostanza, ovvero una macchina virtuale che astragga i limiti fisici del microcontrollore...

C'è un problema.
Siccome il uC non ha un'interfaccia per accedere ad una memoria esterna, il puntatore programma (PC) punta solo la Flash interna.
Creare uno sketch che copi dalla memoria esterna alla memoria interna le istruzioni da eseguire via via ed in tempo reale mi sa che non sia fattibile perché in questo modo i cicli di scrittura della Flash si esaurirebbero velocemente.

infatti il codice nella sd non deve essere trasferito in flash è una soluzione improponibile; bensì si potrebbe prevedere una cosa del tipo:

[u]Programma falsh:[/u]

cicla fino a condizione
{
      *instruzione;
}

dove *istruzione punta ad una istruzione in memoria esterna;

Ne segue che il PC resta sul ciclo e passa sempre per *istruzione, che ogni volta è una nuova istruzione, proveniente da sd...

Credo che ci sia un modo anche migliore di farlo... ma ora sono in periodo esami... XD

Ciao seppe

Non é possibile perché non puoi eseguire dei comandi in linguaggio macchina fuori dalla memoria Flash. Il puntatore non ci arriva. 8)

Perche Ti ostini di provare di fare quacosa per la quale i micorcontroller non sono fatti. :wink:

Il vantaggio é che i microcontroller hanno integrato la memoria perché non é necessario aggiungere un intergato RAM o ROM per farli funzionare. Questa architettura fa che Ti bastano pocchisimi componenti esterni. Questo é un vantaggio di lavoro e costo.

Se vuoi usare della memoria esterna usa un Microprocessore.

Ciao Uwe

infatti il codice nella sd non deve essere trasferito in flash è una soluzione improponibile; bensì si potrebbe prevedere una cosa del tipo:
Ne segue che il PC resta sul ciclo e passa sempre per *istruzione, che ogni volta è una nuova istruzione, proveniente da sd...
Credo che ci sia un modo anche migliore di farlo... ma ora sono in periodo esami... smiley-lol

Ok una macchina virtuale potrebbe fare quello che dici, però sembra più un'interprete che una macchina virtuale, ammeno che non si riesca in poco spazio a creare qualcosa come java che a me sembra l'unica soluzione, però non puoi usare i registri ne tantomeno le istruzioni assembley.

Vediamo nel ciclo ho una read(PC) che ritorna un codice diciamo 0xff, a questo corrisponde un'istruzione ad alto livello per impostare un bit di una porta, quindi chiamo la funzione passandogli gli argomenti.
Fin qui funzionerebbe, se ci pensate bene firmata fa fare al micro delle cose tramite il collegamento seriale, dove la differenza basta aggiungere un puntatore ad SD esterna e nel micro mettere l'interprete o la vm.

Io non scoraggierei mai nessuno, cosa ne esce fuori lo si può scoprire solo dopo averlo implementato, già adesso però si può dire:
Posso eseguire codice esterno ma la memoria ram è sempre quella del micro ammeno di non espanderla con memoria su i2c.
Sarà sicuramente lenta l'esecuzione ma certo sempre più veloce di firmata.

Certo che è un gran bel lavoro.

Ok auguri per gli esami.
Ciao,

vedremo... spero di riuscirci a combinare quanlcosa...
grazie per gli auguri!

Scusate una precisazione quando ho scritto vita breve della eeprom. Se la flash ha 10mila scritture vuol dire che probabilmente dovro' flashare il mio chip 10mila volte per consumarlo, il che mi richiedera' tanto tempo se io utilizzassi sempre lo stesso chip per programmare. Se la eeprom ha 100mila scritture e metto un ciclo di scrittura in un loop di arduino la uccido in 2 minuti...

Scusate una precisazione quando ho scritto vita breve della eeprom. Se la flash ha 10mila scritture vuol dire che probabilmente dovro' flashare il mio chip 10mila volte per consumarlo, il che mi richiedera' tanto tempo se io utilizzassi sempre lo stesso chip per programmare. Se la eeprom ha 100mila scritture e metto un ciclo di scrittura in un loop di arduino la uccido in 2 minuti...

Appunto, quindi?
Tu dici il ciclo di cui sopra, mi è sembrato di aver capito che non era questa l'intenzione, infatti dice:

infatti il codice nella sd non deve essere trasferito in flash è una soluzione improponibile;

Tra l'altro mi pare che leo72 stava sperimentado un'interprete solo che non ricordo il nome (e rimasto nei vecchi post), comunque in questo senso la cosa è possibile, ma c'è da vedere le limitazioni.

Ciao.

L'interprete si chiama Bitlash (http://bitlash.net/wiki/).
E' molto potente, limitatamente alla sua dimensione. Permette di eseguire un sacco di comandi su emulazione di terminale oppure di eseguire anche script salvati su file testuali memorizzati su SD.
Il linguaggio possiede un discreto numero di istruzioni e comandi tali da poter sostituire il C nelle applicazioni comuni (per "comuni" intendo strutturare cicli condizionali, interagire con i PIN, ecc...) e permette anche di creare comandi definiti dall'utente.