Développement sur stm32

Introduction

Même si le schéma de développement est similaire d'un processeur à un autre, il y a des détails qui sont spécifiques à une famille de processeurs. Il est alors nécessaire de les préciser pour permettre la réutilisation des projets. Ce document présente une méthode et les outils pour le développement du processeur stm32, équipant, entre autres, les modules bluepill et maple-mini-clone.

Environnement de développement

Le développement d'un programme consiste à écrire ou modifier un ou des fichiers texte constitituant les sources du programme, compiler ces sources pour obtenir un fichier binaire contenant le code exécutable, charger ce binaire dans la mémoire du processeur, l'exécuter pour le tester, puis on boucle au début parce que des modifications sont nécessaires. Cette boucle est effectuée un certain nombre de fois jusqu'à obtenir un résultat satisfaisant.

Avant de pouvoir écrire un programme, il faut disposer d'un environnement de développement minimal pour le processeur utilisé, ici le stm32f103. Le modèle présenté ici est valable pour toute autre architecture comme les AVR ou les PIC, seul les ingrédients changent.

Un éditeur de texte

Généralement, on utilise son éditeur de texte préféré, à ne pas confondre avec un traitement de texte. Si on n'en a pas encore, c'est le moment de s'en choisir un, selon son gout personnel en privilégiant un qui vous laissera vous concentrer sur l'écriture du programme plutôt que sur le fonctionnement de l'éditeur lui même.

la commande make

La commande make permet d'exécuter les Makefiles, recette de fabrication des applications, aussi importante que le code. Elle fait déjà partie de votre système, sinon il suffit d'installer le paquet du même nom.

Le compilateur et les outils associés gcc+binutils+newlib

La méthode la plus simple pour installer le compilateur croisé cortex-m3 est de le télécharger le paquet cross-arm-none-eabi si il existe dans votre distribution. Il faudra vérifier qu'il fonctionne correctement, ce qui n'est pas toujours le cas !.

On peut aussi le télécharger sur le site GNU Arm Embedded Toolchain voir [1]. Il s'agit d'un binaire précompilé qui peut ou pas fonctionner sur votre machine et dans ce dernier cas, il est possible de le recompiler à partir des sources et des scripts inclus en suivant le mode d'emploi fourni.

Le compilateur utilisé ici est gcc-arm-none-eabi-7-2018-q2-update de GNU Arm Embedded Toolchain recompilé pour utliser la libc musl

la librairie opencm3

La programmatioon des périphériques du microprocesseur consiste à lire ou écrire des bits ou des champs de bits dans leurs registres de contrôle. La librairie opencm3 est une librairie d'accès spécifique aux processeurs cortex-m3. Elle définit les littéraux correspondand à ces bits et champs de bits ainsi que des fonctions d'accès à ces registres. Vous pouvez la télécharger voir [2]. Il faut ensuite la compiler avec le compilateur installé au paragraphe précédent.

La librarie opencm3 gère plusieurs variantes de processeurs, si on en utilise q'une, on peut en compiler une seule :

export PATH=/home8/gnuarm/arm-none-eabi/bin:${PATH}
TARGETS="stm32/f1" make

scripts ld

Lorsque l'on compile en natif sur une machine Linux, il n'est pas nécessaire de fournir un script ld, parce un script ld par défaut est utilisé.

Pour stm32, il nécessaire d'indiquer à ld, le linker de gcc, par l'intermédiaire d'un script ld les adresses et tailles de la mémoire code et ram. En se basant sur les exemples de opencm3, on definit un fichier script ld stm32-boot-flash.ld pour le binaire du bootloader puis un fichier stm32-app-flash.ld pour le binaire de l'application. Les chiffres dépendent du processeur, ici STM32F103CBT6, et de la taille du bootloader.

Pour le bootloader stm32-boot-flash.ld:

MEMORY
{
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x5000
  rom (rx)  : ORIGIN = 0x08000000, LENGTH = 0x20000
}

Pour l'application stm32-app-flash.ld:

MEMORY
{
  ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x5000
  rom (rx)  : ORIGIN = 0x08002000, LENGTH = 0x1E000
}

Normalement le Makefile, prend en charge le script stm32-app-flash.ld, pour utiliser un autre, il faut l'indiquer dans le Makefile avec la variable LDSCRIPT.

LDSCRIPT = $(shell where-sdk stm32)/ld/stm32-boot-flash.ld

Autres alternatives

Il existe d'autre façons de faire par exemple en installant un IDE (integrated development environment) ou l'interface du fabricant. Ils apportent, en général, une couche d'occultation suplémentaire et donc de complexité qui n'est pas nécessaire à ce stade. La connaissance du micro, nécessaire pour son utilisation, s'acquiert exclusivement par la lecture de la datasheet du fabricant et requiert déjà un effort important et ce genre d'outils n'apportent rien pour cela.

Organisation du développement

Chaque projet se fait dans un répertoire regroupé dans un répertoire prj. Cela simplifie les recherches, les sauvegardes, n'introduit pas des fichiers encombrants non relatifs aux projets.

Dans chaque projet on trouve les fichiers spécifiques au projet plus des liens symboliques sur les fichiers communs comme cela on a tout sous la main et pour consulter un projet la commande ls suffit, doncpas besoin d'un outil graphique qui génère une hierarchie de répertoires à 10 niveaux avec un fichier dans chaque répertoire !.

Chaque projet contient un Makefile, spécifique au projet, qui inclus un Makefile.include specifique à l'architecture et peut être à l'organisation de la macine. Ce dernier Makefile inclus Makefile.rules qui spécifie les règles pour l'architecture.

Lorsque l'on crée une archive les fichiers sont copiés, ce qui fait disparaitre les liens symboliques. Si c'est juste pour une compilation ce n'est pas bien grave, mais pour reprendre un développement il faudrait revoir l'organisation.

Dans une archive, on trouve un fichier where-sdk que vous devrez sans doute modifier pour indiquer ou se trouve votre compilateur.

On trouve aussi un fichier nextit pour modifier l'itération du binaire que vous mettez en flash.

On trouve aussi un fichier mkstmsym script perl pour créer à chaque compilation un fichier de symboles utilisé par le terminal de pgrm pour vous permettre de lire et modifier les registres et les variables globales.

Au démarrage, le code émet la chaine gt 0 (get time) sur la liaison série. Si le terminal de gprm est connecté, il répond t 1543560634 qui a pour effet de mettre à l'heure le montage. Le nombre donné est la date courante au format Unix equivalent à date "+s".

Il est aussi posible de passer à pgrm des arguments qui seront transmis avec l'heure et interprêté comme commande, comme par exemple, changer la valeur de la variable verbose.

Références

  1. Pre-built GNU toolchain from ARM Cortex-M & Cortex-R processors.
  2. libopencm3 - Open Source ARM cortex m microcontroller library.