Dans cet article j'explique comment programmer la carte blue pill sans autre outils que ceux fournis par l'open source gnu-arm-none-eabi. Cet article est une adaptation de l'article en anglais produit par Jacob Mossberg. Même si l'article original réfère à une carte STM32-H103 et un programmeur ARM-USB-OCD-H, les outils logiciels et la procédure sont les même pour la carte blue pill et le programmeur STLINK/V2 que j'utilise.
Installation des outils logiciels
- Les utilitaires pour travailler avec les fichiers binaires. Sur mon système la version la plus récente est 2.26.1
sudo apt install binutils-arm-none-eabi
- Le compilateur GCC. Sur mon système la version la plus récente est 5.4.0
sudo apt install gcc-arm-none-eabi
- Le débogueur. Sur mon système la version la plus récente est 7.11.1
sudo apt install gdb-arm-none-eabi
Compiler le programme exemple
Téléchargez les 3 fichiers exemples fournis par Jacobs Mossberg.
- Le code d'initialisation du µC startup.c
- Le fichier pour le linker stm32.ld
- Finalement le fichier makefile.
- Dans mon dépôt blue_pill dans le dossier C il y a les fichiers blink.c et stm32f103c8.h que je vais utiliser comme programme de démonstration.
compiler le programme.
- J'ai modifié le fichier makefile
- Sur la ligne de commande à partir du dossier contenant les fichiers sources il suffit de faire la commande:
pour créer le fichier blink.bin
make build
- La commande suivante suppose que la carte blue pill est branchée au stlink/v2 et que ce dernier est branché au PC.
st-flash write blink.bin 0x8000000
Déboguer un programme avec gdb et stlink/v2
Le programme est déjà déboguer mais on va supposer qu'il ne l'est pas et on va le recompiler pour le débogage avec la commande
make build_debug
st-flash write blink.bin 0x8000000
Séance de débogage
Dans la console déjà ouverte on lance:
st-util
arm-none-eabi-gdb -tui --eval-command="target remote localhost:4242" blink.elf
Les commandes les plus utiles sont les suivantes:
- hbreak arg, pour créer un point d'arrêt matériel. Comme argument on peut utiliser le nom d'une fonction ou un numéro de ligne.
exemples:(gdb) hbreak main (gdb) hbreak main.c:29
- continue ou c, pour relancer l'exécution. S'il n'y a pas de point d'arrêt faire <CTRL-c> pour arrêter l'exécution.
- step ou s, pour exécuter une seule ligne de code.
- next ou n, même chose que step mais saute les appels de fonctions.
- layout regs, pour ouvrir une fenêtre qui affiche le contenu des registres du CPU.
- print var, pour imprimer le contenu d'une variable.
- delete, pour supprimer les points d'arrêt.
- clear no|nom, pour supprimer un point d'arrêt par le numéro de ligne no ou le nom de la fonction.
Une meilleure version de blink
Cette version de blink est loin d'être idéale car elle utilise une boucle de code pour le délais. Ce qui fait que le délais varie en fonction de l'optimisation du code par le compilateur et aussi avec la fréquence du clock. Pour améliorer le programme on va utiliser une minuterie et pourquoi pas brancher la sortie PC13 à un PWM ainsi une fois l'initialisation complétée le µC n'aura plus rien à faire. Au va profiter de l'occasion pour configurer le clock à 72 Mhz en utilisant l'oscillateur externe et le PLL au lieu de l'oscillateur interne.
2018-09-01
J'ai terminé la version améliorée de blink. Elle est dans le dossier blink_v2. Cette version utilise le cristal externe avec le PLL pour obtenir une fréquence SYSCLK maximale de 72 Mhz. Le CPU Cortex-M3 possède un compteur interne de 24 bits incrémenté à la fréquence du clock AHB ou AHB/8. J'ai configuré se compteur pour produire un délais d'une milliseconde avec la fonction millisec() qui est appelé par la fonction delay() qui détermine la fréquence de clignotement de la LED.
Voici la nouvelle version de blink_v2.c
Une autre amélioration à apporter serait d'ajouter une interruption sur le coretimer et de créer un variable globale systicks qui serait incrémmentée à l'intérieur de cette interruption à toute les milliseconde.
2018-09-03
J'ai ajouté systick_demo. Ce programme démontre comment installer une routine d'interruption. La routine d'interruption systick_int incrémente la variable ticks et décrémente la variable timer si sa valeur est non nulle. systick_int gère l'interruption du coretimer qui est programmée pour se produire à intervalle de 1 milliseconde.
2018-09-16
Je poursuis mes expérimentations de programmation bare metal de la blue pill en C. j'ai ajouté plusieurs démos dans le dépôt git
- Expérimentation avec le core timer
- Expérimentation avec les interruptions
- Expérimentation avec le RTC
- Expérimentation avec les appels systèmes.
retour à l'introduction
Aucun commentaire:
Publier un commentaire
Remarque : Seuls les membres de ce blogue sont autorisés à publier des commentaires.