NON_VOLATILE_MEMORY - Kasimashi/Systemes-embarques GitHub Wiki
Les mémoires non volatile
La mémoire non volatile (NVM) est une mémoire qui persiste même lorsque l'appareil est mis hors tension puis sous tension. Sur les microcontrôleurs et les SoC radio de Silicon Labs, la NVM est implémentée sous forme de mémoire flash. Dans de nombreuses applications, la mémoire flash n'est pas seulement utilisée pour stocker le code de l'application, mais également pour stocker des objets de données qui sont écrits et lus fréquemment par l'application. Comme la mémoire flash ne peut être effacée qu'un nombre limité de fois, plusieurs méthodes existent pour lire et écrire efficacement des données non volatiles sans user la mémoire flash. Certaines données sont considérées comme des données de fabrication qui ne sont écrites qu'une seule fois au moment de la fabrication. Ce document concerne les données dynamiques qui changent fréquemment au cours de la vie du produit. Ce document fournit une introduction aux principales options de conception pour le stockage de données dynamiques dans les microcontrôleurs et les SoC radio, ainsi que des directives sur les facteurs qui affectent la durée de vie de la mémoire flash. En outre, il présente les principales implémentations de stockage de données flash proposées par Silicon Labs : • NVM3 • EEPROM simulée version 1 (SimEEv1) et version 2 (SimEEv2) • Stockage persistant (PS Store)
Implémentation basique
L'une des caractéristiques de la mémoire flash est qu'elle est inscriptible en morceaux plus petits, généralement des mots de 32 bits, alors qu'elle ne peut être effacée qu'en plusieurs fois. Des morceaux plus gros, généralement des pages de plusieurs kilo-octets. Lors de l'utilisation de Flash comme stockage de données, l'option de mise en œuvre la plus simple serait de stocker chaque objet de données dans sa propre page flash, comme le montre la figure suivante. De cette façon, chaque objet peut être effacé et réécrit sans influencer les autres objets de données. Habituellement, les objets de données sont beaucoup plus petits que la taille de la page, et cette solution n'est pas un moyen efficace d’utiliser l’espace flash disponible.
Pour éviter de gaspiller de l'espace flash, nous pouvons stocker plusieurs objets de données sur une seule page flash, comme le montre la figure suivante. Cette solution alors introduit un défi lorsque nous voulons écrire une nouvelle valeur dans l'un des objets de données. Dans ce cas, la page doit être effacée avant tout les objets sont réécrits sur la page, y compris l'objet que nous avons modifié. Comme la mémoire flash ne peut supporter qu'une quantité limitée de flash s'efface avant que les cellules flash ne soient usées, cette solution entraîne une durée de vie très limitée de l'appareil.
Pour éviter d'effacer la page flash à chaque écriture d'objet, nous pouvons écrire de nouvelles versions de chaque objet dans de nouveaux emplacements vides du fichier. page flash. Il s'agit d'une forme simple de nivellement de l'usure qui réduit le nombre d'effacements de pages. Cependant, cela nécessite que nous stockions une partie des informations d'identification ainsi que les données de l'objet qui nous indiquent à quel objet appartiennent les données, afin que nous sachions comment trouver la dernière version de l'objet de données. Ceci est illustré dans la figure suivante, où une clé est ajoutée à chaque version des données d'objet pour identifier ce qui objet auquel appartiennent les données. Lors de l'accès à un objet, nous devons ensuite rechercher dans la page flash la version la plus récente du objet. Dans ce cas, la version la plus récente est celle avec l'adresse la plus élevée, car nous commençons à écrire à partir de l'adresse la plus basse de la page.
Gestion des reset ou des pertes d'alimentations
Au fur et à mesure que nous remplissons la page Flash avec de nouvelles versions des objets de données, il ne reste finalement plus de place pour écrire de nouvelles données d'objet. À ce stade, nous vous devez effacer la page et recommencer en écrivant uniquement les dernières versions de chaque objet sur la page flash. Cependant, dans de nombreuses applications, des pannes de courant ou des réinitialisations peuvent survenir à tout moment, et nous ne devrions pas risquer de perdre des données si cela se produit. Si une réinitialisation se produit après le flash la page est effacée, mais avant que les objets de données ne soient réécrits, nous perdrons ces données. Pour gérer ce cas, nous introduisons une deuxième page, sur laquelle nous copions la dernière version des objets de données, avant d'effacer la page d'origine, comme le montre la figure suivante. Ensuite, nous pouvons commencer à remplir la deuxième page avec des données. Lorsque la deuxième page est pleine, nous déplaçons les dernières données vers la première page et ainsi sur. Ce mécanisme, où le stockage est alterné entre deux pages flash, est le fonctionnement du PS Store.
Introduction aux pages virtuelles
Dans certaines applications, nous écrivons fréquemment sur des objets de données et les pages Flash doivent donc également être effacées fréquemment. Comme les objets de données dans l'implémentation jusqu'à présent ne sont répartis que sur deux pages Flash, chaque page sera fréquemment effacée et la durée de vie de la mémoire Flash sera limitée. Pour augmenter la durée de vie, nous pouvons utiliser davantage de pages Flash pour stocker les objets de données. Dans cet exemple, au lieu de deux pages physiques, nous fonctionnons avec deux pages virtuelles (A et B) qui se composent chacune de plusieurs pages Flash physiques. Les pages virtuelles sont effacées et écrites comme s'il s'agissait d'une seule page Flash plus grande. La différence est simplement que chaque page virtuelle est plus grande et que nous pouvons écrire davantage de données avant de devoir effacer la page virtuelle, ce qui prolonge la durée de vie. En plus d'augmenter la durée de vie de la mémoire Flash, l'utilisation de plusieurs pages Flash par page virtuelle vous permet de stocker davantage d'objets ou des objets plus grands. SimEEv1 utilise cette conception, chaque page virtuelle étant composée de deux pages Flash, A et B, comme illustré dans la figure suivante.
Dans certaines applications, le temps nécessaire à l'écriture d'un objet de données non volatile doit être réduit au minimum afin de ne pas interférer avec le timing d'autres opérations critiques. Si une écriture d'objet est déclenchée alors qu'une page virtuelle est pleine, la dernière version de tous les objets doit d'abord être copiée sur la nouvelle page virtuelle avant d'écrire la nouvelle version de l'objet en question sur la nouvelle page. Tous les objets doivent être copiés immédiatement pour permettre l'effacement rapide de la première page afin que nous puissions y déplacer les données en cas de panne. La copie de tous les objets en même temps augmente le temps d'écriture de l'objet dans le pire des cas.
Pour réduire les temps d'écriture, une troisième page virtuelle peut être introduite et est toujours effacée. Au lieu de copier la dernière version de chaque objet lorsque la première page est pleine, nous pouvons copier uniquement certains des objets. Le reste des objets est copié dans le cadre des opérations d'écriture suivantes. De cette façon, nous répartissons le processus de copie vers la nouvelle page sur plusieurs opérations d'écriture, chaque opération d'écriture prenant donc moins de temps à se terminer. Avec cette approche, nous avons des données d'objets en direct réparties sur deux pages virtuelles et la troisième page est toujours effacée, nous avons donc un endroit où déplacer les données en cas de panne. SimEEv2 utilise cette implémentation avec 3 pages virtuelles où chaque page virtuelle se compose de 6 pages flash.
Stockage basique
Le stockage de base est défini comme la taille de toutes les dernières versions de tous les objets, y compris toute surcharge stockée avec eux. À l'exception de NVM3, chaque fois qu'une page Flash ou une page virtuelle est effacée, nous devons d'abord déplacer le stockage de base vers une nouvelle page. La taille du stockage de base est importante, car elle détermine la quantité d'espace Flash restant dans une page pour stocker les nouvelles versions des données de l'objet. Si le stockage de base occupe presque toute la page, nous ne pouvons écrire que quelques nouvelles versions d'objet avant de devoir passer à une nouvelle page et effacer l'ancienne. Cela entraîne des effacements de pages fréquents et une courte durée de vie du Flash.
La NVM3 copie uniquement les objets uniques stockés dans la page qui sera effacée. Si des versions plus récentes de l'objet existent dans d'autres pages, l'objet ne sera pas copié.
Modèle FIFO
Les implémentations de stockage de données flash peuvent être modélisées comme un tampon FIFO (First-In First-Out) (voir la figure suivante), dans lequel nous écrivons de nouvelles versions à l'entrée du FIFO. Au fur et à mesure que le FIFO se remplit, nous devons libérer de l'espace en effaçant une ou plusieurs pages à la fin du FIFO. Avant d'effacer une page, nous devons copier toutes les versions d'objet pour lesquelles aucune version plus récente du même objet n'existe dans le reste des pages flash. D'autres données d'objet peuvent être supprimées, car des versions plus récentes existent. Pour maximiser la durée de vie du flash, nous voulons copier le moins de versions d'objet possible, de sorte que la plupart des écritures dans la mémoire flash soient de nouvelles versions des objets. Si le FIFO est implémenté sur un grand espace flash, il est plus probable que la nouvelle version de l'objet ait été écrite et que les versions d'objet à la fin du FIFO puissent être supprimées. Dans ce cas, la page flash peut être effacée avec peu ou pas de versions d'objet copiées.
L'inconvénient de l'utilisation de quelques pages virtuelles est que la mémoire disponible pour le FIFO est limitée aux seules pages virtuelles pouvant contenir des données en direct. Pour les implémentations utilisant deux pages virtuelles, comme SimEEv1, cela signifie que seule la moitié de l'espace de stockage est utilisée pour le FIFO, tandis que pour SimEEv2, les deux tiers de l'espace de stockage sont utilisés pour le FIFO.
Pour permettre l'utilisation d'une plus grande partie de l'espace de stockage pour le FIFO, nous pouvons plutôt implémenter le FIFO comme un tampon circulaire sur l'ensemble de l'espace de stockage flash alloué, comme illustré dans la figure suivante. Dans cette implémentation, nous devons toujours conserver suffisamment de pages effacées devant le bord avant du tampon pour écrire l'objet de plus grande taille en cas de panne. Lorsque le FIFO se remplit pour atteindre le nombre critique de pages flash effacées, nous copions toutes les versions d'objet qui n'ont pas été remplacées et effaçons la page à l'arrière du FIFO. Cela signifie qu'au lieu de conserver une page virtuelle complète effacée, nous devons uniquement conserver suffisamment d'espace effacé pour contenir l'objet de plus grande taille. Nous pouvons utiliser le reste de l'espace pour le FIFO. NVM3 est implémenté comme un tampon circulaire implémenté sur l'ensemble de l'espace de stockage, augmentant ainsi la durée de vie du flash par rapport aux implémentations utilisant des pages virtuelles plus petites.
Objects de type Counter
Pour certains types de données, le format de stockage peut être optimisé pour le support flash. Les EFR32 Series 0 et 1 peuvent écrire chaque mot deux fois, ce qui permet des mises à jour d'un demi-mot. Les périphériques Series 2 n'autorisent qu'une seule écriture par mot. Par exemple, les valeurs de compteur sont généralement incrémentées de 1 ou d'une autre valeur faible à chaque fois qu'elles sont écrites. Normalement, cela signifie que nous devrions écrire la valeur entière du compteur en plus des octets d'identification à chaque fois que le compteur est incrémenté. Nous pouvons optimiser cela en stockant uniquement une valeur de départ en plus de la valeur d'identification la première fois qu'un compteur est écrit. Ensuite, nous réservons un certain nombre de mots suivant la valeur initiale pour les incréments d'écriture. Les mots flash des périphériques Silicon Labs EFR32 Series 0 et 1 peuvent écrire des mots deux fois entre chaque effacement en conservant un 1 dans les bits qui ne doivent pas être modifiés.
À titre d'exemple, supposons que nous écrivions deux valeurs de 16 bits, 0xAAAA et 0x5555. Pour les écrire en toute sécurité dans le même mot flash, cette méthode peut être utilisée : • Écrire 0xFFFFAAAA (le mot dans le flash devient 0xFFFFAAAA) • Écrire 0x5555FFFF (le mot dans le flash devient 0x5555AAAA)
Notez qu'il y a un maximum de deux écritures sur le même mot entre chaque effacement en raison d'une limitation physique du flash.
Pour trouver la valeur actuelle du compteur, nous commençons par la valeur initiale et ajoutons les valeurs d'incrément dans les demi-mots suivant la valeur initiale. Cela signifie que nous n'avons besoin d'écrire qu'un demi-mot pour chaque incrément, au lieu de la valeur de compteur entière et de la valeur d'identification. NVM3 et SimEEv1/v2 prennent en charge les objets compteurs.
Objects Indexés
Lors du stockage de données telles que des tableaux dans la mémoire Flash, nous ne mettons souvent à jour qu'un seul index à la fois. Si nous stockons l'ensemble du tableau sous la forme d'un seul objet ordinaire, nous devons écrire l'ensemble du tableau dans la mémoire Flash même si un seul index est mis à jour. Au lieu de stocker l'ensemble du tableau dans un seul objet, nous pouvons diviser chaque tableau de données en plusieurs objets et mettre à jour uniquement les objets contenant les index de tableau modifiés. Bien qu'il soit possible de diviser manuellement les tableaux en plusieurs objets pour toutes les implémentations de stockage Silicon Labs, SimEEv1/v2 permet à tous les index de partager une clé d'objet. L'entrée d'index dans le tableau à rechercher est alors fournie sous la forme d'un paramètre distinct.
NVM3 ne prend pas en charge la lecture et l'écriture de parties d'un objet. Si l'application souhaite accéder aux index individuellement, chaque index doit être accessible à l'aide d'une clé unique.
Durée de vie de la Flash
Toutes les implémentations de stockage de données Flash de Silicon Labs utilisent une certaine forme de nivellement de l'usure pour prolonger la durée de vie du flash. L'efficacité du nivellement de l'usure dépend de l'implémentation, du type de données stockées et de la fréquence de mise à jour. Les principaux facteurs qui affectent le nivellement de l'usure et donc la durée de vie du flash sont les suivants :
• Taille de la mémoire flash utilisée pour le stockage des données : une plus grande surface de mémoire flash augmente la durée de vie de la mémoire flash. Pour NVM3, le nombre de pages flash utilisées pour le stockage des données peut être configuré, tandis que les autres implémentations utilisent des tailles de stockage fixes.
• Surcharge stockée par objet : lors de l'écriture de données dans le stockage d'objets, certains octets de surcharge sont ajoutés pour identifier les données. Une implémentation avec moins de surcharge signifie que les objets de données occupent moins d'espace dans la mémoire flash et offre une durée de vie de la mémoire flash plus longue.
• Alignement sur la taille minimale de l'objet : les objets sont stockés en multiples de la plus petite taille d'objet. Si la taille des données ne correspond pas à cette taille, des octets de remplissage sont ajoutés, ce qui augmente les données stockées et réduit la durée de vie de la mémoire flash. Par exemple, lors du stockage d'objets 16 bits, NVM3 et PS Store ajoutent deux octets de remplissage supplémentaires en plus des octets de surcharge. SimEEv1/v2 sont capables de stocker des objets de données 16 bits sans remplissage.
• Stockage restant après le stockage de base : pour les implémentations utilisant des pages virtuelles, lors du passage à une nouvelle page virtuelle, une instance de chaque objet est écrite sur la page. Le reste de la page virtuelle peut ensuite être utilisé pour stocker de nouvelles écritures des objets. Si beaucoup d'espace est utilisé pour stocker une instance de chaque objet, il reste peu d'espace dans la page virtuelle pour l'utiliser pour niveler l'usure des écritures d'objet suivantes. La durée de vie de la mémoire flash sera donc réduite lorsque la quantité totale de données d'objet est importante par rapport à la taille de la page virtuelle. Même pour NVM3, où les pages virtuelles ne sont pas utilisées, la durée de vie de la mémoire flash est limitée par l'espace disponible du stockage NVM3 total.
Pour aider à surveiller l'usure réelle du flash, NVM3 et SimEEv1/v2 incluent des appels de fonction pour signaler le nombre d'effacements de pages des pages flash de stockage de données. Ces compteurs d'effacement peuvent être lus lors des tests accélérés de durée de vie d'un produit pour vérifier si le flash s'use à un rythme acceptable.