Ciao a tutti.
Su un piccolo progetto operativo da qualche anno ogni tanto riscontro che alcuni valori salvati in eeprom si cancellano / "rovinano". Ovvero quando vado a leggerli mi ritrovo con dei valori che non sono gli stessi che avevo memorizzato e che non hanno nessuna logica.
Quando succede vado a reinserire i valori corretti e tutto torna a funzonare in modo assolutamente normale.
Diciamo che in tutto sarà successo 5 / 6 volte da quando il progetto è operativo.
Ho tenuto il conto delle scritture e sono decisamente molto lontano dai limiti dichiarati.
Tenderei anche ad escludere un problema software perché le scritture vengono effettuate solo in determinati casi che prevedono l'inserimento di un codice numerico, l'inserimento del dato da scrivere e la pressione di un tasto di conferma.
Considerando che è un atmega in standalone, ci possono essere delle cause hardware per questo comportamento?
Capisco che senza vedere la situazione reale è un po' sparare alla cieca, ma magari ci sono delle situazioni "note" che possono creare problemi alla eeprom... tipo cali / sbalzi di tensione o roba simile...
Come sempre grazie in anticipo a tutti
Può capitare che il dato venga scritto male, non ricordo di preciso quale ma, in una discussione di non molto tempo fa @gbp01 suggeriva di mettere sempre un calcolo di congruità dei dati alla fine dei dati.
Una cosa tipo
Devo scrivere tre dati, prima di scriverli calcolo il CRC32 di questi e li scrivo nella EEPROM, poi rilegtgo il dato in altre variabili d'appoggio e ne calcolo il CRC32, se entrambe i CRC32 sono identici allora i dati sono stati scritti correttamente e non ti resta che memorizzare anche il CRC in EEPROM, altrimenti ripeti finché non scrivi bene il dato (con un semaforo che magari dopo N scritture esci comunque).
Quando ti serve rileggere la EEPROM calcoli il CRC32 e lo confronti con quello letto dalla EEPROM, se sono uguali i dati sono corretti, altrimenti o sono errati i dati o il CRC memorizzato.
il CRC32 è un esempio così come la logica che ho descritto, magari altri potranno suggerire alternative migliori
Altro suggerimento generico è quello di "sprecare" alcuni byte di EEPROM per metterci dentro dei dati che ti servono per capire se la EEPROM è stata inizializzata bene, ovvero se contiene la tua configurazione.
Es.
Memorizzi nelle prime N celle una serie di caratteri, quando il sistema parte e legge la EEPROM leggi questi N caratteri, se tornano con quel che ti aspetti allora leggi anche gli altri e metti il sistema in condizione di normale operatività.
Se non li trovi lo metti in modalità "attesa parametri di funzionamento" ad esempio.
Il tutto sempre posto sotto un controllo tipo CRC32 per essere sicuri della congruità del dato, se non è congruo, di nuovo, metti il sistema in modalità "attesa parametri di funzionamento"
Grazie per la risposta.
Tenderei ad escludere il primo tipo di problema, perché i dati vengono scritti una volta e letti/usati molte volte.
Il problema si presenta sempre "lontano" dal momento di scrittura.
Cioé:
- li scrivo
- li leggo e uso diverse volte senza problemi (in alcuni casi anche un paio di volte al giorno per qualche mese)
- ad un certo punto riscontro il problema
Per questo pensavo ad una causa esterna "hardware".
Riguardo il "workaround" della verifica con dati noti, all'inizio non ci avevo pensato... ma in effetti potrei aggiungerla.
Altro dato che forse può servire:
i parametri che salvo sono 5, mi pare tutti int (non ho il codice sotto mano, vado a memoria).
Quando riscontro il problema magari ne trovo rovinati uno o 2 su 5. Non è mai successo che fossero tutti rovinati.
Non so dirti, penso che se una cella fosse danneggiata non sarebbero così stabili le letture/scritture.
Non so se una fonte esterna possa indurre un'alterazione selettiva di una cella di memoria ma magari può essere.
Ti tocca aspettare uno bravo ;D
Visto che vuoi aggiungere la verifica con i dati, ti dico anche un'altra cosa che faccio io, memorizzo una roba del tipo:
PTEDM1
PTEDM identifica in qualche modo il progetto in modo che se carico un altro programma la EEPROM so che i dati non sono validi, invece l'uno è la versione dei dati in EEPROM e mi serve in caso di aggiornamenti di programma in cui aggiungo dati salvati.
Metti il tuo caso, salvi 5 dati, tutto ok. Poi aggiungi un sesto dato, ricarichi il programma che parte verifica la stringa iniziale, torna, leggi 6 dati, i primi 5 sono ok perché li avevi salvati prima, il sesto legge chissà cosa c'è nell'indirizzo di memoria, il programma parte e magari succede un casino.
Per gestire il caso invece io nel programma in una define o una costante memorizzo la versione attuale dei dati in EEPROM se quella letta dalla EEPROM è inferiore, so che il sesto dato non è stato memorizzato e quindi, se possibile, ci metto dentro il valore predefinito, aggiorno la versione dei dati in EEPROM e infine eseguo la normale procedura per leggere i dati di configurazione in EEPROM essendo sicuro che tutto quel che leggo è corretto per la normale operatività del programma.
Se non è possibile individuare valori predefiniti allora vado in attesa parametri, quando li ricevo la versione in EEPROM viene aggiornata, i dati scritti e il programma rileggendoli avrà valori consistenti
Certo, un controllo di consistenza lo posso aggiunere. Grazie per le indicazioni.
So anch'io che corrompere una singola cella (o 2 adiacenti) non è che sia facile da fare da parte di un evento esterno, ma come dicevo, i dati corrotti sono sempre massimo un paio su 5 e non sono sempre gli stessi... E' un po' random sia come frequenza (comunque tutto sommato bassa) che come tipo di dato.
La EEPROM ha tempistiche ben precise ... se non le si rispettano i dati vengono corrotti (... è ben descritto nel datasheet).
Detto questo, tu cosa fai? Salvi i dati e spegni o cosa fai? Che sequenza usi?
Guglielmo
La sequenza è tutta "manuale" ovvero effettuata dall'utente (no salvataggi automatici):
- inserisco un codice di 4 cifre che abilita la parte impostazioni
- modifico uno o più dati
- inserisco di nuovo il codice per effettuare la scrittura in eeprom e uscire dalla parte impostazioni
Nella pratica non succede mai che dopo la scrittura il progetto venga spento.
Per leggere e salvare uso Get e Put.
Mmmm ... molto strano ... :
Un'altra cosa che sicuramente provoca corruzione della EEPROM sono le oscillazioni della tensione di alimentazione ... è sufficientemente stabilizzata ? Usi per caso degli interrupt (o cose che usano gli interrupt)?
Guglielmo
Comunque, relativamente all'alimentazione ....
8.4.2 Preventing EEPROM Corruption
During periods of low VCC, the EEPROM data can be corrupted because the supply voltage is too low for the CPU and the EEPROM to operate properly. These issues are the same as for board level systems using EEPROM, and the same design solutions should be applied.
An EEPROM data corruption can be caused by two situations when the voltage is too low. First, a regular write sequence to the EEPROM requires a minimum voltage to operate correctly. Secondly, the CPU itself can execute instructions incorrectly, if the supply voltage is too low.
EEPROM data corruption can easily be avoided by following this design recommendation:
Keep the AVR RESET active (low) during periods of insufficient power supply voltage. This can be done by enabling the internal Brown-out Detector (BOD). If the detection level of the internal BOD does not match the needed detection level, an external low VCC reset Protection circuit can be used. If a reset occurs while a write operation is in progress, the write operation will be completed provided that the power supply voltage is sufficient.
Guglielmo
Purtroppo sull'alimentazione non ho certezze... nel senso che il progetto è inserito in un contesto più ampio.
L'alimentazione che arriva è 20 / 22 Vac (misurazioni fatte con multimetro cinese da 8 euro...).
La raddrizzo con un ponte, soliti condensatori e poi abbasso a 12 Vcc con questo
https://www.digikey.it/product-detail/it/xp-power/JTE0648S12/1470-2077-5-ND/4488456
Una parte del circuito funziona a 12 Vcc, mentre per la parte atmega abbasso ancora a 5 Vcc con un 7805.
Non ho strumenti per verificare l'alimentazione. Io vedo il display acceso, la tastiera risponde e i led di stato si accendono come previsto... quindi do per scontato che tutto sia alimentato.
Non uso interrupt.
Riguardo al paragrafo "8.4.2 Preventing EEPROM Corruption" provo a capire cosa dicono. Grazie per la segnalazione... non sono ferrato con i datasheet...
Riguardo al funzionamento generale, ci tengo a precisare che i parametri di impostazione vengono modificati molto raramente. Allo stato attuale, in pratica vengono modificati solo quando si corrompono.
Dopo la modifica / scrittura viene sempre verificato il corretto funzionamento del tutto, quindi la scrittura è andata sicuramente a buon fine.
Se il discorso corruzione può avvenire anche in lettura allora potrebbe essere che all'avvio quando vengono letti i dati succede qualcosa di strano... comunque in maniera casuale e molto di rado...
No, i dati possono corrompersi solo durante la fase di scrittura ...
... ma a questo punto mi viene il dubbio che non si corrompano affatto, bensì ci sia un bug nel programma per cui, senza che tu lo voglia, in realtà passi, in qualche modo,per la routine che scrive sulla EEPROM e ... chissà a quel punto cosa scrive ... :
Ti aspetta un lungo debug ...
Guglielmo
Sicuramente farò delle altre verifiche (avevo già controllato in diverse occasioni senza riscontrare problemi).
Però la parte di scrittura è vincolata ad una sequenza specifica di operazioni proprio per evitare che l'utente cambi impostazioni senza volerlo e mi sembra stano che il programma arrivi lì quando non dovrebbe...
Verifico.
Grazie a tutti
... metti una qualche indicazione che sei entrato nella routine ... un LED su un pin che rimane acceso o qualche cosa che comunque ti avverte
Guglielmo
Hai ragione, a questo non avevo pensato.
PS: non ti ho mai ringraziato per la dritta sulla stazione saldante... funziona molto bene. Grazie
fratt:
PS: non ti ho mai ringraziato per la dritta sulla stazione saldante... funziona molto bene. Grazie
... sono contento che ti ci sei trovato bene
Guglielmo
This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.