Mise en flash
Le but de cette partie est d'obtenir une carte qui puisse fonctionner toute seule, dès qu'on la met sous tension, sans avoir besoin d'uploader un programme ni de lancer gdb. Pour cela vous allez placer votre exécutable en flash.
Mapping mémoire
On rappelle que le mapping mémoire du processeur est disponible en pages 75 et suivantes du reference manual du processeur :
- Flash : adresse de début =
0x08000000
, taille = 1 MB - RAM : elle est séparée en deux blocs non contigus :
- SRAM1 : début =
0x20000000
, taille = 96 kB - SRAM2 : début =
0x10000000
, taille = 32 kB
- SRAM1 : début =
Attention : La zone en 0x1FFF 7000
est une zone OTP : One Time Programmable. Surtout n'écrivez rien dedans : une mauvaise écriture dedans peut mettre la carte dans un mode "sécurisé" où ne peut plus ni relire, ni modifier, ni effacer le contenu de la flash : la carte devient donc inutilisable pour les prochains TP. Nous vérifierons les cartes, si vous avez écrit dedans vous serez pénalisés.
Problème
Après un reset, le processeur va exécuter l'instruction dont l'adresse se trouve à la 2e position de votre table des vecteurs. Cette adresse doit correspondre à l'adresse d'une fonction thumb (i.e. le bit 0 doit être à 1).
❎ Est-ce bien le cas (utilisez objdumb pour vérifier) ?
❎ Si ce n'est pas le cas, ajoutez dans votre crt0.s
la directive qui permet de dire que le symbole _start
est bien une fonction thumb. Aidez-vous pour cela de la documentation spécifique aux directives pour les processeurs ARM De GNU AS.
❎ De plus, il ne faut plus utiliser le fichier clocks.o
qui vous avait été fourni, mais le recompiler vous-même à partir de clocks.c, avec les mêmes options que les autres fichiers et les optimisations -Og
ou -O1
(pas de -O2
ni -O3
).
Passage du code en XIP
❎ En vous rappelant des étapes de boot d'un processeur et de tout ce que doit faire le crt0.s
, modifiez votre linker script et votre code d'initialisation de façon à ce que la carte puisse booter et que le programme s'exécute depuis la flash.
Attention : avant de reflasher votre carte avec gdb, vérifiez bien avec objdump
que vous ne touchez qu'aux zones autorisées en flash.
❎ Fermez gdb et le driver de sonde JLink, débranchez votre carte puis rebranchez-la. Vérifiez que votre s'exécute correctement tout seul.
❎ N'oubliez pas de mettre le tag XIP
.
Recopie du code en RAM
Sur beaucoup de processeurs l'accès à la flash est plus lent que l'accès à la RAM. C'est le cas sur votre processeur.
❎ Modifiez votre code et votre linker script de façon à ce que le code
- commence par s'exécuter en flash,
- s'auto-recopie en RAM,
- transfère son exécution à la partie située en RAM.
On laissera la section .rodata
en flash. On relogera la table des vecteurs d'interruption en RAM, de façon à donner à l'utilisateur la possibilité de mettre en place ses propres handlers d'IRQ.
❎ N'oubliez pas de mettre le tag FLASH
sur votre dernier commit et de pusher le tout sur votre branche main
:-)