Considérations relatives à la gestion de la mémoire et de la latence
Cette rubrique décrit les considérations de base relatives à l’utilisation de la mémoire et à la latence pour les applications en temps réel qui s’exécutent sur la puce MT3620.
Note
Pour plus d’informations sur la configuration de la mémoire ou DMA, consultez la feuille de données MT3620 publiée à partir de MediaTek. Si des questions persistent, vous pouvez demander la « feuille de données MT3620 M4 » à Avnet en envoyant un e-mail à Azure.Sphere@avnet.com.
Disposition de la mémoire sur les cœurs en temps réel
Le tableau suivant récapitule la mémoire disponible sur les cœurs en temps réel :
Type de mémoire | Adresse de base |
---|---|
TCM | 0x00100000 |
Flash XIP | 0x10000000 |
SYSRAM | 0x22000000 |
Chaque cœur en temps réel a 192 Ko de mémoire étroitement couplée (TCM), qui est mappée dans trois banques de 64 Ko à partir de 0x00100000. Les accès TCM sont rapides, mais seul le cœur en temps réel peut accéder à la mémoire. TCM ne peut pas être partagé avec une application de haut niveau ou avec une application en temps réel (RTApp) qui s’exécute sur un autre cœur.
Chaque cœur en temps réel a également 64 Ko de SYSRAM, qui est mappé à partir de 0x22000000. Le contrôleur DMA peut également cibler SYSRAM, afin que les périphériques puissent y accéder. Les accès à SYSRAM à partir du cœur en temps réel sont plus lents que les accès à TCM. Comme avec TCM, SYSRAM ne peut pas être partagé avec une autre application.
La mémoire flash D’exécution sur place (XIP) est partagée avec les applications de haut niveau. Une fenêtre dans le mappage XIP du flash est visible pour chaque cœur à l’adresse 0x10000000. Le système d’exploitation configure le mappage XIP avant de démarrer l’application si le fichier ELF de l’application contient un segment qui a les propriétés suivantes :
- L’adresse de chargement (comme spécifié dans la colonne VirtAddr de l’en-tête de programme) est égale à 0x10000000
- Décalage et taille du fichier (comme spécifié dans les champs FileSiz et MemSiz dans l’en-tête du programme) dans le fichier ELF de l’application
Si un en-tête de programme avec ces propriétés est présent dans le fichier ELF de l’application, la fenêtre XIP est positionnée de sorte que le segment soit visible à 0x10000000. Le fichier ne peut pas avoir plus d’un segment XIP et doit pointer vers 0x10000000 ; il ne peut pas spécifier d’autre adresse.
Déploiement d’ELF
Les images RTApp doivent être des fichiers ELF. L’image ELF est encapsulée dans un package d’images Azure Sphere et déployée en tant qu’application. Pour charger l’application, le système d’exploitation Azure Sphere démarre un chargeur ELF qui s’exécute sur le cœur en temps réel. Le chargeur traite chaque segment LOAD dans le fichier ELF et le charge dans le type de mémoire indiqué par l’adresse virtuelle dans l’en-tête du programme.
Utilisez arm-none-eabi-readelf.exe -l
(L minuscule), qui fait partie de la chaîne d’outils GNU Arm Embedded Toolchain, pour afficher les en-têtes de programme de votre application. La colonne d’adresse virtuelle (VirtAddr) qui apparaît dans l’en-tête indique l’adresse de destination du segment de charge. Cela ne signifie pas que le processeur lui-même effectue une traduction supplémentaire. Le chargeur ELF Azure Sphere n’utilise pas l’adresse physique (PhysAddr).
Prenons l’exemple suivant :
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000098 0x00100000 0x00100000 0x00000 0x00e78 RW 0x8
LOAD 0x0000a0 0x10000000 0x10000000 0x03078 0x03078 RWE 0x10
LOAD 0x003118 0x00100e78 0x10003078 0x000f0 0x000f0 RW 0x4
Le segment à 0x00100000 cible la mémoire étroitement couplée (TCM). Le chargeur copie les données du package d’image dans la RAM ou initialise zéro le TCM en fonction des besoins.
Le segment à 0x10000000 est mappé à la fenêtre XIP pour le cœur. Au moment de l’exécution, les accès à
0x10000000 + offset
sont traduits en<address-of-XIP-segment-in-flash> + offset
lorsqu’ils quittent le cœur en temps réel.Le segment de données à l’adresse virtuelle 0x00100e78 est mappé à TCM.
Considérations relatives au runtime ELF
Le chargeur ELF effectue certaines des tâches qu’un binaire brut (ou chargeur de démarrage chaîné) effectuerait au démarrage. Plus précisément, il initialise zéro les données BSS (block-started-by-symbol) et copie les données initialisées mais mutables du flash en lecture seule dans la RAM, en fonction des en-têtes de programme. L’application démarre et exécute ensuite ses propres fonctions d’initialisation. Dans la plupart des cas, les modifications apportées aux applications existantes ne sont pas requises. La mise à zéro des données BSS dans l’application est inutile, mais sans danger, car le chargeur a déjà zéro la mémoire.
La copie de données mutables du flash vers la RAM peut, dans certains cas, entraîner des problèmes, selon la façon dont le fichier ELF est disposé. Le chargeur ELF traite les en-têtes de programme de manière séquentielle, sans modifier la disposition globale des segments dans le fichier. Il mappe ensuite non seulement le segment XIP lui-même à 0x10000000, mais également tous les segments suivants dans l’ordre. Si les segments du fichier ELF sont dans l’ordre séquentiel sans alignement ni intervalles, le code de démarrage du système d’exploitation peut utiliser l’arithmétique du pointeur pour rechercher le début du segment de données. Toutefois, si le fichier ELF a une disposition différente, l’arithmétique du pointeur n’entraîne pas l’adresse correcte. Par conséquent, le code de démarrage de l’application ne doit pas essayer de copier la section de données. Cela peut entraîner des problèmes si l’application ou RTOS utilise un chargeur de démarrage chaîné ou doit configurer une pile canary avant de mettre à zéro BSS ou d’initialiser des données mutables.
Cibles de mémoire
Vous pouvez cibler du code sur TCM, flash XIP ou SYSRAM en modifiant le script linker.ld pour votre application. Les exemples d’applications Azure Sphere s’exécutent à partir de TCM, mais le fichier de script linker.ld pour chaque application décrit comment cibler le flash XIP à la place. Comme le montre l’exemple suivant, vous pouvez modifier un exemple pour qu’il s’exécute sur XIP en alias CODE_REGION et RODATA_REGION flash au lieu du gestionnaire de configuration TCM par défaut :
REGION_ALIAS("CODE_REGION", FLASH);
REGION_ALIAS("RODATA_REGION", FLASH);
Pour déterminer si une application compilée s’exécute à partir de TCM ou de XIP Flash, utilisez arm-none-eabi-readelf.exe
, qui fait partie de la chaîne d’outils GNU Arm Embedded Toolchain. Exécutez-le sur le fichier .out, qui se trouve dans le même répertoire que le package d’image, puis spécifiez l’indicateur -l
(L minuscule) pour voir où le code et les données en lecture seule ont été placés. Le code et les données en lecture seule qui sont en mémoire flash sont chargés à l’adresse 0x10000000 ; le code et les données dans TCM sont chargés dans la région TCM.
L’exemple suivant montre une application qui s’exécute à partir de la mémoire flash.
arm-none-eabi-readelf.exe -l UART_RTApp_MT3620_BareMetal.out
Elf file type is EXEC (Executable file)
Entry point 0x10000000
There are 2 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000074 0x00100000 0x00100000 0x00284 0x003c0 RW 0x4
LOAD 0x000300 0x10000000 0x10000000 0x013b9 0x013b9 R E 0x10
Section to Segment mapping:
Segment Sections...
00 .data .bss
01 .text .rodata
Emplacement de la table de vecteurs
Sur les appareils ARMv7-M, la table de vecteurs doit être alignée sur une limite power-of-2 d’au moins 128 octets et non inférieure à la taille de la table, comme indiqué dans le manuel de référence de l’architecture ARMv7-M. Chaque cœur RT d’E/S sur le MT3620 prend en charge 100 interruptions externes. Par conséquent, en incluant le pointeur de pile et 15 exceptions standard, la table comporte 116 entrées de 4 octets, pour une taille totale de 464 octets, ce qui arrondit à 512 octets.
Lorsque le code est exécuté à partir du flash XIP, la table vectorielle doit être placée à 0x10000000 et doit être alignée sur une limite de 32 octets dans le fichier ELF. Lorsque le code n’est pas exécuté à partir du flash XIP, la table est généralement placée au début de TCM0, ce qui est 0x100000. Dans les deux cas, pour vous assurer que l’adresse virtuelle de la table est correctement alignée, placez la table de vecteurs dans une section dédiée et définissez CODE_REGION sur l’adresse appropriée.
Les exemples BareMetal MT3620 dans le référentiel d’exemples Azure Sphere montrent comment procéder. La déclaration de la table de vecteurs dans main.c définit son section
attribut sur .vector_table
. Les alias de script de l’éditeur de liens CODE_REGION au début de TCM ou XIP, et l’attribut ALIGN définit l’alignement de la section de texte dans le fichier ELF comme suit :
SECTIONS
{
.text : ALIGN(32) {
KEEP(*(.vector_table))
*(.text)
} >CODE_REGION
...
}
Considérations relatives au temps réel et à la latence
Les rtapps et les applications de haut niveau se disputent l’accès à la mémoire flash, même si elles ne communiquent pas entre elles. Par conséquent, les applications en temps réel qui s’exécutent à partir d’un flash XIP peuvent rencontrer une latence élevée et imprévisible. Les écritures sur flash, par exemple pendant une mise à jour, peuvent impliquer des pics de latence pouvant atteindre plusieurs centaines de millisecondes. En fonction des exigences de votre application, vous pouvez gérer cela de plusieurs façons :
Placez tout le code et les données dans TCM. Le code qui s’exécute à partir de TCM n’est pas vulnérable à la contention pour flash.
Fractionnez le code en sections critiques et non critiques, puis exécutez le code non critique à partir du flash. Le code qui a des exigences en temps réel, comme un minuteur de surveillance, ne doit pas avoir à s’exécuter quand un autre code accède au flash. Les cibles de mémoire expliquent comment cibler le flash XIP au lieu de TCM.
Utilisez le cache. Une application peut utiliser les 32 Ko de TCM les plus bas comme cache XIP. Cette approche ne fournit pas de garanties dures en temps réel en cas d’absence de cache, mais améliore les performances classiques sans que vous mettez tout le code dans la RAM. Reportez-vous à la « feuille de données MT3620 M4 » pour plus d’informations sur la configuration du cache XIP.