Écriture fréquente dans la mémoire non volatile


10

Je conçois un appareil qui ajuste automatiquement sa position physique lorsque la température change. Si l'appareil s'éteint ou que l'alimentation est coupée, l'appareil doit se souvenir de sa dernière température et position. J'ai la possibilité de stocker ces valeurs dans l'EEPROM mais le problème est que la position et la température pourraient changer très rapidement. Si je devais écrire la température et la pos sur l'EEPROM après chaque changement, cela (1) ralentirait un peu le firmware et (2) tuerait probablement l'EEPROM après un an ou deux. Donc, comme je le vois, mes options sont les suivantes ...

1) utilisez un condensateur / une batterie pour maintenir l'appareil sous tension pendant une courte période après la panne de courant afin que je puisse écrire les valeurs dans l'EEPROM à ce moment-là uniquement. Je n'aime pas ça parce que la planche est un peu gourmande en énergie et cela nécessiterait un gros cap Et je n'ai pas une tonne d'espace libre. Et je ne veux pas le coût supplémentaire d'une batterie et d'un support de batterie / ou d'un grand capuchon.

2) utiliser la F-RAM au lieu de l'EEPROM afin que je puisse y écrire des milliards de fois sans l'user. Je n'aime pas cette option car FRAM est un peu plus cher que l'EEPROM et c'est pour un produit de production (pas un seul).

3) N'écrivez la position et la température que toutes les 5 minutes environ. De cette façon, j'ai toujours une position / temp assez récente enregistrée mais je n'écris pas toutes les secondes donc mon programme n'est pas ralenti et l'EEPROM ne mourra pas aussi vite. Cela semble être ma meilleure option.

Quelqu'un d'autre a-t-il des suggestions auxquelles je ne pense pas?


5
Juste une question. Si l'appareil ajuste automatiquement sa position physique, pourquoi devez-vous vous souvenir de la dernière température? Lorsque vous rallumez l'appareil, il ne mettra pas à jour la température et ajustera sa position?
Daniel Grillo

1
Je suis d'accord avec Daniel. Et si vous éteignez et que la température ambiante change radicalement? À la mise sous tension, si vous utilisiez la dernière température / position enregistrée, vous seriez de toute façon au mauvais endroit et l'appareil finirait par bouger malgré tout. Y a-t-il une autre exigence qui ne figure pas dans votre question?
Dave

Quelle est la spécification EEPROM - combien de cycles d'écriture?
Jason S

Réponses:


10

Vous avez besoin d'une technique appelée nivellement de l'usure . Il n'écrit pas vos données à chaque fois au même emplacement dans l'EEPROM, mais utilise un algorithme pour utiliser différents emplacements. J'ai lu des algorithmes de nivellement d'usure complexes, mais je ne sais pas pourquoi la méthode simple suivante ne fonctionnerait pas.

Ajoutez à vos données un compteur 24 bits, pour que votre bloc de données soit par exemple de 8 octets de long. Les pages d'un 24AA64 ont une longueur de 32 octets, donc une EEPROM de 64 Ko contient 256 pages. De la fiche technique:

"Lorsque vous effectuez une écriture de moins de 32 octets, les données du reste de la page sont actualisées avec les octets de données en cours d'écriture. Cela forcera la page entière à subir un cycle d'écriture, pour cette raison, l'endurance est spécifiée par page."

il n'est donc pas logique d'utiliser des blocs de données plus petits qu'une page de 32 octets.

Regardez le compteur de la première page. Si c'est zéro, vous avez utilisé le nombre maximum de cycles d'écriture pour cette page, vous passez donc à la page suivante et vérifiez ce compteur. Répétez jusqu'à ce que vous trouviez un compteur> zéro. C'est la page que vous utilisez actuellement. Les EEPROM de Microchip ont une endurance de 1 million de cycles, que vous pouvez augmenter à 256 millions avec l'exemple donné de 32 octets maximum par bloc dans une EEPROM de 64 Ko. Cela devrait suffire à survivre à votre produit: 40 ans si vous écrivez une fois toutes les 5 secondes (!).

Vous voudrez initialiser votre EEPROM lors de la première utilisation. Comment savez-vous quand c'est. Utilisez la dernière page pour écrire une signature unique lors de l'initialisation. Vérifiez à chaque mise sous tension si la signature est là. Si ce n'est pas le cas, l'appareil doit être initialisé. Vous pouvez prérégler le compteur dans chaque page avec 0xF4240 (pour 1 million) ou tout effacer sur 0xFF et écrire le 0xF4240 lorsque vous utilisez la page pour la première fois.
L'initialisation d'une EEPROM est nécessaire car parfois un certain modèle lui est écrit dans le processus de production / test.

modifier
Le nivellement par usure devrait résoudre vos problèmes, mais je veux quand même commenter la solution du condensateur. Vous dites que la carte est plutôt gourmande en énergie, mais vous pouvez peut-être isoler l'alimentation du microcontrôleur / EEPROM du reste de la carte avec une diode. Vous n'aurez donc probablement besoin que de quelques mA lorsque l'alimentation principale est coupée. Le 24AA64 écrit une page en moins de 5 ms, puis à 10 mA et à une chute de tension admissible de 100 mV dont vous aurez besoin

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

Facile avec un petit supercap.

lire la suite
fiche technique 24AA64
EEPROM Endurance Tutorial


L'endurance de l'EEPROM est donnée par page (au moins pour le 24AA64 et les autres EEPROM que j'ai utilisées). Le 24AA64 spécifie une page de 32 octets, donc le nombre doit être par page et non par bloc.
Saad

@Saad - Correct. Corrigé dans ma réponse.
stevenvh

4

1) Une fois que vous avez commencé le processus d'écriture, il vous suffit d'alimenter le MCU / EEPROM et de vous assurer que les lignes de contrôle ne pépinent pas - I2C est probablement préférable à SPI pour cela. Vous n'avez besoin que de quelques mA pendant quelques millisecondes, donc cela ne devrait pas être un gros plafond, et vous pouvez mettre le MCU en veille une fois l'écriture lancée. 3) vous pouvez probablement appliquer une certaine intelligence, par exemple un holdoff - une fois écrit, il tient toujours un certain temps avant qu'une autre écriture puisse se produire. Ou attendez que la valeur soit stable pendant un certain temps avant d'écrire.
Vous pouvez également augmenter l'endurance en répartissant les données sur plusieurs emplacements. Microchip a quelques outils et annexes pour calculer l'endurance de ses eeproms, qui peuvent être utiles.


4
Note de l'application Microchip sur l'endurance: ww1.microchip.com/downloads/en/AppNotes/01019A.pdf Dans l'Appnote, vous pouvez également augmenter l'endurance d'environ 2x en diminuant la tension de fonctionnement de 5v à 3,5v.
vandee

1
Si vous utilisez votre première méthode, assurez-vous que l'écriture dans la mémoire non volatile est la priorité la plus élevée dans votre système une fois qu'il démarre, c'est-à-dire. ces interruptions ne peuvent pas faire changer vos valeurs à mi-écriture ou le micro pour démarrer un autre traitement qui vous fait manquer de temps. Il est très important de ne pas écrire de valeurs corrompues lors de la mise hors tension. De plus, un CRC sur les valeurs vous aiderait à confirmer qu'aucune corruption ne s'est produite, mais vous devrez décider quoi faire si c'est le cas, par exemple en utilisant les valeurs par défaut.
Martin

3

Je suggère d'utiliser un périphérique flash orienté bloc et d'utiliser un octet de chaque bloc comme indicateur de mode. Maintenez comme invariant que presque tous les drapeaux de mode seront programmés; il n'y aura qu'un seul bloc où l'indicateur de mode n'est pas programmé mais le bloc précédent (habillage si nécessaire) l'est. Ce bloc sera celui avec les données les plus récentes. Lorsque ce bloc se remplit, effacez le bloc suivant (notez que le bloc en cours d'effacement pourrait contenir n'importe quelle combinaison de données pendant le cycle d'effacement, et l'invariant continuerait de tenir), puis une fois l'effacement effectué, programmez l'indicateur de mode sur ce qui était utilisé pour être le dernier bloc.

Il sera nécessaire de protéger suffisamment l'alimentation du flash pour garantir que toute tentative de programmation d'un octet réussira ou échouera dans son intégralité, mais peu importe si un cycle d'effacement est interrompu, laissant un bloc plein de données arbitraires, car la prochaine tentative d'écriture d'une entrée de données effacera ce bloc.

Si vos données sont de 16 bits, une puce 64Kx8 contiendra plus de 32 000 entrées. Écrire une entrée par seconde remplirait la puce environ 2,7 fois. Même une puce avec une endurance de "seulement" 10 000 cycles d'effacement durerait plus de 10 ans. L'utilisation d'une puce plus grosse ou d'une puce avec une endurance de 100K augmenterait proportionnellement la durée de vie utile.


2

1) Peut-être l'option la plus simple, bien qu'elle puisse nécessiter des modifications matérielles. J'ai réalisé cela avant sans modifications PBC en augmentant simplement les bouchons de découplage et en interrompant le brunissement.

2) Comme vous l'avez souligné, le problème avec FRAM est le prix!

3) En fonction de la volatilité de vos données de température et de position, vous augmenterez l'endurance en n'écrivant que si la valeur a changé. Vous pouvez échantillonner la température une fois par seconde, mais si elle ne change que toutes les 5 minutes, le problème est résolu.


1

Voici comment j'ai résolu ce problème dans mon projet:

Réservez 1 secteur de flash pour contenir un masque de bits d'emplacements inutilisés et un certain nombre d'emplacements pour la valeur.

Le bitmask que j'ai utilisé faisait 16 octets de long, donc j'avais 128 emplacements pour mettre des valeurs.

Le bitmask est initialisé à tous ceux qui, en termes flash, est l'état effacé.

Lorsque vous souhaitez écrire une nouvelle valeur, lisez le masque de bits et recherchez le premier bit qui est un. Il s'agit du numéro d'emplacement où vous écrirez la valeur. Remplacez ce bit par un zéro pour le marquer comme utilisé et réécrivez le masque de bits sur flash sans l'effacer au préalable. Ensuite, écrivez la valeur dans l'emplacement après le masque de bits également sans effacer le flash.

De cette façon, vous prolongez les cycles d'écriture flash de 128 fois en écrivant le nouveau masque de bits avec seulement un changement de un à zéro.

Si le masque binaire entier est à 0, effacez le secteur flash et recommencez.


3
Je pourrais vous décevoir, mais lorsque vous flashez un peu, tout le secteur est écrasé. Votre solution rendra le secteur du «bitmask» mort très bientôt.
Andrejs Cainikovs

1
Si vous n'effacez pas le flash, vous n'utilisez pas l'un des cycles d'effacement 10K pour le secteur. Si vous avez la valeur 0x7F et que vous écrivez la valeur 0x3F, le résultat sera 0x3F. Cela maintient le masque de bits à jour, mais n'efface pas le flash. L'effacement ne se produit qu'une fois que le bitmask entier est à 0.
Robert

Si je me trompe, discutons. Je ne veux pas de mauvaises réponses ici et je ne veux vraiment pas de mauvaise conception dans mon projet.
Robert

Je pense que Robert a raison. Sur mon microcontrôleur, vous ne pouvez écrire que 4 octets à la fois, mais les bits requis sont mis à zéro. La seule façon de les ramener à 1 est de vider le bloc 1k. Ce ne sont que les cycles d'effacement qui portent le flash ...
Tim

Il peut être différent pour chaque type de mémoire et peut-être même pour le fournisseur de mémoire. J'ai vu que les EEPROM doivent effacer la page puis la réécrire pour chaque écriture. J'ai vu de la mémoire flash, vous pouvez écrire des bits qui sont toujours à 1 sans effacer la page.
mjh2007
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.