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 seine letzte Temperatur und Position erinnern. Ich kann diese Werte im EEPROM speichern, aber das Problem ist, dass sich Position und Temperatur sehr schnell ändern können. Wenn ich die Temperatur und Position nach jeder Änderung in das EEPROM schreiben würde, würde dies (1) die Firmware etwas verlangsamen und (2) wahrscheinlich das EEPROM nach ein oder zwei Jahren zerstören. So wie ich das sehe, habe ich folgende Möglichkeiten...
1) Verwenden Sie einen Kondensator / eine Batterie, um das Gerät nach einem 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 irgendwie machthungrig ist und dies eine große Obergrenze 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 Male darauf schreiben kann, ohne es zu verschleißen. Ich mag diese Option nicht, weil FRAM um einiges teurer ist als EEPROM und dies für ein Produktionsprodukt ist (nicht nur für eines).
3) Schreiben Sie die Position und Temperatur nur alle 5 Minuten oder so. Auf diese Weise habe ich immer eine ziemlich aktuelle 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 sonst noch jemand Vorschläge, an die ich nicht denke?
Was Sie brauchen, ist eine Technik namens Wear Leveling . Es schreibt Ihre Daten nicht jedes Mal an die gleiche Stelle im EEPROM, sondern verwendet einen Algorithmus, um verschiedene Stellen zu verwenden. Ich habe über komplexe Wear-Leveling-Algorithmen gelesen, aber ich wüsste nicht, 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 Bytes lang ist. Seiten auf einem 24AA64 sind 32 Bytes lang, ein 64-KB-EEPROM enthält also 256 Seiten. Aus dem Datenblatt:
"Beim Schreiben von weniger als 32 Bytes werden die Daten im Rest der Seite zusammen mit den zu schreibenden Datenbytes aktualisiert. Dadurch wird die gesamte Seite gezwungen, einen Schreibzyklus zu überstehen, aus diesem Grund wird die Dauer pro Seite angegeben."
Daher ist es nicht sinnvoll, Datenblöcke zu verwenden, die kleiner als eine 32-Byte-Seite sind.
Sehen 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, also gehen Sie zur nächsten Seite und überprüfen diesen Zähler. Wiederholen Sie dies, 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 sollten 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 in jeder Seite mit 0xF4240 (für 1 Million) voreinstellen oder alles auf 0xFF löschen und die 0xF4240 schreiben, wenn Sie die Seite zum ersten Mal verwenden.
Das Initialisieren eines EEPROM ist erforderlich, weil manchmal im Produktions-/Testprozess ein bestimmtes Muster darauf geschrieben wird.
Bearbeiten
Das Wear Leveling sollte Ihre Probleme lösen, aber ich möchte noch die Kondensatorlösung kommentieren. Sie sagen, die Platine ist ziemlich stromhungrig, aber vielleicht können Sie die Stromversorgung des Mikrocontrollers / EEPROM mit einer Diode vom Rest der Platine 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
Einfach mit einem kleinen Supercap.
weiterführendes
Datenblatt 24AA64
EEPROM Endurance Tutorial
1) Sobald Sie den Schreibvorgang gestartet haben, müssen Sie nur die MCU/EEPROM mit Strom versorgen und sicherstellen, dass die Steuerleitungen nicht stören - I2C ist dafür wahrscheinlich SPI vorzuziehen. Benötigen Sie nur wenige mA für einige Millisekunden, sollte dies also keine große Obergrenze sein, und Sie könnten die MCU in den Ruhezustand versetzen, sobald der Schreibvorgang eingeleitet wurde. 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 erfolgen kann. Oder warten Sie, bis der Wert für eine Weile stabil ist, bevor Sie schreiben.
Sie können die Ausdauer auch erhöhen, indem Sie die Daten auf mehrere Standorte verteilen. Microchip hat einige Tools und Appnotes, um die Lebensdauer für ihre Eeproms zu berechnen, was nützlich sein kann.
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 Modus-Flags programmiert werden; Es wird nur einen Block geben, in dem das Modus-Flag nicht programmiert ist, aber das des vorherigen Blocks (Umbruch, falls erforderlich). 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 könnte und die Invariante immer noch gelten würde), und programmieren Sie nach Abschluss des Löschvorgangs das Modus-Flag auf das, was früher war der letzte Block sein.
Es ist notwendig, die Versorgung des Flash gut genug zu schützen, um sicherzustellen, dass jeder Versuch, ein Byte zu programmieren, entweder erfolgreich ist oder vollständig fehlschlägt, aber es spielt keine Rolle, ob ein Löschzyklus unterbrochen wird und einen Block voller beliebiger Daten hinterlässt. 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 etwa 2,7-mal füllen. Selbst ein Chip mit einer Lebensdauer von „nur“ 10.000 Löschzyklen würde über 10 Jahre halten. Die Verwendung eines größeren Chips oder eines mit einer Lebensdauer von 100.000 würde die Nutzungsdauer proportional verlängern.
1) Möglicherweise die einfachste Option, obwohl möglicherweise Hardwareänderungen erforderlich sind. Ich habe dies zuvor ohne PBC-Modifikationen erreicht, indem ich einfach die Entkopplungskappen erhöht und den Brown-Out unterbrochen habe.
2) Wie Sie bereits betont haben, ist das Problem bei FRAM der Preis!
3) Abhängig von der Volatilität Ihrer Temperatur- und Positionsdaten erhöhen Sie die Lebensdauer, 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 gelöst.
So habe ich dieses Problem in meinem Projekt gelöst:
Reservieren Sie 1 Flash-Sektor, um eine Bitmaske nicht verwendeter Slots und eine Anzahl von Slots für den Wert zu halten.
Die verwendete Bitmaske war 16 Bytes lang, also hatte ich 128 Slots, um Werte zu setzen.
Die Bitmaske wird auf alle Einsen initialisiert, was in Flash-Begriffen der gelöschte Zustand ist.
Wenn Sie einen neuen Wert schreiben möchten, lesen Sie die Bitmaske ein und finden Sie das erste Bit, das eine Eins ist. Dies ist die Steckplatznummer, in die Sie den Wert schreiben. Ändern Sie dieses Bit in eine Null, um es als verwendet zu markieren, und schreiben Sie die Bitmaske zurück in den Flash, ohne sie vorher zu löschen. Als nächstes schreiben Sie den Wert in den Steckplatz nach der Bitmaske, auch ohne den Flash 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 einer Eins zu einer Null schreiben.
Wenn die gesamte Bitmaske 0 ist, löschen Sie den Flash-Sektor und beginnen Sie neu.
Daniel Grillo
David
Jason S