Il existe différents segments de mémoire dans lesquels divers types de données sont insérés à partir du code C après la compilation. Ie: .text
, .data
, .bss
, pile et tas. Je veux juste savoir où chacun de ces segments résiderait dans une mémoire de microcontrôleur. Autrement dit, quelles données vont dans quel type de mémoire, étant donné que les types de mémoire sont RAM, NVRAM, ROM, EEPROM, FLASH, etc.
J'ai trouvé des réponses à des questions similaires ici, mais elles n'ont pas expliqué quel serait le contenu de chacun des différents types de mémoire.
Toute aide est très appréciée. Merci d'avance!
microcontroller
c
embedded
memory
Soju T Varghese
la source
la source
Réponses:
.texte
Le segment .text contient le code réel et est programmé dans la mémoire Flash pour les microcontrôleurs. Il peut y avoir plusieurs segments de texte lorsqu'il existe plusieurs blocs de mémoire Flash non contigus; par exemple un vecteur de démarrage et des vecteurs d'interruption situés en haut de la mémoire et un code commençant à 0; ou des sections distinctes pour un programme d'amorçage et principal.
.bss et .data
Il existe trois types de données qui peuvent être allouées à l'extérieur d'une fonction ou d'une procédure; la première est des données non initialisées (historiquement appelées .bss, qui incluent également les données 0 initialisées), et la seconde est initialisée (non bss), ou .data. Le nom "bss" vient historiquement de "Block Started by Symbol", utilisé dans un assembleur il y a environ 60 ans. Ces deux zones sont situées dans la RAM.
Lors de la compilation d'un programme, des variables seront affectées à l'un de ces deux domaines généraux. Au cours de l'étape de liaison, tous les éléments de données seront collectés ensemble. Toutes les variables qui doivent être initialisées auront une partie de la mémoire du programme réservée pour contenir les valeurs initiales, et juste avant que main () soit appelée, les variables seront initialisées, typiquement par un module appelé crt0. La section bss est initialisée à tous les zéros par le même code de démarrage.
Avec quelques microcontrôleurs, il existe des instructions plus courtes qui permettent d'accéder à la première page (256 premiers emplacements, parfois appelée page 0) de RAM. Le compilateur de ces processeurs peut réserver un mot-clé comme
near
pour désigner les variables à y placer. De même, il existe également des microcontrôleurs qui ne peuvent référencer que certaines zones via un registre de pointeurs (nécessitant des instructions supplémentaires), et de telles variables sont désignéesfar
. Enfin, certains processeurs peuvent traiter une partie de la mémoire bit par bit et le compilateur aura un moyen de le spécifier (comme le mot-clébit
).Il peut donc y avoir des segments supplémentaires comme .nearbss et .neardata, etc., où ces variables sont collectées.
.rodata
Le troisième type de données externes à une fonction ou une procédure est similaire aux variables initialisées, sauf qu'il est en lecture seule et ne peut pas être modifié par le programme. En langage C, ces variables sont désignées par le
const
mot - clé. Ils sont généralement stockés dans le cadre de la mémoire flash du programme. Parfois, ils sont identifiés comme faisant partie d'un segment .rodata (données en lecture seule). Sur les microcontrôleurs utilisant l'architecture Harvard , le compilateur doit utiliser des instructions spéciales pour accéder à ces variables.empiler et tas
La pile et le tas sont tous deux placés dans la RAM. Selon l'architecture du processeur, la pile peut augmenter ou diminuer. S'il grandit, il sera placé au bas de la RAM. S'il croît, il sera placé à la fin de la RAM. Le tas utilisera la RAM restante non allouée aux variables et augmentera la direction opposée de la pile. La taille maximale de la pile et du tas peut généralement être spécifiée en tant que paramètres de l'éditeur de liens.
Les variables placées sur la pile sont toutes les variables définies dans une fonction ou une procédure sans le mot clé
static
. Elles étaient autrefois appelées variables automatiques (auto
mot-clé), mais ce mot-clé n'est pas nécessaire. Historiquement,auto
existe parce qu'il faisait partie du langage B qui a précédé C, et là, il était nécessaire. Les paramètres de fonction sont également placés sur la pile.Voici une disposition typique pour la RAM (en supposant qu'aucune section spéciale de la page 0):
EEPROM, ROM et NVRAM
Avant l'arrivée de la mémoire Flash, l'EEPROM (mémoire morte programmable effaçable électriquement) était utilisée pour stocker le programme et les données const (segments .text et .rodata). Maintenant, il n'y a qu'une petite quantité (par exemple 2 Ko à 8 Ko d'octets) d'EEPROM disponible, le cas échéant, et elle est généralement utilisée pour stocker des données de configuration ou d'autres petites quantités de données qui doivent être conservées lors d'une mise hors tension. cycle. Celles-ci ne sont pas déclarées comme variables dans le programme, mais sont écrites à la place à l'aide de registres spéciaux dans le microcontrôleur. L'EEPROM peut également être implémentée dans une puce séparée et accessible via un bus SPI ou I²C.
La ROM est essentiellement la même que Flash, sauf qu'elle est programmée en usine (non programmable par l'utilisateur). Il est utilisé uniquement pour les appareils à très haut volume.
La NVRAM (RAM non volatile) est une alternative à l'EEPROM et est généralement implémentée en tant que CI externe. La RAM régulière peut être considérée comme non volatile si elle est sauvegardée sur batterie; dans ce cas, aucune méthode d'accès spéciale n'est nécessaire.
Bien que les données puissent être enregistrées dans Flash, la mémoire Flash a un nombre limité de cycles d'effacement / programme (1000 à 10 000), elle n'est donc pas vraiment conçue pour cela. Il nécessite également l'effacement simultané de blocs de mémoire, il n'est donc pas pratique de mettre à jour quelques octets. Il est destiné au code et aux variables en lecture seule.
L'EEPROM a des limites beaucoup plus élevées sur les cycles d'effacement / programme (100 000 à 1 000 000), c'est donc beaucoup mieux à cet effet. S'il y a une EEPROM disponible sur le microcontrôleur et qu'elle est suffisamment grande, c'est là que vous souhaitez enregistrer des données non volatiles. Cependant, vous devrez également effacer les blocs en premier (généralement 4 Ko) avant d'écrire.
S'il n'y a pas d'EEPROM ou qu'elle est trop petite, une puce externe est nécessaire. Une EEPROM de 32 Ko ne coûte que 66 ¢ et peut être effacée / écrite à 1 000 000 de fois. Une NVRAM avec le même nombre d'opérations d'effacement / programme est beaucoup plus chère (x10). Les NVRAM sont généralement plus rapides à lire que les EEPROM, mais plus lentes à écrire. Ils peuvent être écrits sur un octet à la fois ou en blocs.
Une meilleure alternative à ces deux est la FRAM (RAM ferroélectrique), qui a des cycles d'écriture essentiellement infinis (100 billions) et aucun retard d'écriture. C'est à peu près le même prix que la NVRAM, environ 5 $ pour 32 Ko.
la source
Système embarqué normal:
De plus, il existe généralement des segments flash séparés pour le code de démarrage et les vecteurs d'interruption.
Explication:
Une variable a une durée de stockage statique si elle est déclarée en tant que
static
ou si elle réside dans la portée du fichier (parfois appelée bâclée "globale"). C a une règle stipulant que toutes les variables de durée de stockage statique que le programmeur n'a pas initialisées explicitement doivent être initialisées à zéro.Chaque variable de durée de stockage statique initialisée à zéro, implicitement ou explicitement, se retrouve dans
.bss
. Tandis que ceux qui sont explicitement initialisés à une valeur non nulle se retrouvent dans.data
.Exemples:
Veuillez garder à l'esprit qu'une configuration non standard très courante pour les systèmes embarqués consiste à avoir un "démarrage minimal", ce qui signifie que le programme sautera toute initialisation d'objets avec une durée de stockage statique. Par conséquent, il peut être judicieux de ne jamais écrire de programmes qui s'appuient sur les valeurs d'initialisation de ces variables, mais les définissent plutôt en "exécution" avant de les utiliser pour la première fois.
Exemples des autres segments:
Les variables pouvant aller sur la pile peuvent souvent se retrouver dans les registres du processeur lors de l'optimisation. En règle générale, toute variable dont l'adresse n'est pas prise peut être placée dans un registre CPU.
Notez que les pointeurs sont un peu plus complexes que les autres variables, car ils permettent deux types différents de
const
, selon que les données pointées doivent être en lecture seule ou si le pointeur lui-même doit l'être. Il est très important de connaître la différence pour que vos pointeurs ne se retrouvent pas dans la RAM par accident, lorsque vous vouliez qu'ils soient en flash.Dans le cas des constantes entières, des listes d'initialisation, des littéraux de chaîne, etc., ils peuvent se retrouver soit en .text soit en .rodata selon le compilateur. Probablement, ils finissent par:
la source
.data
généralement une soi-disant adresse de chargement en flash, où les valeurs initiales sont stockées, et une soi-disant adresse virtuelle (pas vraiment virtuelle dans un microcontrôleur) en RAM, où la variable est stockée pendant l'exécution. Avant lemain
démarrage, les valeurs initiales sont copiées de l'adresse de chargement vers l'adresse virtuelle. Vous n'avez pas besoin de stocker des zéros, donc.bss
pas besoin de stocker ses valeurs initiales. sourceware.org/binutils/docs/ld/…Alors que toutes les données peuvent entrer dans n'importe quelle mémoire choisie par le programmeur, le système fonctionne généralement mieux (et est destiné à être utilisé) lorsque le profil d'utilisation des données est mis en correspondance avec les profils de lecture / écriture de la mémoire.
Par exemple, le code du programme est WFRM (en écrire quelques-uns en lire plusieurs), et il y en a beaucoup. Cela convient parfaitement à FLASH. ROM OTOH est W une fois RM.
La pile et le tas sont petits, avec beaucoup de lectures et d'écritures. Cela conviendrait le mieux à la RAM.
L'EEPROM ne conviendrait pas à l'une ou l'autre de ces utilisations, mais elle convient au profil de petites quantités de données qui persistent à travers les mises sous tension, donc des données d'initialisation spécifiques à l'utilisateur et peut-être des résultats de journalisation.
la source