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
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.
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.
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.
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.
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.
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.
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.
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
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.
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
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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.