EEPROM und wie man die Lebensdauer erhöhen kann

Das EEPROM ist einer von drei Speichertypen, die der im Arduino Duemilanove verbaute Atmel ATmega328 mitbringt, in diesem Chip sind 1.024 Bytes davon verbaut.

Anders als das "normale" RAM verliert es seinen Inhalt nicht, wenn am Chip keine Spannung anliegt, es kann aber im Gegensatz zum Flash-Speicher auch vom Chip selbst beschrieben und geändert werden, das macht es zu einem für Konfigurations- und Kalibirierungsdaten äußerst geeigneten Speicher.

Für reines Daten-Logging ist es allerdings eher schlecht geeignet, Grund hierfür ist, dass dieser spezielle Speichertyp pro Speicherzelle nur eine bestimmte Anzahl Schreibvorgänge klaglos hin nimmt, für unsere Chips sind das 100.000. Ist diese Zahl erreicht, wird vom Hersteller nicht mehr gewährleistet, dass die Zelle nach einem Schreibvorgang auch den Wert enthält, den sie enthalten sollte.

Wenn ich also ein einzelnes Datenbyte habe, das ich gerne im EEPROM sicher ablegen will, dann könnte ich dieses Byte 100.000 mal ändern, und wäre immernoch auf der sicheren Seite, aber ab dann würde es unsicher werden...

Alternativ könnte ich das Byte natürlich jedes Mal an eine andere Stelle im Speicher schreiben, dann hätte ich plötzlich 1.024 mal 100.000 Möglichkeiten, den Wert zu ändern, und wäre noch auf der sicheren Seite, also über eine Milliarde.

Klingt gut, funktioniert aber so nicht, da man ja auch irgendwo speichern muss, WO genau im EEPROM das besagte Byte liegt.

Es kann sich glücklich schätzen, wer anderen nichtflüchtigen Speicher in seiner Schaltung hat, z.B. eine auf einem DS1307 basierende Echtzeituhr verwendet, denn die hat 56 Byte zur freien Verfügung, in denen man unter Anderem diese Startadresse hinterlegen könnte. :slight_smile:

Alternativ zum EEPROM gibt es noch so genannte NVRAMs in separaten ICs. Es handelt sich dabei um einen Speicher, der die Vorteile der drei vorhandenen Speichertypen in sich vereinigt: Nichtverlust der Daten beim Spannungswegfall, Beschreibbarkeit vom Microprozessor aus und unbegrenzte Schreibzyklen.

Hätte ich diese zusätzlichen Möglichkeiten nicht, dann würde ich versuchen, ohne eine statische Stelle den Speicher abzuwechseln. Klingt im ersten Moment unmöglich, ist es aber nicht, da wir ja sowohl den komplette Überblick über das gesamte EEPROM wie auch alleinige und vollkommene Rechte darauf haben, und Lesevorgänge sind ja nicht begrenzt.

Man könnte z.B. als ersten Vorgang das gesamte EEPROM mit einem bestimmten Wert beschreiben (z.B. 0x00), wenn man dann einen Wert abgelegt hat, müsste man es nur durchsuchen, und würde das besagte Byte ohne Probleme finden können, da nur es sich vom Rest unterscheidet.
Würde sich der Wert ändern, dann würde ich das ursprüngliche Byte mit 0x00 überschreiben, und den neuen Wert eine Speicherstelle weiter ablegen. Käme man am Ende des Speichers an, würde man einfach am Anfang wieder beginnen, das ergäbe eine gleichmäßige Abnutzung aller Speicherstellen.

Nachteil dieser Methode wäre, dass man für ein Nutzbyte zwei Bytes beschreiben müsste (nämlich das alte Byte überschreiben und den neuen Wert ablegen), was die effektive maximal mögliche Lebensdauer des gesamten Speichers für die genutzte Datenmenge effektiv halbieren würde, man wäre aber auf jeden Fall 512 mal langlebiger als bei der das-Byte-immer-an-die-gleiche-Stelle-Methode. :wink:

Will man mehr als ein Byte speichern, so müsste man bei dieser Methode aber auf jeden Fall ein spezielles Markierungsbyte mit ablegen, denn bei einem einzigen Byte weiss man ja trotzdem, wie sein genauer Wert ist, selbst wenn im ganzen EEPROM nur 0x00 liegen, aber bei mehreren Bytes ist unklar, ob das "fehlende" Byte am Anfang oder am Ende der Struktur liegt.

Sollten die abzuspeichernden Werte es erlauben, ein Markierungsbyte definieren zu können, dessen Wert tatsächlich einzigartig ist (z.B. wenn man sicher nur Daten mit Werten zwischen 0x00 und maximal 0xFE abspeichern wird, dann könnte ein einzigartiges Markierungsbyte vom Wert 0xFF dargestellt werden), dann kann man tatsächlich auf die Löschung alter Daten verzichten, indem man beim nächsten Schreibvorgang einfach leicht überlappend speichert und das alte Markierungsbyte überschreibt, die restlichen Daten aber einfach liegen lässt.

Da man den Start (oder programmatisch besser das Ende) des Nutzdatenblocks anhand des Markierungsbytes bestimmen kann und die genaue Länge des Blocks kennt (da man ihn ja selbst geschrieben hat), ist es dann trotzdem kein Problem, die tatsächlichen Nutzdaten zu extrahieren.

Soweit zu meinen Ideen, kennt jemand eine noch effektivere Methode?

Huiii, so viel hab ich gelesen.

Naja, hier hat noch keiner geschrieben, dass sein EEEPRom inkonsistente Werte hat.

Ich glaub ich würde mir einfach nen neuen ATmega reinbauen, wenn ich das Problem kommen sähe....
Oder nen 30ct I2c-eeprom nehmen. Und das dann 1x im jahr ersetzen :slight_smile:

Ich glaube, so lange du nicht wirklich 100x pro sekunde was draufschreibst, wirst du die haltbarkeit gar nicht merken.

Ich glaube, so lange du nicht wirklich 100x pro sekunde was draufschreibst, wirst du die haltbarkeit gar nicht merken.

Nicht ganz, wenn Du auch nur ein Mal pro Sekunde in die immer gleichen Zellen schreibst, dann sind die 100.000 Schreibzyklen dafür schon nach etwas mehr als einem Tag erreicht... :frowning:

Meine Idee wäre ein
RAMTORN FM24C64-G ist über I2C anzusteuern könnte man dann über die lokale Schnittstelle schreiben.

Hi Joghurt,

EEProms fallen nicht einfach aus. Sie werden vergesslich, d.h. die "retention time" sinkt mit zunehmenden Schreibzyklen. Auch danach funktioniert ein EEProm noch. Nur wird vom Hersteller nicht mehr die "retention time" über den gesamten Temperaturbereich garantiert.

Schau Dir mal
http://www.atmel.com/dyn/Products/app_notes.asp?family_id=607 an und suche nach "AVR101: High Endurance EEPROM Storage". Da wird eine Grundidee für erklärt wie man die Haltbarkeit erhöht.

Offensichtlich kann man die "Reichweite" umso mehr erhöhen je größer das Verhältnis Speicher zu Daten ist. Da ganz offensichtlich auch jede Menge Flash da ist könnte man daher auch auf die Idee kommen nicht nur das EEProm sondern auch den Flash dazu zu verwenden. Fragt sich bloß wie das geht :slight_smile:

Aber auch da hilft Atmel weiter:

Was weiterhin möglich wäre ist gar kein EEProm zu nehmen sondern im Ram zu loggen. Wenn man es richtig anfängt kriegt man die Atmels locker unter 10 uA runter. Da kann man dann relativ lange an einer Batter saugen. Und man kann auch mit einem Pufferelko einen Batteriewechsel überstehen.

Gruß, Udo

Nachtrag: wenn Du ohne externen Speicher loggst, dann kann der Logger nicht allzuviel Speicher vollschreiben weil ja gar nicht viel da ist. Dann stellt sich sofort die Frage was das für ein Logger sein soll der so hochfrequent schreibt, daß er das EEProm schnell kaputt kriegt.

--> Man kann auch erst einmal im Ram loggen und dann einmal pro Stunde oder pro Tag ins EEProm schreiben. Dann sieht es mit der Haltbarkeit auch plötzlich sehr viel besser aus.

Gruß, Udo

Dann stellt sich sofort die Frage was das für ein Logger sein soll der so hochfrequent schreibt, daß er das EEProm schnell kaputt kriegt.

Naja, da würd mir ausm Stegreif ein möglichst genauer Betriebsstundenzähler einfallen...
Aber Du hast Recht, man könnte den Schreibvorgang vielleicht per Interrupt auslösen, wenn die Spannung wegbricht, und das Schreiben über einen Pufferelko sichern, das wär auch ne Idee. :slight_smile:

Danke für die Links!

Mmh, also über deine Ansätze habe ich neulich auch nachgedacht.

Was mir nicht so ganz einleuchtet ist das Markierungsbyte.

Folgende Situation:
Ich habe im gesammten EEPROM einen einheitlichen Wert...
Beispielsweise 0... auf allen Zellen.

Nun schreibe ich einen Wert.

Ich brauche jetzt nur einen neuen Wert zu schreiben,
die zellen auszulesen, und wenn mein ausgelesener Wert 0 ergibt,
ist der letzte geschriebene Wert die Speicherzelle vor dem 0 Wert.

Logisch, weiter hat er ja noch nicht geschrieben.

Interessant wird der Überlauf... nun sind in allen Zellen Werte, und die Identifizierung ist also nicht möglich...

Faktisch müßte ich nun alle Zellen wieder nullen... und den Wert wegschreiben.

An dieser Stelle würde ich quasi das gleiche erreichen wie mit Markierungsbytes... durch das Nullen würde ich wieder auf 2 Schreibvorgänge pro Zelle pro Wert kommen. Nur in diesem Falle halt nacheinander.

Meine Idee wäre... kann aber quatsch sein... :slight_smile: ....

Wenn eine Zelle (nicht das ganze EEPROM) sich 100.000 mal beschreiben läßt, dann wäre es möglich das EEPROM Zelle für Zelle zu zerstören :wink:

Gehen wir mal von 50.000 sicheren Schreibzyklen aus...
Ich würde mir also eine RTC (Realtime-Clock), z.B. DS103 schnappen,
diese mit einer Knopfzelle puffern. (Soll 17 Jahre halten... gehen wir mal von 10 Jahren aus, dann müssen wir ne neue kaufen :wink: )

Naja, jetzt mache ich mir einen Wert aus der Uhrzeit/Datum, welcher
mir die Zelle anzeigt welche zu beschreiben ist.
Wenn wir also z.B. einfach den Tag des Jahres ermitteln, würde er pro Tag eine Zelle benutzen.

Jetzt ist es natürlich wirklich wichtig, wieoft wir am Tag schreiben...
nehmen wir die 100.000 Schreibzyklen(1/Sekunde) dann klappts in der Tat nicht, bzw. gerade so....

Denn am nächsten Tag beschreibt er die nächste Zelle.
Bei z.B. 1024 Zellen, wären das dann 3 Jahre Lebenszeit bei sekündlichem Schreiben.

Wenn Du das jetzt noch mit dem Pufferelko in Betracht ziehst, und nur dann wenn der Saft weg ist schreibst, dürftest Du die nächsten 100 Jahre damit auskommen.

Man bräuchte also eine Routine welche aus der Uhrzeit des Tages einen Wert errechnet welcher zwischen 0 und EEPROMgröße liegt.
Schwups hast Du ohne Markierungsbyte eine geringstmögliche Abnutzung.

Problem ist das der Reboot die aktuelle Stelle nur dann finden kann,
wenn nicht mehr Zeit vergangen ist als der Teiler (Tag>Speicherzelle)
hergibt, sonst liest er die falsche Zelle aus... an dieser Stelle habe ich noch keine Idee..

Weiterhin würde über die Hundert jahre gesehen, nur bei dauerhafter Nutzung alles gleichmäßig beschrieben werden.... jedoch könnte es sein das Du am 11 Februar der Jahr 0-100 deine Schaltung einsetzt, aber ab 24.Dez. der Jahre 0-100 nicht... oder weniger... oder aber jeden Tag um 20:00 Deine Maschine abstellst.

Besser wäre also eine Zellenpositionierung welche z.B. Minute, Stunde, Wochentag, Jahr miteinbezieht... je nachdem wie wahrscheinlich ein Ausfall/Reboot/Poweroff in einem bestimmten Zeitfenster ist....

Nuja, ich denke aber das mit dem Pufferelko "bei Saft weg schreiben, in zusammenhang mit der Zeit/Speicherzellen Routine" du Dir überhauptkeine Sorgen machen mußt.

Lieber Gruß
ChrisS

Also wenn Du eh schon eine RTC verwendest, dann kannst Du auch gleich den Zeiger auf den Speicherblock im EEPROM im freien Speicher der RTC hinterlegen... :wink:

Wie oft läßt sich der EEPROM beschreiben? :wink:

Lieber Gruß
ChrisS

Udo Klein schrieb:
Schau Dir mal http://www.atmel.com/dyn/Products/app_notes.asp?family_id=607 an und suche nach "AVR101: High Endurance EEPROM Storage". Da wird eine Grundidee für erklärt wie man die Haltbarkeit erhöht.

Hmm, die Idee halte ich jetzt nicht für der Weisheit letzter Schluss, zum Einen kannst Du damit immer nur eine ganz bestimmte, im Vorfeld festzulegende Anzahl Bytes im EEPROM speichern, und zum Anderen muss die schon ganzzahlig ins EEPROM passen, wenn man das Maximum aus dem EEPROM quetschen will, wohingegen eine Speicherung ohne separaten Index-Speicherring diese Einschränkung nicht hat; da könnte man sogar im Betrieb (bzw. bei einem Update) die Anzahl der zu speichernden Bytes verändern, und hätte dennoch eine 100%ige Auslastung (und damit über den gesamten möglichen Speicherbereich gleichmäßige Abnutzung) des EEPROMs.
Wenn man das Maximale rausquetschen will, wie gesagt. :wink:

Udo Klein schrieb:
Da ganz offensichtlich auch jede Menge Flash da ist könnte man daher auch auf die Idee kommen nicht nur das EEProm sondern auch den Flash dazu zu verwenden. Fragt sich bloß wie das geht Smiley
Aber auch da hilft Atmel weiter:
www.atmel.com/dyn/resources/prod_documents/doc2546.pdf

Wow, interessanter Ansatz! :slight_smile:
Aber klingt sehr auwändig, ich denke, da wärs um Längen einfacher, einfach noch nen spezialisierten Chip dazuzulöten... :wink:

Ich habe ja auch "Grundidee" geschrieben. In Spezialfällen kann man das auch anders angehen. Weiterhin ist es nicht besonders sinnvoll alles auf 100% auszureizen. Irgendwann ist der Punkt erreicht wo die Optimierungen für die letzten paar % teurer sind als der zu erwartende Nutzen. Beovr ich die letzten 2% rausquetsche nehme ich einen Prozessor eine Nummer größer. (Oder hier: externen Speicher, ich würde eine SD Card nehmen, die kann man dann auch bequem auslesen wenn man es richtig macht).

Gruß, Udo