Ciao,
stavo cercando di capire come funziona la eeprom sul 328. Ho letto il datasheet, poi ho fatto una ricerca qui e mi sono imbattuto in questo interessantissimo thread (che però è chiuso in quanto vecchio di qualche mese):
http://arduino.cc/forum/index.php/topic,88054.15.htmlIl mio dubbio riguarda(va) il "blocco" (attesa) del programma quando si scrive sulla eeprom, e deriva principalmente dal fatto che finora ho utilizzato soltanto le istruzini EEPROM.write() e EEPROM.read() di Arduino. Ho notato che la scrittura consecutiva di alcune centinaia di byte in eeprom (ad esempio un intero array) richiede un tempo apprezzabile, e dal punto di vista dell'effetto sul codice del programma principale somiglia molto ad una delay().
Come dicevo, per dissipare i miei dubbi ho letto il datasheet del 328 (pagg. 21 e seguenti), poi il thread suddetto e infine i sorgenti EEPROM.h e arduino-1.0.2/hardware/tools/avr/lib/avr/include/avr/eeprom.h
In quest'ultimo file ho scoperto che tutte le funzioni di accesso alla eeprom iniziano con una
busy wait per attendere il completamento di un'eventuale operazione precedente di accesso alla eeprom (in pratica attendono che la periferica hw che si occupa della eeprom a basso livello sia pronta).
Inoltre il commento all'inizio del file dice che la modalità di scrittura utilizzata è quella "atomica" (erase+write), quindi i tempi di completamento della scrittura di un byte sono di 3.4ms (pag. 22 datasheet, Table 8-1).
Il risultato è che se scrivo 10 byte in fila blocco (nel senso della delay()) il mio programma per circa 34ms o_O
Vengo quindi alle mie due considerazioni e mezzo:
1) se al momento di scrivere un byte sulla eeprom non è in corso alcuna operazione di i/o sulla eeprom stessa, allora EEPROM.write() ritorna subito, senza attendere che la scrittura termini. Questo significa che se mi accontento di scrivere in eeprom un singolo byte alla volta ad una distanza minima di 4ms l'uno dall'altro, non ho alcun rallentamento al flusso del programma.
E' giusto ?
2) se scrivo più byte consecutivamente, come fa ad esempio fa EEPROMWriteAnything, non interferisco in alcun modo con gli interrupt, perché il
busy wait sulla condizione di "eeprom pronta" è un normale ciclo wait che legge un bit da un registro, quindi può essere tranqullamente interrotto. La sezione critica, cioè le istruzioni eseguite con gli interrupt disabilitati, dura solo 4 o 5 istruzioni assembly, quindi se arriva un interrupt proprio lì in mezzo, viene memorizzato e servito non appena viene chiamata la sei() al termine della sezione critica, pochi us più tardi.
Ho capito bene ? (lo so che il punto 2 non c'entra nulla con la domanda iniziale, ma già che siamo in tema...

)
2.5) Se volessi salvare 'sto benedetto array di 200 byte senza bloccare il programma principale, dovrei scrivere una funzione che utilizza la tecnica di "blink without delay" per cadenzare le scritture di singoli byte ogni (diciamo) 5ms, oppure replicare per la eeprom il meccanismo di scrittura ad interrupt usato nella Serial.write delle ultime release... In pratica dovrei usare un buffer temporaneo in cui copio i dati da scrivere, poi lancio la scrittura del primo byte e lascio finire il lavoro alla ISR che risponde all'int EE READY
