La carte, le processeur
Vous allez développer sur des cartes STM32 IoT Node. Ces cartes sont basées sur un microcontrôleur de ST, le STM32L475VGT6. Un microcontrôleur est un circuit intégré rassemblant un coeur de processeur ainsi que plusieurs périphériques usuels. En l'occurrence le coeur de processeur est un ARM Cortex M4 associé à plusieurs périphériques, comme des entrées-sorties basiques appelées GPIO (Global Purpose Input Ouput), des bus (I2C, UART, SPI, …), des générateurs PWM, des convertisseurs analogiques-numériques, etc.
Cette carte inclut plusieurs capteurs, dont :
- des modules de communication radio (WiFi, Bluetooth, SubGHz, …),
- un transpondeur NFC,
- deux microphones,
- un capteur d'humidité et de température,
- un magnétomètre, un accéléromètre et un gyroscope 3D,
- un baromètre de précision,
- un détecteur de distance et de gestes,
- de l'USB OTG,
- un bouton poussoir,
- des LED,
- des connecteurs d'expansion pour brancher des cartes additionelles…

Vous trouverez plusieurs documents importants en bas de cette page :
- La datasheet du processeur STM32L475VGT6.
- Le Manuel de référence du processeur STM32L475VGT6.
- Le Manuel d'utilisateur de la carte IoT Node, et les schémas électroniques.
Impératif : téléchargez au moins le manuel de référence du processeur et stockez-le dans votre dépôt git, ce sera votre bible pour le reste de l'UE. Tant que vous y êtes, téléchargez aussi les autres documents…
Branchement de la carte
Pour alimenter et débugger la carte, il suffit de brancher un câble micro-USB entre la prise USB Débug de la carte et votre PC. C'est tout !
Mapping mémoire
Le mapping mémoire du processeur est disponible en page 75 du reference manual du processeur. Pas la peine de tout lire, pour l'instant retenez juste les emplacements et tailles des éléments suivants :
- Flash : adresse de début = 0x08000000, taille = 1MB
- RAM : elle est séparée en deux blocs non contigus :
- SRAM1 : début = 0x20000000, taille = 96kB
- SRAM2 : début = 0x10000000, taille = 32kB
Dans un premier temps, le programme qu'on écrira sera logé en RAM. Pour des raisons qu'on verra plus tard, nous allons le loger dans SRAM1. SRAM2 sera réservé pour autre chose (patience petit Padawan).
Outils de débug
La carte de développement intègre une sonde JTAG, ce qui est bien pratique. Elle est disponible sur le connecteur de la figure ci-dessus appelé "USB Débug" (!). Plus exactement, ce connecteur USB vous donne accès à deux choses :
- la sonde JTAG intégrée
- un port série sur USB, vu sous Linux comme
/dev/ttyACM0(115200 baud, pas de parité, 8 bits, pas de contrôle de flux)
La sonde JTAG intégrée native est une sonde STLink V2.1. Nous avons reflashé ces sondes de façon à ce qu'elles se comportent comme des sondes JLink de Segger, qui comptent parmi les sondes les plus efficaces du marché et vous offrent des possibilités de débug qui vous seront bien utiles dans la suite du TP.
Comme pour toutes les sondes JTAG, nous devrons utiliser un "driver" pour faire le pont entre gdb et la sonde. Ce driver s'appelle JLinkGDBServer ou JLinkGDBServerExe en version graphique. Il est disponible ici (pour ceux qui souhaitent travailler sur leur portable). Ce "driver" est installé sur toutes les stations de la A406. Il est aussi disponible dans les paquets de la distribution ArchLinux. Si votre carte n'est reconnue que lorsque vous êtes root, c'est que vous avez probablement oublié d'installer les règles udev nécessaires (cf. fichier README.TXT)
Pilotage de la sonde
Depuis gdb, il est possible d'envoyer à la sonde des commandes spécifiques, en les préfixant par "monitor" (ou "mon" pour faire plus court) . Voici les commandes les plus utiles pour les sondes JLink :
reset: déclenche un reset hardware du processeur et le maintient en pause.halt: met le processeur en pause.endian little: déclare à la sonde que le processeur est câblé pour être en mode little-endian.
Pour lancer / débugger un programme, une procédure typique serait la suivante :
- Lancer le driver :
JLinkGDBServer -device STM32L475VG -endian little -if SWD -speed auto -ir -LocalhostOnly - Dans un autre terminal, lancer le cross-débugger :
arm-none-eabi-gdb xxx.elf(remplacerxxx.elfpar le nom du programme que vous voulez débugger) - Dire à gdb qu'on fait du débug distant et sur quel port communiquer avec le driver de sonde :
target ext :2331 - Transmettre au driver de sonde la commande disant que le processeur est en mode little-endian :
mon endian little - Rebooter le processeur et le maintenir en pause par
mon reset. - Transférer le programme sur la carte :
load(ici, gdb se charge de positionner le PC à l'entry point de votre exécutable si celui-ci en a un) - Lancer l'exécution :
cont - Débugger de façon normale (
sipour avancer d'une instruction assembleur, etc.)
Plutôt que de taper à chaque fois toutes ces commandes, il est préférable de se créer un fichier .gdbinit, qui sera exécuté à chaque lancement de arm-none-eabi-gdb dans le répertoire où ce fichier se trouve.
De plus, le driver actuel de sonde ne sait pas comment programmer la flash (le bug a été remonté). D'où les instructions spéciales pour passer la flash en mode "écriture posible" (cf. fonctions flash, romerase and co).
mon endian little
mon halt
# interface with asm, regs and cmd windows
define split
layout split
layout asm
layout regs
focus cmd
end
# interface with C source, regs and cmd windows
define ss
layout split
layout src
layout regs
focus cmd
end
define flash
dont-repeat
mon reset
load
end
# Usefull function when the processor is in hardfault to see
# where it comes from.
define armex
printf "EXEC_RETURN (LR):\n",
info registers $lr
if ($lr & 0x4)
printf "Uses MSP 0x%x return.\n", $MSP
set $armex_base = $MSP
else
printf "Uses PSP 0x%x return.\n", $PSP
set $armex_base = $PSP
end
printf "xPSR 0x%x\n", *($armex_base+28)
printf "ReturnAddress 0x%x\n", *($armex_base+24)
printf "LR (R14) 0x%x\n", *($armex_base+20)
printf "R12 0x%x\n", *($armex_base+16)
printf "R3 0x%x\n", *($armex_base+12)
printf "R2 0x%x\n", *($armex_base+8)
printf "R1 0x%x\n", *($armex_base+4)
printf "R0 0x%x\n", *($armex_base)
printf "Return instruction:\n"
x/i *($armex_base+24)
printf "LR instruction:\n"
x/i *($armex_base+20)
end
document armex
ARMv7 Exception entry behavior.
xPSR, ReturnAddress, LR (R14), R12, R3, R2, R1, and R0
end
Attention : pour des raisons de sécurité, par défaut les .gdbinit ne sont pas lus. Lisez attentivement le message de arm-none-eabi-gdb après avoir créé le .gdbinit pour voir ce que vous avez à faire pour qu'il soit exécuté.
Attention : ce .gdbinit est à comprendre, pas à recopier bêtement. Surtout si vous comptez suivre SE302 : il faudra l'adapter à vos besoins (vous comprendrez lorsque vous aurez fait la partie sur les IRQ).
Une fois que vous avez ce .gdbinit en place (pensez à le committer), tout ce que vous avez à faire est :
flash, pour charger le programme sur le processeur.
Si vous avez défini unENTRYpoint dans votre script de link, gdb positionne automatiquement le PC à la bonne valeurcontpour démarrer le programme.
Conseils :
- Dans votre
Makefile, définissez une cible virtuelle qui lanceJLinkGDBServer(ou la version graphique) avec les bonnes options - À partir de maintenant vous devriez avoir, dans un répertoire nommé TD, un
Makefilequi permet de lancerJLinkGDBServer, ainsi qu'un.gdbinit.
L'environnement de débug est en place, on peut maintenant entrer dans le vif du sujet !
Au fait, vous avez pensé à committer / pusher combien de fois ? Une fois que vous pensez avoir terminé cette partie, mettez le tag git INTRO sur le commit de fin, et pushez le par git push --tags.
Attention : lors de la correction du TP, seuls les commit avec les tags précisés ici seront examinés.
| Fichier attaché | Taille |
|---|---|
| 1.44 Mo | |
| 1.85 Mo | |
| 2.64 Mo | |
| 35.26 Mo | |
| 3.32 Mo | |
| 1.3 Ko |