Logo Spiria

Développement embarqué ARM sous ChibiOS/RT avec un microcontrôleur STM32-H152 d’Olimex

20 juin 2014.

Within the framework of an embedded development project for one of our customers, we had to set up an ARM embedded development environment under ChibiOS/RT with an STM32-H152 microcontroller from Olimex in order to meet their needs and complete the project. The following article is a tutorial on the steps we had to take in order to have everything in place to proceed with the development of the embedded solution.

Matériel utilisé

 

STM32-H152 d’Olimex

olimex st32-h152

Le choix du microcontrôleur pour ce projet s’est arrêté sur le STM32-H152 d’Olimex car il correspondait aux besoins particuliers de notre client. Il s’agit d’un circuit intégré de développement à faible coût basé sur la série de processeurs STM32L de STMicroelectronics. Le processeur ARM Cortex-M3 se démarque par sa très faible consommation d’énergie et supporte plusieurs interfaces de communication telle qu’USB, USART, SPI et I2C. Il intègre 128K octets de mémoire flash, 16K octets de mémoire RAM, en plus d’offrir un pilote LCD 8x40 segments, 80 GPIO et une horloge de 32MHz. Bref, une petite merveille!

ARM-USB-TINY-H d’Olimex

decorative

Nous avons choisi d’utiliser le débogueur ARM USB JTAG à cause de son faible coût et parce qu’il fonctionne avec OpenOCD (logiciel libre). Il offre également une vitesse de programmation (copie vers mémoire flash) rapide sous USB 2.0.

Préparation de l’environnement de développement

Bien qu’il soit possible et facile de mettre en place un environnement de développement ARM en logiciel libre sous Linux et Mac OS X, cet article se concentre sur la configuration sous Windows 7 seulement. Il existe plusieurs solutions commerciales pour faire du développement ARM, mais nous avons choisi d’y aller avec la solution Eclipse (CDT), OpenOCD, YAGARTO et Zylin.

Olimex permet de simplifier la configuration en offrant une suite de développement nommée Olimex ODS et basée sur OpenOCD. Si vous êtes déjà familier avec l’environnement de développement intégré Eclipse, vous apprécierez de ne pas avoir à apprendre un nouvel outil.

Eclipse

Un des environnements de développement intégré les plus utilisés au monde. La version 0.9 de la suite de développement propose la version Helios avec C/C++ Developer Tooling (CDT) d’Eclipse.

YAGARTO (Yet Another GNU Arm Toolchain)

YAGARTO contient tous les outils nécessaires pour compiler (GCC) et déboguer (GDB) avec l’architecture ARM.

Zylin Embedded CDT

Il s’agit d’une extension en logiciel libre qui permet de faire le pont entre OpenOCD et Eclipse.

OpenOCD

Open On-Chip Debugger (OpenOCD) est un outil pour programmer les circuits ARM supportant différents adaptateurs JTAG via USB (incluant notre débogueur ARM-USB-OCD-H).

Installation d’Olimex ODS

L’installation de la suite de développement est fort simple. Il suffit de télécharger l’installateur à l’adresse suivante et de suivre les instructions.

Nous allons revenir plus tard avec quelques étapes de configuration particulières qui sont nécessaires afin de transférer le binaire dans la mémoire flash et pour déboguer.

ChibiOS/RT

Il existe plusieurs options intéressantes pour le choix d’un système d’exploration temps réel (RTOS). Certains sont commerciaux et propriétaires (Windows CE, VxWorks) tandis que d’autres sont en logiciel libre et gratuit (RTLinux, FreeRTOS). Notre choix s’est arrêté sur ChibiOS/RT principalement à cause de sa petite taille, de sa vitesse pour le changement de contexte et sa portabilité. Notons également son excellent support pour l’architecture ARM.

http://www.chibios.org/

ChibiOS/RT est utilisé en production dans le domaine de l’automobile, la robotique et la gestion de l’énergie entre autres. Il est bien documenté et présente plusieurs exemples afin d’accélérer l’apprentissage. Pour développer avec ChibiOS, il suffit de télécharger la dernière version stable et de décompresser les fichiers dans un endroit facile d’accès.

ChibiOS fonctionne sous forme de sous-systèmes grâce à des pilotes que l’on peut activer selon nos besoins. En voici quelques-uns:

  • ADC (Analog to Digital Converter)
  • CAN (Controller Area Network)
  • GPT (General Purpose Timer)
  • HAL (Hardware Abstraction Layer)
  • I2C (Inter-Integrated Circuit)
  • MAC (Media Access Control)
  • SDC (Secure Digital Card)
  • SPI (Serial Peripheral Interface)
  • USB (Universal Serial Bus)

Exemple simple

Le code source suivant démontre un exemple simple, mais classique, qui ne fait que clignoter la LED rouge (PIN 10 de la banque E) sur le STM32-H152 toutes les secondes.


#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);
  }
}

C’est ce code que nous allons utiliser pour poursuivre la configuration de notre environnement.

Création d’un nouveau projet dans Eclipse et compilation

La première étape consiste à créer un nouveau projet dans Eclipse. Pour se faire, il suffit de créer un projet C (File → New → C Project), de lui donner un nom et de sélectionner le type Makefile / Empty Project avec Other Toolchain.

Ensuite, il est conseillé d’importer un projet déjà existant parmi ceux disponibles dans la distribution de ChibiOS/RT. Les exemples sont légers et contiennent peu de code et ils peuvent servir de squelette pour la création d’un nouveau projet. Donc, dans le cas du STM32-H152, nous avons tout simplement importé l’exemple nommé ARMCM3-STM32L152-DISCOVERY présent dans le dossier « demos » (clic droit sur le projet → Import… → File System). Ensuite, il faut sélectionner les fichiers de l’exemple en excluant les dossiers « iar » et « keil ».

decorative

Une fois que le projet est créé, vous aurez la structure suivante.

decorative

Les liens des dossiers « board », « os » et « test » doivent être modifiés afin de pointer vers ceux qui sont contenus dans le dossier de ChibiOS (clic droit sur le dossier → Properties… → Location Edit…).

Si ce n’est pas déjà fait, il faut ajouter le chemin des outils YAGARTO dans la variable d’environnement PATH comme ci-dessous. Dans notre cas, les exécutables étaient installés dans C:\OlimexODS\yagarto\bin.

decorative

Étant donné qu’il s’agit d’une copie d’un exemple existant, il faut également modifier le fichier Makefile du projet afin d’ajuster la valeur de la variable CHIBIOS pour qu’elle pointe au bon endroit comme dans la figure suivante.


# Imported source files and paths
CHIBIOS = C:\Users\jprimeau\Documents\ChibiOS_2.6.3
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

La dernière étape consiste à copier le code source de notre exemple simple que nous avons vu un peu plus tôt et de remplacer le contenu du fichier main.c provenant de l’exemple importé. Nous sommes maintenant prêts à compiler l’application embarquée (Project → Build). Cette action produira un fichier « build\ch.bin » qui pourra être copié sur la mémoire flash du processeur STM32.

decorative

Configuration et lancement d’OpenOCD

Maintenant que nous avons compilé le code source avec succès, il faut ajouter une configuration pour un outil externe afin de faciliter le lancement d’une instance d’OpenOCD (Run → External Tools → External Tools Configuration) et d’ajouter une configuration comme ci-dessous.

decorative

Dans notre cas, les arguments nécessaires pour spécifier la bonne cible pour le STM32-H152 et la bonne interface pour le JTAG ARM-USB-TINY-H étaient les suivants.


-f C:\OlimexODS\openocd-0.6.1\scripts\interface\olimex-arm-usb-tiny-h.cfg -f C:\OlimexODS\openocd-0.6.1\scripts\target\stm32l.cfg -c "init" -c "reset"

Copie du binaire et débogage sur le STM32-H152

Premièrement, il est nécessaire de créer une configuration de débogage pour le projet (Run → Debug Configurations…). Cette configuration doit être de type « Zylin Embedded debug (Native) ». Dans l’onglet « Debugger », il faut faire pointer le champ « GDB Debugger » vers le GDB de YAGARTO. Dans notre cas, le chemin était C:\OlimexODS\yagarto\bin\arm-none-eabi-gdb.exe.

decorative

Finalement, il faut spécifier un script d’initialisation pour GDB afin qu’il se connecte à l’instance d’OpenOCD (port 3333 sur localhost). Ce même script copiera l’image (binaire) sur la mémoire flash du microcontrôleur pour finalement mettre un point d’arrêt dans la fonction main.

Dans notre cas, le script pour copier le binaire sur le microcontrôleur et pour provoquer un arrêt dans la fonction main était le suivant.


target remote localhost:3333 
monitor reset halt 
monitor wait_halt 
monitor sleep 100 
monitor poll 
monitor flash probe 0 
monitor flash write_image erase /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.bin 0x08000000 
monitor sleep 200 
monitor soft_reset_halt
monitor wait_halt 
monitor poll
symbol-file /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.elf
thbreak main 
continue

Une fois que tout est en place, il ne suffit que de lancer une instance d’OpenOCD (Run → External Tools → OpenOCD) et de lancer une instance de GDB (Run → Debug).

Lancement de l’instance d’OpenOCD :


Open On-Chip Debugger 0.6.1 (2012-10-07-10:34)
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_m3 reset_config sysresetreq
Info : max TCK change to: 30000 kHz
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)

Lancement de l’instance de GDB :


target remote localhost:3333 
0x00000000 in ?? ()
monitor reset halt 
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: 0x08000120 msp: 0x20000400
monitor wait_halt 
monitor sleep 100 
monitor poll 
background polling: on
TAP: stm32l.cpu (enabled)
target state: halted
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000120 msp: 0x20000400
monitor flash probe 0 
flash size = 128kbytes
flash 'stm32lx' found at 0x08000000
monitor flash write_image erase /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.bin 0x08000000 
auto erase enabled
wrote 8192 bytes from file /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.bin in 2.195126s (3.644 KiB/s)
monitor sleep 200 
monitor soft_reset_halt
requesting target halt and executing a soft reset
target state: halted
target halted due to breakpoint, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000120 msp: 0x20000400
monitor wait_halt 
monitor poll
background polling: on
TAP: stm32l.cpu (enabled)
target state: halted
target halted due to breakpoint, current mode: Thread 
xPSR: 0x01000000 pc: 0x08000120 msp: 0x20000400
symbol-file /Users/jprimeau/Documents/workspace/STM32-H152/build/ch.elf
thbreak main 
Hardware assisted breakpoint 1 at 0x8001822: file main.c, line 5.
continue

Le résultat

Si tout a fonctionné comme prévu, vous devriez être en mesure de voir la LED rouge clignoter toutes les secondes comme c’est le cas dans la photo suivante. Félicitations! Vous venez de faire du développement embarqué pour une architecture ARM sur un microcontrôleur en utilisant un système d’exploitation temps réel!

decorative

Conclusion

Nous avons débuté par faire un survol du matériel utilisé pour ce tutoriel pour enchainer avec la préparation de l’environnement de développement et de la présentation de ChibiOS/RT. Nous avons ensuite créé un projet de développement embarqué pour ChibiOS dans Eclipse à partir d’un exemple et nous avons procédé à sa compilation pour terminer avec les étapes nécessaires à la configuration d’OpenOCD et de Zylin.