Forum: Mikrocontroller und Digitale Elektronik Spannungsausfall beim schreiben von EEPROM-Daten


von Third E. (third-eye)


Lesenswert?

Hallo,

folgendes Szenario, das mir schon einmal so passiert ist:
Ein µC (in meinem Fall AVR) speichert kurz vor dem Ausschalten eine 
durch den Benutzer eingestellte u32-Variable als 4  Bytes im EEPROM. Der 
µC wird dabei aus einem Elko versorgt. Doch bevor er fertig ist mit 
Schreiben, gibt es einen Brown-Out, weil durch einen Defekt in der 
Schaltung der Elko zu schnell leer wurde.
3 Bytes sind erfolgreich geschrieben, das 4. Byte ist aber im Zustand 
des letzten Schreibvorgangs. In meinem Fall war das der Lautstärkewert 
für zwei Kanäle eines digitalen Lautstärkepotis in einem kräftigen 
Audioverstärker.
Beim nächsten Einschalten liest der AVR das u32 und stellt nun einen 
Kanal ein, wie gewollt, der andere Kanal wird aber auf ohrenbetäubende 
Lautärke gestellt, da der Wert zufälligerweise im erlaubten Bereich ist.

Mit welcher einfachen Maßnahme kann man dieses Problem lösen?
Eine Prüfsumme wäre wohl die sicherste Variante, ist aber auch etwas 
Rechenaufwand und damit Speicherverbrauch. Zumindest, wenn man eine 
"gute" Prüfsumme haben will.

Mir schwebt folgender einfacher Algorithmus vor:
Es wird ein 5. Byte verwendet. Schreibreihenfolge:
Byte 5 auf 0xAA setzen
Byte 1 bis 4 schreiben
Byte 5 auf 0xBB setzen

Nach dem nächsten Einschalten werden die Nutzdaten nur als plausibel 
betrachtet, wenn Byte 5 = 0xBB.
Ansonsten wird ein Default-Wert verwendet.

Hat jemand noch weitere Ideen?

Gruß
Third-Eye

von NichtWichtig (Gast)


Lesenswert?

Ich betreibe einen ATTiny und speichere beim Abschalten einen C Struktur 
ins EEPROM (ca. 20 Bytes)

Um das sauber und sicher zu lösen werte ich die Betriebsspannung per ADC 
aus und schreibe früh genug bei Unterspannung und aktiviere erst bei 
höhere Spannung.

Der ADC mist die Spannung (in meinem Fall KFZ Betriebsspannung) VOR dem 
Spannungsregler und hat als Puffer einen GoldCap.

Also bei ca. 8V geht der µC in den Standby Modus wo die Schaltung nix 
mehr macht, bei >9V wird sie wieder aktiv.

Die Struktur wird mit einem CRC abgesichert und im Falle eines Fehlers 
würden beim Lesen default-Werte verwendet.

Funktioniert an 2 Mopeds als Kettenoiler seit Jahren hervorragend.
Da einige laufende Daten gespeichert werden läßt sich durch Vergleich 
mit dem Tachostand recht gut prüfen ob die Daten stimmen, was sie tuen.

von Chris K. (Gast)


Lesenswert?

Die Alternative ist dreifache Ablage und dann 2 aus 3 Entscheidung was 
richtig ist. Oder aber den Fehler in der Schaltung beheben, so dass die 
Ladung im Kondensator ausreicht.

von Axel S. (a-za-z0-9)


Lesenswert?

Third E. schrieb:
> Hat jemand noch weitere Ideen?

Klar.

1. einen größeren Stützkondensator verwenden und die Betriebsspannung 
vor dem Stützkondensator messen. Bspw. die Rohspannung vor dem 
Spannungsregler. Und nur zu schreiben anfangen, wenn die Spannung hoch 
genug ist. Der Stützkondensator muß dann genug Energie enthalten, um den 
Schreibvorgang trotzdem abschließen zu können.

2. einen schneller beschreibbaren nichtflüchtigen Speicher verwenden, 
z.B. FRAM.

3. einen schnell beschreibbaren flüchtigen Speicher verwenden und den 
mit Batterie/Goldcap/$WHATEVER puffern. Viele RTC-Chips bieten ein paar 
Bytes RAM, die mitgepuffert werden.

Eine Prüfsumme oder wenigstens ein Prüfbyte ist unabhängig davon 
trotzdem eine gute Idee.

von Wolfgang (Gast)


Lesenswert?

Third E. schrieb:
> Doch bevor er fertig ist mit Schreiben, gibt es einen Brown-Out, weil
> durch einen Defekt in der Schaltung der Elko zu schnell leer wurde.

Verwende für den µC einen eigenen Elko vor dem Spannungsregler, der von 
der restlichen Schaltung entkoppelt ist.

> Hat jemand noch weitere Ideen?

Defekt reparieren und Prüfsumme verwenden.

Die Prüfsumme muss kein Superhochsicherheitsding sein. Sie soll 
lediglich mit ausreichender Sicherheit verhindern, dass ein 
unvollständiger Wert mit vertretbarem Restrisiko nicht akzeptiert wird.

> Beim nächsten Einschalten liest der AVR das u32 und stellt nun einen
> Kanal ein, wie gewollt, der andere Kanal wird aber auf ohrenbetäubende
> Lautärke gestellt, da der Wert zufälligerweise im erlaubten Bereich ist.

Ändere den erlaubten Bereich auf vernünftige Werte.

von c-hater (Gast)


Lesenswert?

Third E. schrieb:

> Mit welcher einfachen Maßnahme kann man dieses Problem lösen?
> Eine Prüfsumme wäre wohl die sicherste Variante, ist aber auch etwas
> Rechenaufwand und damit Speicherverbrauch.

"Rechenzeitaufwand und damit Speicherverbrauch" ist Schwachsinn. Nö, es 
ist in der Realität so, dass du entweder Rechenzeit- oder 
Speicherverbrauch hast.

Darüber hinaus sind einfache CRC-Prüfsummen über wenige Bytes ein Witz 
bezüglich der Leistungsfähigkeit neuzeitlicher µC. Das sind bei 
Performance-Optimierung (also: wenig Rechenzeit + relativ viel Speicher 
für Tabellen) nur ein paar hundert Nanosekunden.

> Hat jemand noch weitere Ideen?

Mach' es wie die Erwachsenen: Nutze eine CRC-Prüfsumme und sorge dafür, 
dass die Scheisse genug Zeit hat, bei einem Brown-Out immer zu einem 
glücklichen Ende zu kommen. In aller Regel bedarf es dazu nur eines 
etwas größeren Elkos in der Versorgung.

von (prx) A. K. (prx)


Lesenswert?

Chris K. schrieb:
> Die Alternative ist dreifache Ablage und dann 2 aus 3 Entscheidung was
> richtig ist.

Reihenfolge:
- 1. Eintrag wird korrekt geschrieben.
- 2. Eintrag geht in die Fritten.
- 3. Eintrag hat vorigen Stand.
Jetzt hast du 3 verschiedene Einträge. Welcher ist richtig?

Ok, da das nur bei diesem Szenario auftritt, wirds der erste sein. Aber 
sowiel zu einer 2 aus 3 Entscheidung. ;-)

Ich habe eine 8-Bit CRC zu jedem Config-Eintrag hinzugefügt. Wenn 
falsch, dann Standardwert. Die Parameter werden einzeln geschrieben, es 
kann also nur einen betreffen.

von Peter D. (peda)


Lesenswert?

Third E. schrieb:
> Eine Prüfsumme wäre wohl die sicherste Variante, ist aber auch etwas
> Rechenaufwand und damit Speicherverbrauch.

Nö.
Such Dir einfach eine aus der "crc16.h" aus.

von georg (Gast)


Lesenswert?

Third E. schrieb:
> Zumindest, wenn man eine
> "gute" Prüfsumme haben will.

Nicht übertreiben, z.B. die 16bit-Summe der 4 Bytes reicht völlig, und 
der Rechenaufwand ist unerheblich. Dass da ein gültiger Datensatz durch 
Zufall entsteht ist genügend unwahrscheinlich.

Eine nicht ganz schlechte Idee wäre es, auch die vorherige Version zu 
speichern und im Notfall erst mal auf die zurückzugreifen. 6 Bytes 
werden sich ja noch unterbringen lassen.

Georg

von Karl (Gast)


Lesenswert?

Die 4 Bytes miteinander und noch mit $AA ver-xor-en. Das $AA schließt 
aus, dass fünfmal $FF oder fünfmal $00 als gültig erkannt werden. Die 
Wahrscheinlichkeit für eine falsche Erkennung ist 1/256. Mit einem 
einzigen Prüfbyte wird die Wahrscheinlichkeit auch nicht besser, egal 
wie es berechnet wird.

von spess53 (Gast)


Lesenswert?

Hi

>Doch bevor er fertig ist mit
>Schreiben, gibt es einen Brown-Out, weil durch einen Defekt in der
>Schaltung der Elko zu schnell leer wurde.

Dann behebe einfach den Defekt. Ich habe das schon vor >10 Jahren 
praktiziert. Rohspannung über Analogkomparator "messen" und bei 
Spannungsabfall im Interrupt speichern. Funktioniert auch ohne dieses 
CRC-Gedöhns wunderbar.

MfG spess

von Planlos (Gast)


Lesenswert?

Hast du noch viel ungenutztes EEPROM?

Pack deine Werte in eine Art Ringbuffer:

Beim Start Werte ee[i%N],  i=1..N lesen, der Wert bei dem der 
Nachfolge-Wert ungültig ist, ist der Eintrag zum verwenden.

Beim schreiben zuerst ee[(i+1)%N] Löschen (0xFFFFFFF...), dann ee[i] 
schreiben.

"i" selber musst du nicht im EEProm speichern.

Damit verteilst du deine Schreibzugriffe auf mehr Speicherzellen, und 
kannst einfach nach jeder Bedienung des Lautstärkereglers den 
aktuellen Wert schreiben, ohne dass dein AVR in den nächsten 100 Jahren 
schlapp machst.
Zusatz-Kondensatorschaltungen, Brownout-Früherkennung etc. werden damit 
überflüssig.

Noch besser wäre es, wenn der AVR den Lösch- und Schreibvorgang des 
EEproms Trennen könnte:

Löschen (alles auf 0xFF) mit viel Zeit- und Strombedarf vorab,
Schreiben (einzelne Bits 1->0) schnell und sparsam.

Gibt aber die AVR-Hardware m.W. nicht her.

von 6a66 (Gast)


Lesenswert?

A. K. schrieb:
> Reihenfolge:
> - 1. Eintrag wird korrekt geschrieben.
> - 2. Eintrag geht in die Fritten.
> - 3. Eintrag hat vorigen Stand.
> Jetzt hast du 3 verschiedene Einträge. Welcher ist richtig?
>
> Ok, da das nur bei diesem Szenario auftritt, wirds der erste sein. Aber
> sowiel zu einer 2 aus 3 Entscheidung. ;-)

Nach meinem Dafürhaltaen klappt 2oo3 nicht (siehe auch Zitat) sondern 
nur 2oo4. Begründung:
Beim Schreibversuch auf die Nr.2 geht der Wert verloren, ein Zufallswert 
ensteht. Nr. 1 ist neu, Nr. 3 ist alt.
Bei 2oo4 würde ich dann auf zwei Neue Werte prüfen. Sind mindestens 2 
Neue da gelten die, sind weniger als 2 Neue da gelten die Alten. Im Fall 
von Ungleichheit werden die Minoritäten auf die Majorität berichtigt, 
alternativ im Falle der Gleichheit Alte auf Neu berichtigen, noch bevor 
das System überhaupt aktiv wird.

rgds

von B. J. (bjue)


Lesenswert?

Die 4 Bytes mit einer Checksumme versehen (am besten CRC) und zwei mal 
abspeichern. Ich nenne sie mal Struktur 1 und 2.

Wert wird vom Benutzer geändert:
CRC über Struktur 1 bilden und schreiben (EEPROM).

In gewissen Abständen (kommt auf die Anwendung an) diese geänderte 
Struktur 1 kopieren und ein zweites mal in Struktur 2 schreiben 
(EEPROM). Man hat also eine Schattenkopie.

Geht beim Schreiben von Struktur 1 etwas schief, hat man immer noch die 
Vorgängerversion Struktur 2. Geht beim Schreiben von Struktur 2 etwas 
schief hat man noch die Struktur 1 (quasi das Original).

Lesen:
Checksumme von Struktur 1 stimmt? Wenn ja --> benutzen.
Wenn nein: Checksumme von Struktur 2 stimmt? Wenn ja --> benutzen.
Wenn nein: Default Werte benutzen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.