Wie kann eine Datenbeschädigung durch „teilweises Schreiben“ während eines Stromausfalls verhindert werden?

StackOverflow https://stackoverflow.com//questions/21051614

Frage

In einer eingebetteten Umgebung (mit MSP430) habe ich einige Datenbeschädigungen beobachtet, die durch teilweise Schreibvorgänge in den nichtflüchtigen Speicher verursacht wurden.Dies scheint durch einen Stromausfall während eines Schreibvorgangs verursacht zu werden (entweder in den FRAM oder in die Info-Segmente).

Ich validiere die an diesen Orten gespeicherten Daten mit einem CRC.

Meine Frage ist: Was ist der richtige Weg, um diese Beschädigung durch „teilweises Schreiben“ zu verhindern?Derzeit habe ich meinen Code so geändert, dass er in zwei separate FRAM-Speicherorte schreibt.Wenn also ein Schreibvorgang unterbrochen wird, was zu einem ungültigen CRC führt, sollte der andere Speicherort gültig bleiben.Ist das eine gängige Praxis?Muss ich dieses Doppelschreibverhalten für einen nichtflüchtigen Speicher implementieren?

War es hilfreich?

Lösung

Eine einfache Lösung ist die Wartung zwei Versionen der Daten (auf separaten Seiten für Flash-Speicher), die aktuelle Version und die vorherige Version.Jede Version hat einen Header, der aus einer Sequenznummer und einem Wort besteht, das die Sequenznummer validiert – einfach das 1er-Komplement der Sequenznummer, zum Beispiel:

---------
|  seq  |
---------
| ~seq  |
---------
|       |
| data  |
|       |
---------

Das Entscheidende ist, dass beim Schreiben der Daten die seq Und ~seq Worte werden geschrieben zuletzt.

Auf Start-up Sie lesen die Daten, die das haben höchste gültige Sequenz Zahl (was vielleicht für den Umbruch verantwortlich ist – insbesondere bei Wörtern mit kurzer Folge).Wenn Sie die Daten schreiben, überschreiben und validieren Sie sie älteste Block.

Die Lösung, die Sie bereits verwenden, ist gültig, solange der CRC zuletzt geschrieben wird, aber es mangelt ihr an Einfachheit und sie verursacht einen CRC-Berechnungsaufwand, der möglicherweise nicht notwendig oder wünschenswert ist.

Bei FRAM haben Sie keine Bedenken hinsichtlich der Lebensdauer, aber das ist ein Problem für Flash-Speicher und EEPROM.In diesem Fall verwende ich eine Write-Back-Cache-Methode, bei der die Daten im RAM gespeichert werden und bei Änderung ein Timer gestartet oder neu gestartet wird, wenn er bereits läuft – wenn der Timer abläuft, werden die Daten geschrieben – dies verhindert Burst-Schreibvorgänge verhindert, dass der Speicher überlastet wird, und ist sogar im FRAM nützlich, da es den Software-Overhead beim Schreiben von Daten minimiert.

Andere Tipps

Unser Engineering-Team nimmt ein zweitraktiger Ansatz für dieses Problem: Lösen Sie es in Hardware und Software!

Der erste ist eine Dioden- und Kondensatoranordnung, um während eines Brauntourses ein paar Millisekunden von Macht bereitzustellen. Wenn wir feststellen, dass wir die externe Stromversorgung verloren haben, verhindern wir, dass der Code nicht verlässlich schreibt.

Second, unsere Daten sind besonders kritisch für den Betrieb, es aktualisiert häufig und wir möchten nicht unseren nicht verletzten Flash-Speicher abnutzen (es unterstützt nur so viele Schreibvorgänge.) Somit speichert wir die Daten 16-mal in Flash und schützen Sie jeden Datensatz mit einem CRC-Code. Beim Boot finden wir das neueste gültige Schreib und starten dann unsere Lösch- / Schreibzyklen.

Wir haben seit der Umsetzung unseres ehrlich paranoiden Systems noch nie die Datenruderion gesehen.

update:

Ich sollte beachten, dass unser Flash external an unsere CPU ist, sodass die CRC die Daten validiert, wenn ein Kommunikationsproblem zwischen der CPU und einem Flash-Chip vorliegt. Wenn wir in einer Reihe mehrere Störungen erfahren, schützen die mehreren Schreibungen vor dem Datenverlust.

Wir haben etwas Ähnliches wie Cliffords Antwort genutzt, aber in einem Schreibvorgang geschrieben.Sie benötigen zwei Kopien der Daten und wechseln zwischen ihnen abwechseln.Verwenden Sie eine inkrementierende Sequenznummer, so dass effektiv ein Standort sogar Sequenzummern aufweist, und einer hat ungerade.

Schreiben Sie die Daten so (in einem Schreibbefehl, falls Sie können):

generasacodicetagpre.

Wenn Sie es gelesen haben, stellen Sie sicher, dass beide Sequenznummern gleich sind - wenn sie nicht dann sind, sind die Daten ungültig.Lesen Sie beim Start beide Standorten und trainieren Sie, welche neuerer neuer ist (unter Berücksichtigung der Sequenznummer rollt rollt).

speichern Sie immer Daten in einiger Art von Protokoll, wie start_byte, total Bytes, um zu schreiben, Daten, Endbyte. Bevor Sie an externen / internen Speicher schriftlich sind, überprüfen Sie immer die Macht-Moniter-Register / ADC. Wenn Sie anschließend Ihre Daten beschädigt haben, wird das Endbyte auch beschädigt.Daher wird der Eintrag nach der Validierung des gesamten Protokolls nicht vaild angezeigt. Die Prüfsumme ist keine gute Idee, Sie können CRC16 anstelle davon auswählen, wenn Sie CRC in Ihr Protokoll einschließen möchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top