<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wiki.electroniciens.cnrs.fr/index.php?action=history&amp;feed=atom&amp;title=Les_Groupes_ARM_%3A_STM32%2Ftoolchain_sous_Linux</id>
	<title>Les Groupes ARM : STM32/toolchain sous Linux - Historique des versions</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.electroniciens.cnrs.fr/index.php?action=history&amp;feed=atom&amp;title=Les_Groupes_ARM_%3A_STM32%2Ftoolchain_sous_Linux"/>
	<link rel="alternate" type="text/html" href="https://wiki.electroniciens.cnrs.fr/index.php?title=Les_Groupes_ARM_:_STM32/toolchain_sous_Linux&amp;action=history"/>
	<updated>2026-04-14T19:55:40Z</updated>
	<subtitle>Historique des versions pour cette page sur le wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://wiki.electroniciens.cnrs.fr/index.php?title=Les_Groupes_ARM_:_STM32/toolchain_sous_Linux&amp;diff=4863&amp;oldid=prev</id>
		<title>David.picard : /* En mode release */</title>
		<link rel="alternate" type="text/html" href="https://wiki.electroniciens.cnrs.fr/index.php?title=Les_Groupes_ARM_:_STM32/toolchain_sous_Linux&amp;diff=4863&amp;oldid=prev"/>
		<updated>2021-07-13T13:51:12Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;En mode release&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nouvelle page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;div&amp;gt;[[Accueil]] - [[Les_Groupes_ARM|ARM]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;hr/&amp;gt;&lt;br /&gt;
&amp;lt;div&amp;gt;[[Les_Groupes_ARM_:_ArmADEUS|ArmADEUS]] - [[Les_Groupes_ARM_:_STM32|Cortex M3/M4 et le STM32]] - [[Les_Groupes_ARM_:_STM32/toolchain_sous_Linux| Toolchain sous linux pour STM32]] - [[Les_Groupes_ARM_:_A13-micro|Olinuxino A13-micro]] - [[Les_Groupes_ARM_:_Raspberry_Pi|Raspberry Pi]] - [[Les_Groupes_ARM_:_Eukréa|Eukréa]] - [[Les_Groupes_ARM_:_LabVIEW|LabVIEW]] - [[Les_Groupes_ARM_:_GCC|GCC]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;hr/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= Objectif =&lt;br /&gt;
&lt;br /&gt;
Il existe de nombreuses combinaisons d&amp;#039;outils pour développer sur des STM32.&lt;br /&gt;
La méthode présentée ici n&amp;#039;est qu&amp;#039;une solution parmi d&amp;#039;autres.&lt;br /&gt;
Les outils logiciels sont tous gratuits et la plupart est libre.&lt;br /&gt;
L&amp;#039;outil matériel pour programmer (in-circuit debugger) coûte environ 12€.&lt;br /&gt;
&lt;br /&gt;
Cette page explique comment programmer et débugger les STM32 sous Linux avec les outils suivants :&lt;br /&gt;
* Configurateur graphique [https://www.st.com/en/development-tools/stm32cubemx.html STM32CubeMX]&lt;br /&gt;
* Compilateur GNU GCC + débugger GNU GDB&lt;br /&gt;
* IDE [https://fr.wikipedia.org/wiki/Qt_Creator Qt Creator]&lt;br /&gt;
* [http://openocd.org/ OpenOCD], the Open On-Chip Debugger&lt;br /&gt;
* In-circuit debugger ST-Link V2 (par exemple celui d&amp;#039;une carte de démo Nucleo-64 à 10€ env.)&lt;br /&gt;
&lt;br /&gt;
Cette méthode permet de compiler, programmer et débugger le code (points d&amp;#039;arrêt, valeur des variables, etc.).&lt;br /&gt;
Une fois configurée, le confort d&amp;#039;utilisation est excellent, a fortiori si on est familier de Qt Creator.&lt;br /&gt;
&lt;br /&gt;
= Installer la toolchain =&lt;br /&gt;
&lt;br /&gt;
== STM32CubeMX ==&lt;br /&gt;
&lt;br /&gt;
STM32CubeMX est un logiciel pour générer le code d&amp;#039;initialisation : horloges, timers, interruptions, périphériques (I2C, SPI, etc.)...&lt;br /&gt;
&lt;br /&gt;
Pour configurer un proxy, menu Help &amp;gt; Updater settings &amp;gt; Connection parameters.&lt;br /&gt;
&lt;br /&gt;
Télécharger sur https://my.st.com (créer un compte). Extraire l&amp;#039;archive et lancer le programme d&amp;#039;&lt;br /&gt;
    $ sudo ./SetupSTM32CubeMX-&amp;lt;version&amp;gt;.linux&lt;br /&gt;
&lt;br /&gt;
Le répertoire d&amp;#039;installation par défaut est /usr/local/. Créer un alias (modifier &amp;lt;tt&amp;gt;PATH&amp;lt;/tt&amp;gt; ne marche pas), par exemple dans &amp;lt;tt&amp;gt;~/.bashrc&amp;lt;/tt&amp;gt; ou dans &amp;lt;tt&amp;gt;~/.bash_aliases&amp;lt;/tt&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
    alias stm32cubemx=&amp;#039;/usr/local/STMicroelectronics/STM32Cube/STM32CubeMX/STM32CubeMX&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Menu Help &amp;gt; Install new libraries et choisir celles qui correspondent au composant sur lequel on développe.&lt;br /&gt;
&lt;br /&gt;
== OpenOCD ==&lt;br /&gt;
&lt;br /&gt;
=== Installation depuis le code source ===&lt;br /&gt;
&lt;br /&gt;
C&amp;#039;est l&amp;#039;[http://openocd.org/about/ Open On-Chip Debugger]. Il permet de programmer le MCU et de débugger (points d&amp;#039;arrêt, valeur des variables), en lien avec gdb.&lt;br /&gt;
&lt;br /&gt;
La version de la distribution Linux est peut-être trop ancienne pour supporter les STM32. Dans ce cas, il faut télécharger le code source et le compiler.&lt;br /&gt;
&lt;br /&gt;
Installer le paquet pkg-config :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ apt-get install pkg-config&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Télécharger et sélectionner la dernière version stable :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ~/opt&lt;br /&gt;
$ git clone git://git.code.sf.net/p/openocd/code openocd&lt;br /&gt;
$ cd openocd&lt;br /&gt;
$ git tag                         // lister les tags de versions&lt;br /&gt;
$ git checkout v0.11.0            // sélectionner la dernière version stable&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Compiler :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ ./bootstrap&lt;br /&gt;
$ ./configure --enable-stlink --disable-werror&lt;br /&gt;
$ make -j4&lt;br /&gt;
$ sudo make install&lt;br /&gt;
$ which openocd&lt;br /&gt;
/usr/local/bin/openocd&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
L&amp;#039;option --disable-werror est nécessaire en cas d&amp;#039;erreur de compilation avec gcc v7+.&lt;br /&gt;
&lt;br /&gt;
Mettre à jour :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cd ~/opt/openocd&lt;br /&gt;
$ make clean                      // nettoyer une éventuelle version précédente&lt;br /&gt;
$ git pull                        // intégrer les derniers changements&lt;br /&gt;
$ git tag                         // lister les tags de versions&lt;br /&gt;
$ git checkout v0.11.0            // sélectionner la dernière version stable&lt;br /&gt;
$ git checkout &amp;lt;tag_de_la_nouvelle_version_stable&amp;gt;&lt;br /&gt;
$ make clean&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Puis refaire l&amp;#039;étape &amp;quot;compiler&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pour tester, connecter soit une carte Nucleo avec les jumpers ST-Link installés, soit une carte Nucleo avec les jumpers ST-Link enlevés et connectée à une carte maison via le connecteur CN4 (SWD). Ctrl+C pour quitter).&lt;br /&gt;
&lt;br /&gt;
=== Utilisation ===&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important :&amp;#039;&amp;#039;&amp;#039; avant de lancer OpenOCD, il faut connecter une carte sur un port USB du PC hôte, sinon il quitte immédiatement avec le message &amp;lt;tt&amp;gt;Error: open failed&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Lancer OpenOCD dans un terminal, et le laisser tourner pendant qu&amp;#039;on utilise Qt Creator.&lt;br /&gt;
On peut se connecter au serveur OpenOCD via telnet dans un autre terminal et lui envoyer des commandes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ sudo openocd -s /usr/local/share/openocd/scripts/target/ -f interface/stlink.cfg -c &amp;quot;transport select hla_swd&amp;quot; -f target/stm32l4x.cfg&lt;br /&gt;
Open On-Chip Debugger 0.11.0-dirty (2021-07-06-11:05)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
	http://openocd.org/doc/doxygen/bugs.html&lt;br /&gt;
hla_swd&lt;br /&gt;
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD&lt;br /&gt;
Info : Listening on port 6666 for tcl connections&lt;br /&gt;
Info : Listening on port 4444 for telnet connections&lt;br /&gt;
Info : clock speed 500 kHz&lt;br /&gt;
Info : STLINK V2J28M17 (API v2) VID:PID 0483:374B&lt;br /&gt;
Info : Target voltage: 3.229746&lt;br /&gt;
Info : stm32l4x.cpu: hardware has 6 breakpoints, 4 watchpoints&lt;br /&gt;
Info : starting gdb server for stm32l4x.cpu on 3333&lt;br /&gt;
Info : Listening on port 3333 for gdb connections&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Créer &amp;lt;tt&amp;gt;/usr/local/bin/oocd.sh&amp;lt;/tt&amp;gt; pour lancer cette ligne de commande :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
&lt;br /&gt;
OOCD_DIR=/usr/local/share/openocd/scripts/target/&lt;br /&gt;
&lt;br /&gt;
# Avec ST-Link V2 :&lt;br /&gt;
#openocd -f interface/stlink-v2.cfg -c &amp;quot;transport select hla_swd&amp;quot; -f target/stm32l4x.cfg&lt;br /&gt;
# Avec ST-Link V2-1 (Nucleo) :&lt;br /&gt;
openocd -s ${OOCD_DIR} -f interface/stlink.cfg -c &amp;quot;transport select hla_swd&amp;quot; -f target/stm32l4x.cfg&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Donner les permissions d&amp;#039;exécution au script :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo chmod a+x /usr/local/bin/openocd-stm32l4x&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Références :&lt;br /&gt;
* https://www.hackster.io/yusefkarim/upload-code-to-stm32l4-using-linux-gnu-make-and-openocd-a3d4de&lt;br /&gt;
&lt;br /&gt;
== gcc ==&lt;br /&gt;
&lt;br /&gt;
Visiter https://launchpad.net/gcc-arm-embedded et sous &amp;quot;Series and milestones&amp;quot;, choisir la version sur le graphe des branches de développement. Si les fichiers ne sont pas disponibles, un lien indique où les trouver (https://developer.arm.com/open-source/gnu-toolchain/gnu-rm). gdb fourni avec cette distribution a le support Python, requis par Qt Creator.&lt;br /&gt;
Extraire l&amp;#039;archive :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$ sudo tar -xf gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2 -C /usr/local/&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Qt Creator ==&lt;br /&gt;
&lt;br /&gt;
=== Plugins ===&lt;br /&gt;
&lt;br /&gt;
Le menu &amp;#039;&amp;#039;Help &amp;gt; About plugins&amp;#039;&amp;#039; affiche une boîte de dialogue. Vérifier que les plugins suivants sont installés :&lt;br /&gt;
* QbsProjectManager (inutile si vous utilisez CMake)&lt;br /&gt;
* BareMetal&lt;br /&gt;
&lt;br /&gt;
=== OpenOCD ===&lt;br /&gt;
&lt;br /&gt;
Dans le menu Tools &amp;gt; Options &amp;gt; Devices &amp;gt; Bare metal, cliquer Add puis OpenOCD.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Paramètre !! Valeur&lt;br /&gt;
|-&lt;br /&gt;
| Name || OpenOCD&lt;br /&gt;
|-&lt;br /&gt;
| Startup mode || No startup&lt;br /&gt;
|-&lt;br /&gt;
| Host || localhost:3333&lt;br /&gt;
|-&lt;br /&gt;
| Init commands || set remote hardware-breakpoint-limit 6&amp;lt;br&amp;gt;&lt;br /&gt;
set remote hardware-watchpoint-limit 4&amp;lt;br&amp;gt;&lt;br /&gt;
monitor reset halt&amp;lt;br&amp;gt;&lt;br /&gt;
load&amp;lt;br&amp;gt;&lt;br /&gt;
monitor reset halt&lt;br /&gt;
|-&lt;br /&gt;
| Reset commands || monitor reset halt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Dans le menu Tools &amp;gt; Options &amp;gt; Devices &amp;gt; Devices, créer un device avec le GDB server provider défini plus haut.&lt;br /&gt;
&lt;br /&gt;
Créer un kit avec le compilateur, le debugger, le device bare metal.&lt;br /&gt;
&lt;br /&gt;
=== Kit ===&lt;br /&gt;
&lt;br /&gt;
* Compilateur C : &amp;lt;tt&amp;gt;arm-none-eabi-gcc&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Compilateur C++ : &amp;lt;tt&amp;gt;arm-none-eabi-g++&amp;lt;/tt&amp;gt;&lt;br /&gt;
* Debugger : &amp;lt;tt&amp;gt;arm-none-eabi-gdb-py&amp;lt;/tt&amp;gt;&lt;br /&gt;
* System CMake at &amp;lt;tt&amp;gt;/usr/bin/cmake&amp;lt;/tt&amp;gt; ou celui fourni avec Qt, qui est souvent plus récent.&lt;br /&gt;
&lt;br /&gt;
CMake configuration :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;CMake&amp;quot;&amp;gt;&lt;br /&gt;
CMAKE_CXX_COMPILER:STRING=%{Compiler:Executable:Cxx}&lt;br /&gt;
CMAKE_C_COMPILER:STRING=%{Compiler:Executable:C}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Si au moment d&amp;#039;ajouter GDB, Qt Creator indique &amp;quot;not recognized&amp;quot;, essayer de lancer GDB dans un terminal pour voir quelle est l&amp;#039;erreur.&lt;br /&gt;
S&amp;#039;il lui manque libncurses (&amp;#039;&amp;#039;error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory&amp;#039;&amp;#039;) :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ sudo apt install libncurses5&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Puis fermer/relancer Qt Creator.&lt;br /&gt;
&lt;br /&gt;
= Matériel =&lt;br /&gt;
&lt;br /&gt;
== ST-Link ==&lt;br /&gt;
&lt;br /&gt;
La procédure expliquée sur cette page peut être appliquée de 2 manières :&lt;br /&gt;
* avec une carte Nucleo64 : on programme le STM32 qui est dessus via le ST-Link de la carte connectée au PC en USB&lt;br /&gt;
* avec une carte Nucleo64 et une carte maison : on programme le STM32 qui est sur la carte maison via le ST-Link de la carte Nucleo64, connectée au PC en USB&lt;br /&gt;
&lt;br /&gt;
Pour programmer une carte maison avec le ST-Link d&amp;#039;une carte [https://www.st.com/en/evaluation-tools/nucleo-l476rg.html Nucleo64], souder R9 (boîtier 0603, de 1K à 47K) et dessouder SB12 (jumper NRST, face de dessous). Enlever les 2 jumpers sur CN2, et connecter la carte maison à CN4 (SWD).&lt;br /&gt;
&lt;br /&gt;
== Carte maison ==&lt;br /&gt;
&lt;br /&gt;
Voici un [[:File:Stm32-stlink.pdf|schéma]] exemple pour dessiner une carte maison, programmable avec le module ST-Link présent sur une carte Nucleo64.&lt;br /&gt;
&lt;br /&gt;
= Utilisation =&lt;br /&gt;
&lt;br /&gt;
== Support du MCU ==&lt;br /&gt;
&lt;br /&gt;
Pour choisir les options du compilateur/linker, voir dans le répertoire d&amp;#039;installation de GCC, le tableau dans &amp;lt;code&amp;gt;/share/doc/gcc-arm-none-eabi/readme.txt&amp;lt;/code&amp;gt;, sous &amp;quot;Architecture options usage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Par exemple, pour un Cortex-M4 avec une FPU (floating point processing unit), les options de GCC sont :&lt;br /&gt;
* soft FP : &amp;lt;code&amp;gt;-mthumb -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;hard FP&amp;#039;&amp;#039;&amp;#039; : &amp;lt;code&amp;gt;-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Les STM32L4 ont une FPU  matérielle. La deuxième ligne est donc à privilégier.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important :&amp;#039;&amp;#039;&amp;#039; ces options doivent être passées à la compilation ET à l&amp;#039;édition de liens. Pour cela, LD ne doit pas être appelé directement, mais via le driver de GCC.&lt;br /&gt;
&lt;br /&gt;
== Générer le code d&amp;#039;initialisation ==&lt;br /&gt;
&lt;br /&gt;
STM32CubeMX permet de générer le code d&amp;#039;initialisation du MCU :&lt;br /&gt;
* fonction attribuée à chaque broche&lt;br /&gt;
* configuration des horloges&lt;br /&gt;
* configuration des interruptions&lt;br /&gt;
* configuration des middlewares (USB, CAN, etc.)&lt;br /&gt;
&lt;br /&gt;
STM32CubeMX a un gestionnaire pour télécharger les librairies ST.&lt;br /&gt;
Il existe 2 types de librairies : HAL, de haut niveau, et LL (low-level) de plus bas niveau.&lt;br /&gt;
La première est plus simple d&amp;#039;utilisation, mais est moins efficace que la seconde.&lt;br /&gt;
&lt;br /&gt;
STM32CubeMX propose de faire un lien vers les libraries, ou de les copier dans le projet.&lt;br /&gt;
La 2ème solution permet une maintenance plus facile du projet sur le long terme.&lt;br /&gt;
&lt;br /&gt;
Une fois le projet configuré, on peut générer le code.&lt;br /&gt;
* Pour Qbs, choisir &amp;#039;&amp;#039;SW4STM32&amp;#039;&amp;#039; pour Toolchain/IDE et cocher la case &amp;#039;&amp;#039;Generate under root&amp;#039;&amp;#039;.&lt;br /&gt;
* Pour CMake, choisir &amp;#039;&amp;#039;Makefile&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Le code généré contient des balises BEGIN/END en commentaire (à ne surtout pas toucher !) pour insérer le code utilisateur.&lt;br /&gt;
Le code entre ces balises est préservé si le code est généré de nouveau avec STM32CubeMX, pour par exemple, changer une configuration.&lt;br /&gt;
Par exemple, pour faire clignoter la LED LD2 de la Nucleo-64 avec une période de 1 s, modifier main.c :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=C&amp;gt;&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
  /* some code here */&lt;br /&gt;
&lt;br /&gt;
  /* Infinite loop */&lt;br /&gt;
  /* USER CODE BEGIN WHILE */&lt;br /&gt;
  while (1)&lt;br /&gt;
  {&lt;br /&gt;
    /* USER CODE END WHILE */&lt;br /&gt;
&lt;br /&gt;
    /* USER CODE BEGIN 3 */&lt;br /&gt;
    HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);&lt;br /&gt;
    HAL_Delay(500);&lt;br /&gt;
  }&lt;br /&gt;
  /* USER CODE END 3 */&lt;br /&gt;
&lt;br /&gt;
  /* some code here */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Projet Qbs ==&lt;br /&gt;
&lt;br /&gt;
Dans Qt Creator, créer un nouveau projet (non-Qt application, C application). Sélectionner le kit défini précédemment, et cliquer sur &amp;#039;&amp;#039;Configure project&amp;#039;&amp;#039;. Ajouter le fichier Qbs ci-dessous au projet.&lt;br /&gt;
&lt;br /&gt;
[https://doc.qt.io/qbs/ Qbs] (prononcer &amp;quot;cubes&amp;quot;) est un outil fourni avec Qt Creator pour simplifier la compilation et épargner l&amp;#039;écriture de makefiles.&lt;br /&gt;
Il est appelé à disparaître car il sera remplacé par [https://cmake.org/ CMake], qui est un standard libre.&lt;br /&gt;
En attendant, voici un exemple de fichier Qbs à adapter.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=C&amp;gt;&lt;br /&gt;
import qbs&lt;br /&gt;
&lt;br /&gt;
CppApplication {&lt;br /&gt;
    consoleApplication: true&lt;br /&gt;
    property string family: &amp;quot;STM32L4xx&amp;quot;&lt;br /&gt;
    property string linkerScript: &amp;quot;STM32L476RGTx_FLASH.ld&amp;quot;&lt;br /&gt;
    cpp.positionIndependentCode: false              // make sure option -fPIC is not passed to GCC&lt;br /&gt;
&lt;br /&gt;
    // Make sure to call the linker through GCC driver :&lt;br /&gt;
    cpp.linkerMode: &amp;quot;manual&amp;quot;        // default : &amp;quot;automatic&amp;quot;&lt;br /&gt;
    cpp.linkerName: &amp;quot;gcc&amp;quot;           // this string is appended to &amp;quot;&amp;lt;full_path_to_toolchain&amp;gt;/arm-none-eabi-&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    // Define some symbols (GCC -D flag)&lt;br /&gt;
    cpp.defines: [&lt;br /&gt;
        &amp;quot;USE_HAL_DRIVER&amp;quot;,&lt;br /&gt;
        &amp;quot;STM32L476xx&amp;quot;,&lt;br /&gt;
        &amp;quot;__weak=__attribute__((weak))&amp;quot;,&lt;br /&gt;
        &amp;quot;__packed=__attribute__((__packed__))&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    // Options for compilation AND linking.&lt;br /&gt;
    cpp.driverFlags: [&lt;br /&gt;
        // CPU&lt;br /&gt;
        &amp;quot;-mcpu=cortex-m4&amp;quot;,&lt;br /&gt;
        &amp;quot;-mthumb&amp;quot;,&lt;br /&gt;
        &amp;quot;-mfpu=fpv4-sp-d16&amp;quot;,&lt;br /&gt;
        &amp;quot;-mfloat-abi=hard&amp;quot;,&lt;br /&gt;
        &amp;quot;-specs=nano.specs&amp;quot;,                  // use smaller libc&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    // Compiler flags for all langages (C, C++).&lt;br /&gt;
    cpp.commonCompilerFlags: [&lt;br /&gt;
        // Optimizations&lt;br /&gt;
//        &amp;quot;-Os&amp;quot;,&lt;br /&gt;
//        &amp;quot;-O0&amp;quot;,&lt;br /&gt;
        &amp;quot;-Og&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;-Wall&amp;quot;,&lt;br /&gt;
        &amp;quot;-fdata-sections&amp;quot;,&lt;br /&gt;
        &amp;quot;-ffunction-sections&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        // For debug&lt;br /&gt;
        &amp;quot;-g&amp;quot;,&lt;br /&gt;
        &amp;quot;-gdwarf-2&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;-c&amp;quot;,                                       // don&amp;#039;t run the linker&lt;br /&gt;
//        &amp;quot;-v&amp;quot;                                      // print a whole lot of details&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    // Linker flag only i.e. understood by LD !!!&lt;br /&gt;
    // Qbs will prepend all these flags with &amp;quot;-Wl,&amp;quot; so that GCC transfers them to LD.&lt;br /&gt;
    // Other options required for linking should be set in the driverFlags section.&lt;br /&gt;
    cpp.linkerFlags: [&lt;br /&gt;
        &amp;quot;-T&amp;quot;+path+&amp;quot;/&amp;quot;+linkerScript,&lt;br /&gt;
        &amp;quot;-static&amp;quot;,&lt;br /&gt;
        &amp;quot;--verbose&amp;quot;,                                // displays library search&lt;br /&gt;
        &amp;quot;-lc&amp;quot;,&lt;br /&gt;
        &amp;quot;-lm&amp;quot;,&lt;br /&gt;
        &amp;quot;-lnosys&amp;quot;,&lt;br /&gt;
        &amp;quot;-Map=&amp;quot;+buildDirectory+&amp;quot;/memory.map&amp;quot;,       // file created at the end of the link step&lt;br /&gt;
        &amp;quot;--cref&amp;quot;,                                   // map file formatting&lt;br /&gt;
        &amp;quot;--gc-sections&amp;quot;,                            // fixes &amp;quot;undefined reference to _exit&amp;quot; error&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    // Include directories.&lt;br /&gt;
    cpp.includePaths: [&lt;br /&gt;
        &amp;quot;Inc&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/CMSIS/Include&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/CMSIS/Device/ST/&amp;quot;+family+&amp;quot;/Include&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/STM32L4xx_HAL_Driver/Inc&amp;quot;,&lt;br /&gt;
        &amp;quot;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc&amp;quot;,&lt;br /&gt;
        &amp;quot;Middlewares/ST/STM32_USB_Device_Library/Core/Inc/&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    // Source files.&lt;br /&gt;
    files: [&lt;br /&gt;
        &amp;quot;Inc/*.h&amp;quot;,&lt;br /&gt;
        linkerScript,&lt;br /&gt;
        &amp;quot;Src/*.c&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/CMSIS/Device/ST/&amp;quot;+family+&amp;quot;/Include/*.h&amp;quot;,&lt;br /&gt;
        &amp;quot;startup/*.s&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/CMSIS/Device/ST/&amp;quot;+family+&amp;quot;/Source/Templates/*.c&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/CMSIS/Include/*.h&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/&amp;quot;+family+&amp;quot;_HAL_Driver/Inc/*.h&amp;quot;,&lt;br /&gt;
        &amp;quot;Drivers/&amp;quot;+family+&amp;quot;_HAL_Driver/Src/*.c&amp;quot;,&lt;br /&gt;
        &amp;quot;Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/*.c&amp;quot;,&lt;br /&gt;
        &amp;quot;Middlewares/ST/STM32_USB_Device_Library/Core/Src/*.c&amp;quot;&lt;br /&gt;
    ]&lt;br /&gt;
&lt;br /&gt;
    Properties {&lt;br /&gt;
        condition: qbs.buildVariant === &amp;quot;debug&amp;quot;&lt;br /&gt;
        cpp.defines: outer.concat([&amp;quot;DEBUG=1&amp;quot;])&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    Group {     // Properties for the produced executable&lt;br /&gt;
        fileTagsFilter: product.type&lt;br /&gt;
        qbs.install: true&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Projet CMake ==&lt;br /&gt;
&lt;br /&gt;
Si on a généré le code avec STM32CubeMX en choisissant &amp;#039;&amp;#039;Makefile&amp;#039;&amp;#039;, un fichier &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; est créé.&lt;br /&gt;
Ce fichier contient tout ce qu&amp;#039;il faut pour écrire le fichier de config de CMake, &amp;lt;tt&amp;gt;CMakeLists.txt&amp;lt;/tt&amp;gt; :&lt;br /&gt;
* liste des .c&lt;br /&gt;
* liste des répertoires à inclure&lt;br /&gt;
* les defines pour &amp;lt;tt&amp;gt;target_compile_definitions()&amp;lt;/tt&amp;gt;&lt;br /&gt;
* les options de compilation pour &amp;lt;tt&amp;gt;target_compile_options()&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Avant de commencer, renommer &amp;lt;tt&amp;gt;Makefile&amp;lt;/tt&amp;gt; en &amp;lt;tt&amp;gt;Makefile.STM32CubeMX&amp;lt;/tt&amp;gt; pour éviter que la compilation du fichier CMake ne l&amp;#039;écrase.&lt;br /&gt;
&lt;br /&gt;
Voici un &amp;lt;tt&amp;gt;CMakeLists.txt&amp;lt;/tt&amp;gt;, à adapter selon le MCU, en s&amp;#039;aidant du Makefile généré par STM32CubeMX.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;CMake&amp;quot;&amp;gt;&lt;br /&gt;
# Board : nucleo64-stm32l476rg&lt;br /&gt;
&lt;br /&gt;
cmake_minimum_required(VERSION 3.15.3)&lt;br /&gt;
&lt;br /&gt;
# Skip toolchain check&lt;br /&gt;
# Useful if CMake fails with error &amp;quot;The C compiler is not able to compile a simple test program&amp;quot;.&lt;br /&gt;
set(CMAKE_C_COMPILER_WORKS 1)&lt;br /&gt;
set(CMAKE_CXX_COMPILER_WORKS 1)&lt;br /&gt;
&lt;br /&gt;
project(L4_blinky_cmake)&lt;br /&gt;
&lt;br /&gt;
enable_language(C ASM)&lt;br /&gt;
set(CMAKE_C_STANDARD 99)&lt;br /&gt;
set(CMAKE_C_STANDARD_REQUIRED ON)&lt;br /&gt;
set(CMAKE_C_EXTENSIONS OFF)&lt;br /&gt;
&lt;br /&gt;
set(STM32CUBEMX_GENERATED_FILES&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;Core/Src/main.c&amp;quot;&lt;br /&gt;
    &amp;quot;Core/Src/stm32l4xx_it.c&amp;quot;&lt;br /&gt;
    &amp;quot;Core/Src/stm32l4xx_hal_msp.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_tim_ex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart_ex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_i2c_ex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_rcc_ex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_flash_ramfunc.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_gpio.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_dma_ex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_pwr_ex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_cortex.c&amp;quot;&lt;br /&gt;
    &amp;quot;Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_exti.c&amp;quot;&lt;br /&gt;
    &amp;quot;Core/Src/system_stm32l4xx.c&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;startup_stm32l476xx.s&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
set(EXECUTABLE ${PROJECT_NAME}.out)&lt;br /&gt;
&lt;br /&gt;
add_executable(${EXECUTABLE} ${STM32CUBEMX_GENERATED_FILES})&lt;br /&gt;
&lt;br /&gt;
target_include_directories(${EXECUTABLE} PRIVATE&lt;br /&gt;
    Core/Inc&lt;br /&gt;
    Drivers/STM32L4xx_HAL_Driver/Inc&lt;br /&gt;
    Drivers/STM32L4xx_HAL_Driver/Inc/Legacy&lt;br /&gt;
    Drivers/CMSIS/Device/ST/STM32L4xx/Include&lt;br /&gt;
    Drivers/CMSIS/Include&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
target_compile_definitions(${EXECUTABLE} PRIVATE&lt;br /&gt;
    -DUSE_HAL_DRIVER&lt;br /&gt;
    -DSTM32L476xx&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
set(MCU&lt;br /&gt;
    -mcpu=cortex-m4&lt;br /&gt;
    -mthumb&lt;br /&gt;
    -mfpu=fpv4-sp-d16&lt;br /&gt;
    -mfloat-abi=hard&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
target_compile_options(${EXECUTABLE} PRIVATE&lt;br /&gt;
    ${MCU}&lt;br /&gt;
&lt;br /&gt;
    -fdata-sections&lt;br /&gt;
    -ffunction-sections&lt;br /&gt;
&lt;br /&gt;
    -Wall&lt;br /&gt;
&lt;br /&gt;
    $&amp;lt;$&amp;lt;CONFIG:Debug&amp;gt;:-Og&amp;gt;		# add -g if debug is selected&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
target_link_options(${EXECUTABLE} PRIVATE&lt;br /&gt;
    -T${CMAKE_SOURCE_DIR}/STM32L476RGTx_FLASH.ld&lt;br /&gt;
    ${MCU}&lt;br /&gt;
    -specs=nano.specs&lt;br /&gt;
    -lc&lt;br /&gt;
    -lm&lt;br /&gt;
    -lnosys&lt;br /&gt;
    -Wl,-Map=${PROJECT_NAME}.map,--cref&lt;br /&gt;
    -Wl,--gc-sections                   # fixes &amp;quot;undefined reference to _exit&amp;quot; error&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
# Get the path to the toolchain&lt;br /&gt;
if(CMAKE_VERSION VERSION_LESS &amp;quot;3.20&amp;quot;)&lt;br /&gt;
    get_filename_component(TOOLCHAIN_PATH ${CMAKE_C_COMPILER} DIRECTORY)&lt;br /&gt;
else()&lt;br /&gt;
    cmake_path(GET CMAKE_C_COMPILER ROOT_PATH TOOLCHAIN_PATH)&lt;br /&gt;
endif()&lt;br /&gt;
message(STATUS &amp;quot;Toolchain path: ${TOOLCHAIN_PATH}&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
# Print executable size&lt;br /&gt;
add_custom_command(TARGET ${EXECUTABLE}&lt;br /&gt;
    POST_BUILD&lt;br /&gt;
    COMMAND echo &amp;quot;Target size:&amp;quot;&lt;br /&gt;
    COMMAND ${TOOLCHAIN_PATH}/arm-none-eabi-size ${EXECUTABLE}&lt;br /&gt;
    )&lt;br /&gt;
&lt;br /&gt;
# Create all necessary files to flash the MCU from the command line.&lt;br /&gt;
# Only relevant in Release mode.&lt;br /&gt;
if(CMAKE_BUILD_TYPE STREQUAL &amp;quot;Release&amp;quot;)&lt;br /&gt;
    message(STATUS &amp;quot;Build type: Release&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    # Create bin and hex file&lt;br /&gt;
    add_custom_command(TARGET ${EXECUTABLE}&lt;br /&gt;
        POST_BUILD&lt;br /&gt;
        COMMAND ${TOOLCHAIN_PATH}/arm-none-eabi-objcopy -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin&lt;br /&gt;
        COMMAND ${TOOLCHAIN_PATH}/arm-none-eabi-objcopy -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
    # Concatenate 2 OpenOCD config files into one, into the build directory.&lt;br /&gt;
    add_custom_command(TARGET ${EXECUTABLE}&lt;br /&gt;
        POST_BUILD&lt;br /&gt;
        COMMAND cat /usr/local/share/openocd/scripts/interface/stlink.cfg /usr/local/share/openocd/scripts/target/stm32l4x.cfg &amp;gt; ${PROJECT_NAME}.cfg&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
    # Create a Bash script in the build directory to flash the MCU from the command line.&lt;br /&gt;
    # The script must be run as ROOT !&lt;br /&gt;
    file(WRITE &amp;quot;${CMAKE_BINARY_DIR}/flash.sh&amp;quot;&lt;br /&gt;
        &amp;quot;#!/bin/bash\n\nopenocd -f ${PROJECT_NAME}.cfg -c \&amp;quot;init; reset halt; stm32l4x mass_erase 0; program ${PROJECT_NAME}.bin reset exit 0x08000000\&amp;quot;&amp;quot;&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
    # Set script permissions.&lt;br /&gt;
    file(CHMOD &amp;quot;${CMAKE_BINARY_DIR}/flash.sh&amp;quot;&lt;br /&gt;
        FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_WRITE GROUP_EXECUTE WORLD_READ WORLD_EXECUTE&lt;br /&gt;
        )&lt;br /&gt;
&lt;br /&gt;
endif()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Référence :&lt;br /&gt;
* https://dev.to/younup/cmake-on-stm32-the-beginning-3766&lt;br /&gt;
&lt;br /&gt;
Autres références :&lt;br /&gt;
* https://www.bartslinger.com/qtcreator/stm32cubemx-cmake-and-qtcreator/&lt;br /&gt;
* https://github.com/ObKo/stm32-cmake&lt;br /&gt;
&lt;br /&gt;
== Programmer le STM32 ==&lt;br /&gt;
&lt;br /&gt;
=== En mode debug ===&lt;br /&gt;
&lt;br /&gt;
# Connecter la carte Nucleo-64 (avec le ST-Link V2) au PC (USB).&lt;br /&gt;
# Dans un terminal, lancer OpenOCD via le script écrit plus haut en tant que root.&lt;br /&gt;
# Dans Qt Creator&lt;br /&gt;
## configurer le projet en mode debug&lt;br /&gt;
## taper Ctrl+R (run) pour compiler, programmer, et exécuter le code sur la cible.&lt;br /&gt;
&lt;br /&gt;
Et voilà !&lt;br /&gt;
&lt;br /&gt;
=== En mode release ===&lt;br /&gt;
&lt;br /&gt;
Bien qu&amp;#039;au moment de lancer le programme (Ctrl+R : flasher + exécuter) sur la cible en mode Release, Qt Creator affiche un warning &amp;quot;This does not seem to be a Debug build&amp;quot;, &amp;#039;&amp;#039;&amp;#039;le MCU est bel et bien programmé&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
Mais on peut aussi le programmer en ligne de commande grâce à CMake et au script &amp;lt;tt&amp;gt;flash.sh&amp;lt;/tt&amp;gt; généré par CMake.&lt;br /&gt;
Voir la doc de CMake.&lt;br /&gt;
Utile si on ne veut pas lancer Qt Creator.&lt;br /&gt;
&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Stopper OpenOCD&amp;#039;&amp;#039;&amp;#039; s&amp;#039;il est lancé dans un terminal (Ctrl+C).&lt;br /&gt;
# Dans Qt Creator, configurer le projet en mode release.&lt;br /&gt;
# Compiler (Ctrl+B).&lt;br /&gt;
# Ouvrir un terminal dans le &amp;#039;&amp;#039;&amp;#039;répertoire de compilation&amp;#039;&amp;#039;&amp;#039; (qui en général n&amp;#039;est pas celui du source).&lt;br /&gt;
# Exécuter &amp;lt;tt&amp;gt;$ sudo ./flash.sh&amp;lt;/tt&amp;gt;, le script créé par CMake.&lt;br /&gt;
&lt;br /&gt;
Ce script concatène 2 fichiers de config d&amp;#039;OpenOCD, puis efface/programme le STM32.&lt;br /&gt;
Il est équivalent aux 2 commandes ci-dessous.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Bash&amp;quot;&amp;gt;&lt;br /&gt;
$ cat /usr/local/share/openocd/scripts/interface/stlink.cfg /usr/local/share/openocd/scripts/target/stm32l4x.cfg &amp;gt; myboard.cfg&lt;br /&gt;
$ sudo openocd -f myboard.cfg -c &amp;quot;init; reset halt; stm32l4x mass_erase 0; program L4_blinky_cmake.bin reset exit 0x08000000&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Erreurs connues =&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;object_file&amp;#039;&amp;#039; uses VFP register arguments, &amp;#039;&amp;#039;target&amp;#039;&amp;#039; does not&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Incompatibilité de FPU entre le code utilisateur et les libraries liées (&amp;#039;&amp;#039;-mfloat-abi=hard&amp;#039;&amp;#039; vs. &amp;#039;&amp;#039;-mfloat-abi=softfp&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039; Le programme compile mais bloque dans un error handler.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Vérifier que LD n&amp;#039;est pas appelé directement, mais via le driver de GCC. Vérifier que la ligne de commande de GCC au moment de la compilation ET au moment de l&amp;#039;édition de liens contient bien les options qui définissent le MCU  et la libc : &amp;lt;tt&amp;gt;-mcpu=cortex-m4, -mthumb, -mfpu=fpv4-sp-d16, -mfloat-abi=hard, -specs=nano.specs&amp;lt;/tt&amp;gt;.&lt;/div&gt;</summary>
		<author><name>David.picard</name></author>
	</entry>
</feed>