Développement du microcontrôleur ARM Olimex STM32-H152 avec ChibiOS/RT à partir de l'interface de ligne de commande Linux
Un article précédent a montré comment mettre en œuvre un exemple de système ChibiOS pour la plate-forme Olimex STM32-H152 à partir d'une éclipse sous les fenêtres. Le présent article montre comment obtenir les mêmes résultats en utilisant un ordinateur basé sur Linux.
Matériel
Nous utilisons la même plateforme que le tutoriel original qui est un Olimex STM32-H152. La carte est basée sur le processeur STM32L de STMicroelectronics. Les spécifications exactes sont disponibles sur le poste original. Nous utilisons également le même débogueur ARM USD JTAG avec OpenOCD.
Environnement de développement
Pour ce tutoriel, nous utilisons une machine 64 bits fonctionnant sous Fedora 21. Pour ce billet, contrairement au précédent, nous utiliserons les outils typiques disponibles dans le shell gnome plutôt que l'intégration d'éclipse. Nous allons d'abord créer un répertoire de projet
mkdir
cd
Nous devrons obtenir la dernière version de ChibiOS sur le site web de ChibiOS (via sourceforge).
wget http://downloads.sourceforge.net/project/chibios/ChibiOS_RT%20stable/Version%202.6.7/ChibiOS_2.6.7.zip
unzip ChibiOS_2.6.7.zip
Les paquets fournissent un ensemble de scripts et de modèles de configuration que nous pouvons utiliser pour notre projet. Bien que nous puissions modifier les fichiers directement sous les paquets décompressés, nous en créerons une copie pour rester fidèle à l'exemple original tout en évitant de modifier le paquet original. Par conséquent, une fois que nous serons passés du "tutoriel" au "projet réel", la réutilisation et les mises à jour du code devraient être un peu plus faciles. À ce stade, nous allons donc créer un répertoire de projet dans lequel nous allons copier l'exemple de ChibiOS :
cp ./ChibiOS_2.6.7/demos/ARMCM3-STM32L152-DISCOVERY/* .
Nous remplacerons le contenu du fichier main.c par :
#include "ch.h"
#include "hal.h"
int main(void) {
halInit();
chSysInit();
palSetPadMode(GPIOE, GPIOE_PIN10, PAL_MODE_OUTPUT_PUSHPULL);
while (TRUE) {
palSetPad(GPIOE, GPIOE_PIN10);
chThdSleepMilliseconds(500);
palClearPad(GPIOE, GPIOE_PIN10);
chThdSleepMilliseconds(500);
}
}
Enfin, nous aurons besoin de la chaîne d'outils ARM :
wget https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q1-update/+download/gcc-arm-none-eabi-4_9-2015q1-20150306-linux.tar.bz2
tar -xjf gcc-arm-none-eabi-4_9-2015q1-20150306-linux.tar.bz2
Ce tarball inclut à la fois le compilateur gcc arm utilisé par les makefiles ChibiOS et le débogueur gdb. Pour que tout cela fonctionne, nous aurons besoin de quelques paquets. Si votre plate-forme est déjà en 32 bits, vous n'aurez pas besoin de la faire fonctionner :
sudo yum install glibc.i686 ncurses-devel.i686
Nous avons presque terminé. Nous allons ajouter les binaires de notre chaîne d'outils dans notre variable PATH :
export PATH=/gcc-arm-none-eabi-4_9-2015q1/bin:$PATH
A ce stade, il ne nous manque aucun élément pour construire l'image. Cependant, nous devrons modifier le Makefile pour pouvoir définir la variable CHIBIOS make en fonction de nos besoins. Il suffit donc de modifier la ligne où la variable CHIBIOS est définie :
# Imported source files and paths
CHIBIOS = ./ChibiOS_2.6.7
include $(CHIBIOS)/boards/ST_STM32L_DISCOVERY/board.mk
include $(CHIBIOS)/os/hal/platforms/STM32L1xx/platform.mk
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32L1xx/port.mk
include $(CHIBIOS)/os/kernel/kernel.mk
include $(CHIBIOS)/test/test.mk
Et nous devrions être capables de construire notre image :
make
L'exemple de Makefile crée un répertoire de compilation dans lequel vous trouverez les fichiers générés par celui-ci. Maintenant, pour fonctionner, le JTAG utilisera OpenOCD :
sudo yum install openocd
OpenOCD fournit les fichiers de configuration nécessaires pour cette carte. Une fois que la carte est connectée à l'ordinateur via le JTAG avec un câble USB, vous pouvez lancer OpenOCD avec :
sudo openocd -f /usr/share/openocd/scripts/interface/ftdi/olimex-arm-usb-tiny-h.cfg -f /usr/share/openocd/scripts/target/stm32l.cfg -c "init" -c "reset"
Le sudo est obligatoire car vous devez accéder au bon noeud de périphérique /dev/usbmon# pour ceux qui sont moins familiers avec linux ou tout système unix d'ailleurs. La sortie doit ressembler à :
Open On-Chip Debugger 0.8.0 (2014-06-07-21:57)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.sourceforge.net/doc/doxygen/bugs.html
Info : only one transport option; autoselect 'jtag'
adapter speed: 100 kHz
adapter_nsrst_delay: 100
jtag_ntrst_delay: 100
cortex_m reset_config sysresetreq
Info : clock speed 100 kHz
Info : JTAG tap: stm32l.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32l.bs tap/device found: 0x06416041 (mfg: 0x020, part: 0x6416, ver: 0x0)
Info : stm32l.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : JTAG tap: stm32l.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Info : JTAG tap: stm32l.bs tap/device found: 0x06416041 (mfg: 0x020, part: 0x6416, ver: 0x0)
Ce qui n'est pas sans rappeler celui que nous avons vu dans le précédent ... Heureusement. Dans mon cas, à ce stade, je pouvais déjà observer le comportement sur l'image puisque la planche avait déjà été utilisée pour le précédent tutoriel. Donc, juste pour le plaisir, "fun" comme dans "assurez-vous que je savais ce que je faisais", j'ai changé le main.c avec le code suivant :
#include "ch.h"
#include "hal.h"
static int fib_array[10] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};static int fibonacci(int);
static int recur_fibonacci(int);
int main(void);
int main(void) {
int base_time = 50;
int incr = 0;
int time = 500;
halInit();
chSysInit();
palSetPadMode(GPIOE, GPIOE_PIN10, PAL_MODE_OUTPUT_PUSHPULL);
while (TRUE) {
if(incr > 8) incr = 0;
time = base_time * fibonacci(incr);
palSetPad(GPIOE, GPIOE_PIN10);
chThdSleepMilliseconds(time);
palClearPad(GPIOE, GPIOE_PIN10);
chThdSleepMilliseconds(500);
++incr;
}
}
static int fibonacci(int n){
// fibonacci sequence is f(n) = f(n-1) + f(n-2)
if(fib_array[n] == -1)
fib_array[n] = recur_fibonacci(n);
return fib_array[n];
}
static int recur_fibonacci(int n){
if(n == 0)
return 1;
if(n == 1)
return 1;
return fibonacci(n-2) + fibonacci(n-1);
}
Le clignotement non linéaire où la phase non éclairée croîtrait proportionnellement à la séquence de Fibonacci. Très apaisant. Sans oublier de recompiler le code, nous sommes prêts à lancer le débogueur pour mettre à jour l'image sur la carte. Nous avons réutilisé exactement le même fichier gdb (openocd.gdb) de l'autre tutoriel recopié ici pour plus de commodité :
target remote localhost:3333
monitor reset halt
monitor wait_halt
monitor sleep 100
monitor poll
monitor flash probe 0
monitor flash write_image erase ./build/ch.bin 0x08000000
monitor sleep 200
monitor soft_reset_halt
monitor wait_halt
monitor poll
symbol-file ./build/ch.elf
thbreak main
continue
You can then launch gdb with the one provided with the toolchain that should still be in your PATH environment variable:
arm-none-eabi-gdb -x openocd.gdb
ce qui devrait déclencher une console gdb interactive qui fera d'abord clignoter la nouvelle image, puis s'arrêtera à la fonction principale de main.c :
GNU gdb (GNU Tools for ARM Embedded Processors) 7.8.0.20150304-cvs
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http: gnu.org="" gpl.html="" licenses="">
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-linux-gnu --target=arm-none-eabi".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http: bugs="" gdb="" software="" www.gnu.org="">.
Find the GDB manual and other documentation resources online at:
<http: documentation="" gdb="" software="" www.gnu.org="">.
For help, type "help".
Type "apropos word" to search for commands related to "word".
0x00000000 in ?? ()
JTAG tap: stm32l.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
JTAG tap: stm32l.bs tap/device found: 0x06416041 (mfg: 0x020, part: 0x6416, ver: 0x0)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000160 msp: 0x20000400
background polling: on
TAP: stm32l.cpu (enabled)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x08000160 msp: 0x20000400
STM32L flash size is 128kb, base address is 0x8000000
flash 'stm32lx' found at 0x08000000
auto erase enabled
wrote 8192 bytes from file ./build/ch.bin in 1.989375s (4.021 KiB/s)
requesting target halt and executing a soft reset
soft_reset_halt is deprecated, please use 'reset halt' instead.
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x01000000 pc: 0x08000160 msp: 0x20000400
background polling: on
TAP: stm32l.cpu (enabled)
target state: halted
target halted due to breakpoint, current mode: Thread
xPSR: 0x01000000 pc: 0x08000160 msp: 0x20000400
Hardware assisted breakpoint 1 at 0x8000102: file main.c, line 9.
Temporary breakpoint 1, main () at main.c:9
9 palSetPad(GPIOE, GPIOE_PIN10);
(gdb)</http:></http:></http:>
Si vous continuez à taper dans le prompt du shell gdb, le clignotement devrait disparaître ! La variation naturelle du clignotement adaptée à la séquence de Fibonacci devrait invariablement vous hypnotiser dans une transe de satisfaction du travail bien fait.
Il est tout aussi facile de jouer avec la carte Olimex STM32-H152 depuis un ordinateur linux avec l'OS temps réel ChibiOS que depuis une éclipse sous windows.