Comment éviter les “écriture partielle” de la corruption de données lors de la perte de puissance?

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

Question

Dans un environnement embarqué (à l'aide de MSP430), j'ai vu certains de corruption de données causée par un partiel écrit à la mémoire non volatile.Cela semble être causé par la perte de puissance pendant une écriture (soit FRAM ou info segments).

Je suis la validation des données stockées dans ces endroits avec un CRC.

Ma question est, est-ce la bonne façon de prévenir cette "écriture partielle" de la corruption?Actuellement, j'ai modifié mon code pour écrire à deux FRAM endroits.Donc, si une écriture est interrompue provoquant une défaillance de la CRC, autre lieu doit rester valable.Est-ce une pratique courante?Ai-je besoin pour mettre en œuvre cette double écriture comportement pour toute la mémoire non volatile?

Était-ce utile?

La solution

Une solution simple consiste à maintenir deux les versions des données (dans des pages distinctes pour la mémoire flash), la version actuelle et la version précédente.Chaque version possède un en-tête comprenant un numéro de séquence et un mot valide le numéro de séquence - tout simplement le 1er complément du numéro de séquence par exemple:

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

La chose la plus critique est que lorsque les données sont écrites les seq et ~seq les mots sont écrits dernière.

Sur les start-up vous lire les données qui ont le plus de séquence valide nombre (accounting for wrap-around peut-être - en particulier pour les courtes séquences de mots).Lorsque vous écrivez des données, d'écraser et de valider le la plus ancienne le bloc.

La solution que vous utilisez déjà est valide tant que le CRC est écrit en dernier, mais il manque de simplicité et impose un calcul de CRC surcharge qui peut ne pas être nécessaire ou souhaitable.

Sur FRAM vous n'avez aucune inquiétude à propos de l'endurance, mais c'est une question de mémoire Flash et EEPROM.Dans ce cas, j'utilise un cache à écriture différée méthode, où les données sont conservées dans la mémoire RAM, et lorsqu'ils sont modifiés d'un timer est démarré ou redémarré si il est déjà en cours d'exécution - lorsque le délai expire, les données sont écrites - ce qui empêche l'éclatement écrit de rosser la mémoire, et est utile, même sur FRAM, car il minimise le logiciel généraux de l'écriture de données.

Autres conseils

Notre équipe d'ingénierie prend une approche à deux volets de ce problème: résolvez-la dans du matériel et des logiciels!

Le premier est une diode et un agencement de condensateur pour fournir quelques millisecondes de puissance pendant un brun-out. Si nous remarquons que nous avons perdu la puissance externe, nous empêchons le code d'entrer dans toutes les écrivies non violentes.

Deuxièmement, nos données sont particulièrement critiques pour le fonctionnement, il se met à jour souvent et nous ne voulons pas porter notre stockage flash non violé (il ne prend en charge que de nombreuses écritures.) Nous stockons donc réellement les données 16 fois en flash et protéger chaque enregistrement avec un code CRC. Au démarrage, nous trouvons la dernière écriture valide et commençons ensuite nos cycles effaçons / écrits.

Nous n'avons jamais vu de corruption de données depuis la mise en œuvre de notre système franchement paranoïaque.

mise à jour:

Je dois noter que notre flash est externe à notre CPU. Le CRC aide donc à valider les données s'il existe un problème de communication entre la CPU et la puce Flash. De plus, si nous rencontrons plusieurs problèmes d'affilée, les multiples écrites protègent contre la perte de données.

Nous avons utilisé quelque chose de similaire à la réponse de Clifford, mais écrit en une seule opération d'écriture.Vous avez besoin de deux copies des données et d'alterner entre eux.Utilisez un numéro de séquence d'incrémentation de manière à ce que l'on puisse fonctionner efficacement un nombre de séquences même et que l'on a étrange.

Écrivez les données telles que celles-ci (dans une commande d'écriture si vous le pouvez):

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

Lorsque vous le lisez en arrière, assurez-vous que les deux numéros de séquence sont identiques - s'ils ne sont pas alors invalides.Au démarrage, lisez les deux endroits et travaillez lequel est plus récent (en tenant compte du numéro de numéro de séquence).

stocke toujours des données dans une sorte de protocole, comme Start_Byte, Total des octets d'écriture, de données, d'octets de fin. Avant d'écrire à la mémoire externe / interne, vérifiez toujours les registres de moniteur d'alimentation / ADC. Si de toute façon que vos données corrompent, l'octet de fin sera également corrompu.Donc, cette entrée ne vaillait pas après la validation d'un protocole entier. CheckSum n'est pas une bonne idée, vous pouvez choisir CRC16 au lieu de cela si vous souhaitez inclure CRC dans votre protocole.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top