Häufiges Schreiben in den nichtflüchtigen Speicher

10

Ich entwerfe ein Gerät, das seine physische Position automatisch anpasst, wenn sich die Temperatur ändert. Wenn das Gerät ausgeschaltet oder die Stromversorgung unterbrochen wird, muss sich das Gerät an die letzte Temperatur und Position erinnern. Ich habe die Möglichkeit, diese Werte im EEPROM zu speichern, aber das Problem ist, dass sich Position und Temperatur sehr schnell ändern können. Wenn ich die Temperatur und die Position nach jeder Änderung in das EEPROM schreiben würde, würde dies (1) die Firmware etwas verlangsamen und (2) das EEPROM wahrscheinlich nach ein oder zwei Jahren beenden. So wie ich es sehe, sind meine Optionen wie folgt ...

1) Verwenden Sie einen Kondensator / eine Batterie, um das Gerät nach Stromausfall für kurze Zeit mit Strom zu versorgen, damit ich die Werte nur zu diesem Zeitpunkt in das EEPROM schreiben kann. Ich mag das nicht, weil das Board ein bisschen machtgierig ist und dies eine große Kappe erfordern würde. Und ich habe nicht viel freien Speicherplatz. Und ich möchte nicht die zusätzlichen Kosten für eine Batterie und einen Batteriehalter / oder eine große Kappe.

2) Verwenden Sie F-RAM anstelle von EEPROM, damit ich Billionen Mal darauf schreiben kann, ohne es zu verschleißen. Ich mag diese Option nicht, weil FRAM ziemlich viel teurer als EEPROM ist und dies für ein Produktionsprodukt ist (nicht nur für eines).

3) Schreiben Sie die Position und Temperatur nur etwa alle 5 Minuten auf. Auf diese Weise habe ich immer eine relativ neue Position / Temperatur aufgezeichnet, aber ich schreibe nicht jede Sekunde, damit mein Programm nicht verlangsamt wird und das EEPROM nicht so schnell stirbt. Dies scheint meine beste Option zu sein.

Hat jemand andere Vorschläge, an die ich nicht denke?

PICyourBrain
quelle
5
Nur eine Frage. Wenn das Gerät seine physische Position automatisch anpasst, warum müssen Sie sich an die letzte Temperatur erinnern? Wenn Sie das Gerät wieder einschalten, wird die Temperatur nicht aktualisiert und die Position angepasst.
Daniel Grillo
1
Ich stimme Daniel zu. Was ist, wenn Sie abschalten und sich die Umgebungstemperatur drastisch ändert? Wenn Sie beim Einschalten die zuletzt gespeicherte Temperatur / Position verwendet haben, befinden Sie sich ohnehin an der falschen Stelle, und das Gerät bewegt sich trotzdem. Gibt es eine andere Anforderung, die in Ihrer Frage nicht aufgeführt ist?
Dave
Was ist die EEPROM-Spezifikation - wie viele Schreibzyklen?
Jason S

Antworten:

10

Was Sie brauchen, ist eine Technik namens Verschleißnivellierung . Es schreibt Ihre Daten nicht jedes Mal an derselben Stelle im EEPROM, sondern verwendet einen Algorithmus, um verschiedene Stellen zu verwenden. Ich habe über komplexe Verschleißausgleichsalgorithmen gelesen, aber ich würde nicht wissen, warum die folgende einfache Methode nicht funktionieren würde.

Fügen Sie Ihren Daten einen 24-Bit-Zähler hinzu, sodass Ihr Datenblock beispielsweise 8 Byte lang ist. Seiten auf einem 24AA64 sind 32 Byte lang, sodass ein 64-KB-EEPROM 256 Seiten enthält. Aus dem Datenblatt:

"Bei einem Schreibvorgang von weniger als 32 Byte werden die Daten auf der restlichen Seite zusammen mit den zu schreibenden Datenbytes aktualisiert. Dadurch wird die gesamte Seite gezwungen, einen Schreibzyklus zu durchlaufen. Aus diesem Grund wird die Lebensdauer pro Seite angegeben."

Daher ist es nicht sinnvoll, Datenblöcke zu verwenden, die kleiner als eine 32-Byte-Seite sind.

Schauen Sie sich den Zähler der ersten Seite an. Wenn es Null ist, haben Sie die maximale Anzahl von Schreibzyklen für diese Seite verwendet. Fahren Sie also mit der nächsten Seite fort und überprüfen Sie diesen Zähler. Wiederholen, bis Sie einen Zähler> Null finden. Das ist die Seite, die Sie gerade verwenden. Die EEPROMs von Microchip haben eine Lebensdauer von 1 Million Zyklen, die Sie mit dem angegebenen Beispiel von maximal 32 Bytes pro Block in einem 64-KB-EEPROM auf 256 Millionen erhöhen können. Das sollte ausreichen, um Ihr Produkt zu überdauern: 40 Jahre, wenn Sie alle 5 Sekunden (!) Einmal schreiben.

Sie möchten Ihr EEPROM bei der ersten Verwendung initialisieren. Woher weißt du, wann das ist? Verwenden Sie die letzte Seite, um bei der Initialisierung eine eindeutige Signatur zu schreiben. Überprüfen Sie bei jedem Einschalten, ob die Signatur vorhanden ist. Ist dies nicht der Fall, muss das Gerät initialisiert werden. Sie können den Zähler auf jeder Seite mit 0xF4240 (für 1 Million) voreingestellt oder alles auf 0xFF löschen und den 0xF4240 schreiben, wenn Sie die Seite zum ersten Mal verwenden.
Das Initialisieren eines EEPROM ist erforderlich, da manchmal im Produktions- / Testprozess ein bestimmtes Muster darauf geschrieben wird.

edit
Die Verschleißnivellierung sollte Ihre Probleme lösen, aber ich möchte trotzdem die Kondensatorlösung kommentieren. Sie sagen, die Karte ist ziemlich leistungshungrig, aber vielleicht können Sie die Leistung des Mikrocontrollers / EEPROMs mit einer Diode vom Rest der Karte trennen. Sie benötigen also wahrscheinlich nur wenige mA, wenn die Hauptstromversorgung unterbrochen ist. Der 24AA64 schreibt eine Seite in weniger als 5 ms, dann bei 10 mA und einem zulässigen Spannungsabfall von 100 mV, den Sie benötigen

C=ItΔV=10mA5ms100mV=500μF

Einfach mit einer kleinen Superkappe.

Lesen
Sie weiter das Datenblatt 24AA64
EEPROM Endurance Tutorial

stevenvh
quelle
Die Lebensdauer des EEPROM wird pro Seite angegeben (zumindest für 24AA64 und andere von mir verwendete EEPROMs). Der 24AA64 gibt eine 32-Byte-Seite an, daher sollte die Anzahl pro Seite und nicht pro Block erfolgen.
Saad
@ Saad - Richtig. In meiner Antwort behoben.
Stevenvh
4

1) Sobald Sie den Schreibvorgang gestartet haben, müssen Sie nur noch die MCU / das EEPROM mit Strom versorgen und sicherstellen, dass die Steuerleitungen nicht fehlerhaft sind - I2C ist wahrscheinlich SPI vorzuziehen. Benötigen Sie nur ein paar mA für ein paar Millisekunden, damit dies keine große Kappe ist, und Sie können die MCU in den Ruhezustand versetzen, sobald der Schreibvorgang gestartet wird. 3) Sie können wahrscheinlich etwas Intelligenz anwenden, z. B. einen Holdoff - einmal geschrieben, hält es immer eine bestimmte Zeit, bevor ein weiterer Schreibvorgang stattfinden kann. Oder warten Sie eine Weile, bis der Wert stabil ist, bevor Sie schreiben.
Sie können die Ausdauer auch erhöhen, indem Sie die Daten auf mehrere Standorte verteilen. Microchip verfügt über einige Tools und Appnotes, mit denen die Lebensdauer der Eeproms berechnet werden kann. Dies kann hilfreich sein.

mikeselectricstuff
quelle
4
Hinweis zur Mikrochip-App zur Lebensdauer : ww1.microchip.com/downloads/en/AppNotes/01019A.pdf In der Appnote können Sie die Lebensdauer auch um etwa das Zweifache erhöhen, indem Sie die Betriebsspannung von 5 V auf 3,5 V verringern.
Vandee
1
Wenn Sie Ihre erste Methode verwenden, stellen Sie sicher, dass das Schreiben in den nichtflüchtigen Speicher nach dem Start die höchste Priorität in Ihrem System hat, d. H. Diese Interrupts können nicht dazu führen, dass sich Ihre Werte während des Schreibens ändern oder das Mikro eine andere Verarbeitung startet, wodurch Ihnen die Zeit ausgeht. Es ist äußerst wichtig, dass Sie beim Ausschalten keine beschädigten Werte schreiben. Darüber hinaus können Sie anhand einer CRC für die Werte bestätigen, dass keine Beschädigung aufgetreten ist. Sie müssen jedoch entscheiden, was zu tun ist, wenn dies der Fall ist, z. B. die Verwendung von Standardeinstellungen.
Martin
3

Ich würde vorschlagen, ein blockorientiertes Flash-Gerät zu verwenden und ein Byte von jedem Block als Modus-Flag zu verwenden. Behalten Sie als Invariante bei, dass fast alle Modusflags programmiert werden. Es gibt nur einen Block, in dem das Modus-Flag nicht programmiert ist, aber der vorherige Block (ggf. umbrechen). Dieser Block ist derjenige mit den neuesten Daten. Wenn dieser Block voll ist, löschen Sie den folgenden Block (beachten Sie, dass der zu löschende Block während des Löschzyklus eine beliebige Kombination von Daten enthalten kann und die Invariante weiterhin gültig ist). Wenn das Löschen abgeschlossen ist, programmieren Sie das Modus-Flag auf das, was früher verwendet wurde sei der letzte Block.

Es ist notwendig, die Versorgung des Flashs gut genug zu schützen, um sicherzustellen, dass jeder Versuch, ein Byte zu programmieren, entweder erfolgreich ist oder vollständig fehlschlägt. Es spielt jedoch keine Rolle, ob ein Löschzyklus unterbrochen wird und ein Block voller beliebiger Daten übrig bleibt. da der nächste Versuch, einen Dateneintrag zu schreiben, diesen Block erneut löscht.

Wenn Ihre Daten 16 Bit groß sind, enthält ein 64Kx8-Chip über 32.000 Einträge. Das Schreiben eines Eintrags pro Sekunde würde den Chip ungefähr 2,7-mal füllen. Selbst ein Chip mit einer Lebensdauer von "nur" 10K-Löschzyklen würde über 10 Jahre halten. Die Verwendung eines größeren Chips oder eines Chips mit einer Lebensdauer von 100.000 würde die Lebensdauer proportional verlängern.

Superkatze
quelle
2

1) Möglicherweise die einfachste Option, obwohl möglicherweise Hardwareänderungen erforderlich sind. Ich habe dies zuvor ohne PBC-Modifikationen erreicht, indem ich nur die Entkopplungskappen vergrößert und das Brown-Out unterbrochen habe.

2) Wie Sie bereits betont haben, ist das Problem mit FRAM der Preis!

3) Abhängig von der Flüchtigkeit Ihrer Temperatur- und Positionsdaten erhöhen Sie die Ausdauer, indem Sie nur schreiben, wenn sich der Wert geändert hat. Möglicherweise messen Sie die Temperatur einmal pro Sekunde, aber wenn sie sich nur alle 5 Minuten ändert, ist das Problem behoben.

Tim
quelle
1

So habe ich dieses Problem in meinem Projekt gelöst:

Reservieren Sie 1 Flash-Sektor, um eine Bitmaske nicht verwendeter Steckplätze und eine Anzahl von Steckplätzen für den Wert aufzunehmen.

Die Bitmaske, die ich verwendet habe, war 16 Byte lang, also hatte ich 128 Steckplätze, um Werte zu setzen.

Die Bitmaske wird für alle initialisiert, was in Flash-Begriffen der gelöschte Zustand ist.

Wenn Sie einen neuen Wert schreiben möchten, lesen Sie die Bitmaske ein und suchen Sie das erste Bit, das eins ist. Dies ist die Steckplatznummer, in die Sie den Wert schreiben. Ändern Sie dieses Bit auf Null, um es als verwendet zu markieren, und schreiben Sie die Bitmaske zurück, um zu blinken, ohne sie zuvor zu löschen. Schreiben Sie als nächstes den Wert in den Steckplatz nach der Bitmaske, ohne den Blitz zu löschen.

Auf diese Weise verlängern Sie die Flash-Schreibzyklen um das 128-fache, indem Sie die neue Bitmaske nur mit einer Änderung von eins auf null schreiben.

Wenn die gesamte Bitmaske 0 ist, löschen Sie den Flash-Sektor und starten Sie neu.

Robert
quelle
3
Ich könnte Sie enttäuschen, aber wenn Sie ein bisschen blinken, wird der gesamte Sektor überschrieben. Ihre Lösung wird den Bitmaskensektor sehr bald zum Erliegen bringen.
Andrejs Cainikovs
1
Wenn Sie den Flash nicht löschen, verbrauchen Sie keinen der 10K-Löschzyklen für den Sektor. Wenn Sie den Wert 0x7F haben und den Wert 0x3F schreiben, ist das Ergebnis 0x3F. Dadurch wird die Bitmaske auf dem neuesten Stand gehalten, der Blitz wird jedoch nicht gelöscht. Das Löschen erfolgt erst, wenn die gesamte Bitmaske 0 ist.
Robert
Wenn ich falsch liege, lass uns diskutieren. Ich möchte hier keine schlechten Antworten und ich möchte wirklich kein schlechtes Design in meinem Projekt.
Robert
Ich denke Robert hat recht. Auf meinem Mikrocontroller können Sie immer nur 4 Bytes gleichzeitig schreiben, aber die erforderlichen Bits werden auf Null gesetzt. Die einzige Möglichkeit, sie wieder auf 1 zu bringen, besteht darin, den 1k-Block zu leeren. Es sind nur die Löschzyklen, die den Blitz tragen ...
Tim
Es kann für jeden Speichertyp und möglicherweise sogar für den Speicherhersteller unterschiedlich sein. Ich habe gesehen, dass EEPROMs die Seite löschen und sie dann für jeden Schreibvorgang neu schreiben müssen. Ich habe Flash-Speicher gesehen, Sie können Bits schreiben, die noch 1 sind, ohne die Seite zu löschen.
mjh2007