Eclipse - GCC ARM - STM32 - La retour de la vengeance

Petite mise à jour sur le développement sur STM32.

Il y a maintenant deux ans (... putain c'est loin) j'avais fait un petit article qui introduisait l'installation d'Eclipse et l'utilisation basique de la lib standard ST.

Pas mal d'eau a coulé sous les ponts depuis, et après avoir fait quasiment uniquement de l'électronique analogique, je vais me remettre à la commande numérique, j'ai donc remis en place une chaine de dev. Et, honnêtement, tout est plus simple maintenant. En cherchant sur googoo j'ai trouvé quelques sites qui ont fait ce genre de listes de chaînes d'outils pour STM32/ARM, mais soit c'est trop vieux, soit c'est orienté vers des solutions proposées par le site en question. Genre ça qui a les deux inconvénients : trop vieux, proposent une solution à eux.

Je ne vais pas forcément m'étendre dans les détails sur chaque choix de chaîne de dev, je vais juste faire la liste des méthodes que j'ai rencontré ces derniers temps, et dire ce que j'en pense.

TL;DR : c'est toujours autant la merde pour trouver un setup qui marche, à chaque fois ya un truc qui va pas, ou ça ne marche pas pour une raison inconnue. Hautement frustrant. Seule planche de salut (selon moi) : CubeIDE.

Compilateur payant

Solution Roxxor, c'est ce que j'utilise au taff, IAR pour ne pas le citer. Ça fait le job, mais c'est trop cher pour du hobby.

Licence d'évaluation d'un compilateur payant

Par exemple KEIL est dispo en licence d'évaluation, limité à 32k de code. Au passage, l'on remarquera que cette limitation rend quasiment impossible l'utilisation de Mbed ... Perso je ne suis pas trop pour, les limitations je tombe dedans, avec la chance que j'ai ... Mais je connais des ens qui l'utilisent, et qui arrivent à faire des choses étonnantes avec, donc ce n'est pas à jeter. C'est juste pas adapté pour moi.

Mbed

Mon avis n'a pas changé : trop lourd (C++ ...), trop buggé (incompatibilités entre périphériques dus à l'implémentation des méthodes), trop obscur, trop contraignant. Je suis content qu'il ait existé pour me permettre de jouer il y a 4-5 ans, mais maintenant il me faut quelque chose de sérieux et fiable.

GCC-arm-non-eabi + makefile

Mon avis n'a pas changé : je préfère courir tout nu dans un réacteur nucléaire plutôt qu'avoir à nouveau à essayer de compiler un projet ARM en ligne de commande.

Eclipse

Oui c'est la facilité, oui Java c'est de la merde, je sais. Mais au moins ça marche et je comprends ce que ça fait.

La donne a pas mal changé depuis deux ans, et il y a de nouvelles options intéressantes.

AC6 - System Workbench / OpenSTM32

Cette option est toujours dispo, c'est un Eclipse re-packagé et pré-configuré, avec ce qu'il faut pour générer un projet de base sur une carte d'éval sans trop se faire chier; et le fait qu'il y ait les cartes Nucleo "intégrées" directement à la création du projet. Ça marche toujours bien, mais ça impose de faire un compte sur leur site ... moyen-moyen pour un truc qui s'appelle "OPEN" STM32. C'est pas l'idéal, mais c'est toujours plus fiable que Mbed.

A noter que j'arrive à faire du debug avec sous Windows. Sous Linux ça merde, voir mes déboires avec GDB / OpenOCD plus bas.

A récupérer ici:

https://www.st.com/en/development-t...

http://www.openstm32.org/System+Wor...

Attolic Truestudio / CubeIDE

Une autre alternative, équivalente à System-Workbench. C'est aussi un Eclipse repackagé, avec la même contrainte de créer un compte, ou plutôt laisser son mail pour un petit supplément de spam.

Ca a récemment été racheté par ST, qui l'a packagé directement avec CubeMX, ce qui donne CubeIDE. Comme tous les téléchargements ST, il faut un compte sur leur site, rien de plus. C'est toujours gratuit, non-limité, et ça prend toujours autant de place (700Mo de base + les packages par famille).

A récupérer ici:

Attolic Trustudio - Annoncé deprecated, forcément maintenant c'est CubeIDE qui remplace.

https://www.st.com/content/st_com/e...

GNU MCU Eclipse

Le nouveau nom de GNU ARM Eclipse. Ça peut s'installer comme un plugin d'Eclipse, aucune inscription requise. Et, contrairement à ce que j'en pensais du temps que ça s’appelait GNU ARM Eclipse, aujourd'hui ça fonctionne ! Par contre, il n'y a pas de pré-configuration pour les cartes d'éval, Nucleo et DISCO, donc il faut configurer les pins soit-même. Leur site est très bien documenté par ailleurs.

Le vrai point noir, c'est que tous les modèles de MCUs ne sont pas proposés dans les template de projets. Par exemple, il n'y a pas les F1xx, uniquement les F0xx, et il n'y a pas les F33x ... C'est con, parce que je comptais bien utiliser les Nucleo en STM32F152 et STM32F334 ! Donc ... Pas utilisable tel quel.

A récupérer ici:

https://gnu-mcu-eclipse.github.io/

CubeMX

Oui je sais, c'est de la merde, ça génère du code dégueulasse. Mais ça permet de générer des exemples de code à peu près fonctionnel avec le HAL, ce qui est toujours ça de pris, vu à quel point le HAL est compliqué. Ne serait-ce que configurer les horloges, si ya moyen de le faire graphiquement, j'achète ! Et ça permet de vérifier les incompatibilités entre périphériques, ce qui n'est pas du luxe, tant il n'est pas trivial de les identifier. Et il y a des pièges, en plus, donc autant profiter de toutes les aides disponibles. D'ailleurs c'est un des griefs principaux que je fais à Mbed : il génère du code qui ne marche pas du fait d'incompatibilité entre périphériques ... dus à des choix d'implémentation dans Mbed, et qui ne sont détectable que par essai-erreur. La joie, la joie, la joie (plus jamais). C'est bon, j'ai assez bitché sur Mbed ?

On peut installer CubeMX comme un plugin à Eclipse plutôt qu'en stand-alone, donc ça peut venir en complément de GNU MCU ... Bien penser à le configurer pour qu'il génère un projet avec makefile, et pas un projet pour EWARM ou KEIL ou autre. Après, dans Eclipse, on peut ouvrir le projet en faisant New/Makefile project with existing code. Ou alors juste lire le code et prendre ce qui est intéressant dedans.

A noter que les projets CubeMX sont chiants à importer dans Eclipse sous Windows, il y a même des gens qui ont fait des scripts en Python qui font la conversion automatique, sinon c'est trop chiant à faire à la main ... Ce n'est forcément trivial, voir ici. Sous Linux ça se passe assez bien, vu qu'il va retrouver automatiquement les chemins vers gnu-arm-none-eabi et le projet compile direct.

A noter que les packages dont il a besoin pour les différentes familles de MCU prennent une place démentielle. Genre j'avais téléchargé juste STM32F4 et STM32F7 et j'en était déjà à 8Go de libs ! C'est totalement délirant ! Ce qui fait que j'ai du le virer et installer le standalone plutôt que le plugin, parce que comme Eclipse est sur un disque un peu plein ça me le bourrait totalement et Windows n'a pas trop aimé ...

A récupérer ici:

https://www.st.com/en/development-t...

Et CubeIDE alors ? Ça donne quoi ?

Après tous les déboires que j'ai eu avec les autres méthodes (voir la suite), je me suis penché sur celle-là. Ça se choppe donc ici, il y a des versions pour Windows, Mac et Linux, ça s'installe en un package, c'est totalement monolithique, et de ce que j'ai essayé, ça juste marche. Aujourd'hui, c'est la seule solution que j'ai qui fonctionne dans tous les cas et me permet de débuguer. Ce n'est pas tellement une surprise, même si ST ne nous avait pas forcément habitué à des outils aussi fonctionnels.

Il faut juste un compte sur le site de ST, mais 1) de toutes façons pour les libs standard il en faut un, donc cc'est difficile de ne pas y passer et 2) niveau spam ça va, je reçois une newsletter toutes les 3-4 semaines, c'est pas la mort.

Seul vrai problème que je vois pour le moment : je n'ai pas trouvé comment changer le chemin du repository pour les libs, même en installant CubeIDE sur un disque autre que C il me met encore les libs des familles de composants dans C, et si je change le chemin il me met un message d'erreur. C'est hautement pénible.

En-dehors de cela ... En fait c'est la solution la plus efficace que j'ai trouvé. Ça s'installe pas moins bien que les autres, voire même plus facilement, et ça juste marche. La compilation marche, le debug aussi, CubeMX permet de configurer rapidement les horloges et les périphériques sans se taper 300 pages de docs (même s'il faut quand-même mettre un peu le nez dedans, ne serait-ce que pour l'assignation des signaux d'horloges aux périphériques), on peut créer un projet pour une carte Discovery ou Nucleo ça instancie direct les bons GPIO ... ça juste marche ! Depuis que je l'ai installé je n'utilise plus que ça, tout autre chaîne me semble insupportable en comparaison.

Alors, oui, c'est pas vraiment libre, oui. Et ça bouffe un max de place sur le disque, oui. Mais j'en ai tellement marre de me battre contre les outils, je choisis celui-là.

Tiens, je viens de regarder ça : portage de Chocolate Doom sur Discovery STM32F429. J'ai fait un clone du repository, dans CubeIDE File->New->Makefile Project With Existing Code, je lui indique le dossier du git, il trouve le makefile, il reconstruit l'arborescence, je fais Build ... Et ça build, hassle-free, rien à configurer en plus, pas de message d'erreur à la con, le bonheur.

Nuttx

Celui-là ça fait un bout de temps que j'en entend parler, surtout par des membres du Lab qui l'utilisent. C'est un OS temps-réel open-source et libre, qui intègre plein de configs toutes-faites pour plein de MCUs ST. Autant le côté libre, open-source me plait bien, autant le côté OS m'embête un peu. Je n'ai pas trop envie de m'encombrer d'une usine à gaz, vu ce que je veux faire et vu les processeurs que je vise. Néanmoins il semble qu'il y ait des choses intéressantes à y récupérer, ne serait-ce que de la doc, et certains modules qui ont l'air intéressants. En particulier le shell, qui a ses propres libs et exemples spécifiques, qui s'appelle NuttShell. Le reprendre pourrait m'éviter de devoir coder entièrement un interpréteur pour faire du remote ... Si tant est que j'arrive à le reprendre. C'est sans doute totalement inadapté par rapport à ce que je veux faire.

Si je devais l'utiliser vraiment, ce qui m'embête aussi c'est qu'il n'est pas compatible avec les STM32F1xx.

Après, c'est vraiment un OS, avec un prompt (le fameux NuttShell), sur lequel on va lancer des applications. Donc c'est sans doute un peu (beaucoup) overkill pour ce que je veux faire avec mes pédales. Par contre, si je devais faire un truc un peu plus costaud, genre ma matrice de switch d'effets avec écran LCD à base de DISCO STM32F746NG, ça ne serait peut-être pas idiot de m'en servir. En tout cas ça serait surement pas plus con con que d'utiliser Mbed. Pour le moment ... C'est un peu trop "next level shit" pour moi.

http://www.nuttx.org/

Doc de NuttShell:

http://www.nuttx.org/doku.php?id=do...

Étendons nous un peu sur Nuttx, vu que j'ai décidé de jouer un peu avec. La documentation est, disons, laconique. On trouve quelques tutoriels, parmi ceux qui ne renvoient pas un 404 j'en ai essayé plusieurs, dont celui-ci qui utilise Qemu mais ne propose pas de compiler quoi que ce soit (le binaire est fourni), ce qui permet tout de même de jouer avec NuttShell sans avoir la carte-cible. Celui-ci avec lequel j'ai pu compiler Nutx sur plusieurs cibles, pour voir ce que ça donne. Ca permet de voir les étapes à suivre pour générer un binaire pour une cible donnée, et accessoirement ça m'a forcé à nettoyer mes repos Debian, qui étaient bloqués à cause d'un package foireux, ce qui m'empêchait d'installer les outils requis. Quelques remarques tout de même:

  • Pour la carte cible qu'ils donnent, aucun problème, même avec Debian Buster, et sans choisir la version de GCC qu'il préconise. Après, je n'ai pas la carte, donc je n'ai pas pu flasher pour vérifier si le binaire est fonctionnel ... En tous cas ça a généré un binaire.
  • Pour reset la config et changer de cible il faut faire un make dist-clean dans la racine du répertoire nuttx.
  • J'ai essayé de compiler pour la Nucleo-F334R8, vu que je l'avais sur mon bureau :P Cette carte est supportée j'ai donc juste changé la cible ./configure.sh nucleo-f334r8/nsh. Ca a planté au make, au link plus précisément, il me dit qu'il y a des sections qui s'overlappent. Je suppose qu'il y a une config à modifier pour cette carte, à moins que le MCU n'ait pas assez de flash ou de RAM pour encaisser NuttShell, et qu'il faudrait que je comile sans NuttShell ? Je demanderai conseil à un confrère du Lab pour avoir son avis, car je suis assez surpris de ce comportement.
  • J'ai essayé de compiler sur la Disco STM32F746NG, qui est supportée elle aussi, donc ./configure.sh stm32f746g-disco/nsh. Là il a généré le binaire, je suis donc allé au bout de la connerie et j'ai chargé avec openocd. A noter qu'il propose de recompiler, alors qu'il est dans les repos Debian, donc je ne sais pas trop si c'est nécessaire ou si un aptitude install openocd n'est pas suffisant. Toujours est-il que j'ai recompilé openocd avec les options qu'il donne pour être sûr de moi. Il y a une subtilité quand on lance openocd, il faut lui indiquer que c'est un STlink v2-1, et pas STlink v2 tout court, ce qui le fait planter. Ce qui donne sudo openocd -f interface/stlink-v2-1.cfg -c "set WORKAREASIZE 0x2000" -f target/stm32f7x.cfg -c "program nuttx verify reset exit" (ne pas oublier aussi de changer la famille de MCU pour STM32F7). Ca a visiblement chargé le binaire sur la carte, par contre je n'ai rien sur le terminal série.
  • Pour savoir quels sont les interfaces et les cibles disponibles dans openocd, il faut regarder dans /usr/share/openocd/scripts/interface et /usr/share/openocd/scripts/target (info que j'ai trouvé ici).
  • Dans le tuto il utilise un adaptateur USB-série, je me suis dit que j'allais plutôt me connecter directement sur le VCOM du STlink, mais aucun prompt :( Je me suis connecté sur /dev/ttyACM0 (qui est le port COM du STlink tel qu'il apparait dans Debian, pour info) en 115200 bds (il dit que c'est la fréquence par défaut), et en 9600 bds, mais rien de rien, pas de NuttShell. Bigre ... Soit j'ai foiré la génération du binaire et il est daubé, soit NuttShell est mappé sur un autre port série de la carte (sur ce site ils parlent de USART6, il faut que j'essaye avec un adaptateur USB-série). Je sors donc mon adaptateur USB-série FTDI en 3.3V, je mets le TX (orange) sur PC7 (USART6 RX, CN4-1) et le RX (jaune) sur PC6 (USART6 TX, CN4-2), et la masse, ça marche mieux avec la masse, sudo screen /dev/ttyUSB0 115200. Et là bingo :) J'ai le prompt qui s'affiche. Une grosse victoire après tous mes déboires avec les STM32 sous Debian :P Maintenant il faut que je teste d'autres trucs, genre un exemple avec de l'affichage, ça serait cool ! Mais j'ai l'impression que le LCD de cette carte n'est pas supporté actuellement (le contrôleur en tous cas n'apparait pas dans les options disponibles), donc je vais me renseigner, et voir ce qu'on peut faire raisonnablement.

Dans cet autre tuto il est expliqué comment ajouter le répertoire de Nuttx dans Eclipse. Sous Windows ça merdoie parce qu'il ne trouve pas la chaine de build - vu qu'il suit les makefile et qu'ils sont plutôt faits pour du Linux ça ne m'étonne pas trop, par contre sous Debian avec Photon ça a l'air de marcher, ça me génère un binaire. Encore une fois, je n'ai pas encore pu tester s'il est valide, il faut que je le fasse.

Globalement, pour le moment je ne sais pas trop quoi en penser, j'ai un mal fou à avoir un setup fonctionnel. Néanmoins, ça m'a forcé à me sortir les doigts et cleaner mon install de Debian, ce qui quand-même appréciable. Un mal pour un bien.

Debugger avec Eclipse sous Debian

Très honnêtement je ne comprends pas comment il faut configurer Eclipse sous Debian pour arriver à debug. J'ai des bouts de trucs qui marchent, mais je n'arrivent pas à tout faire coucher ensemble. Quand je cherche sur le net, je trouve des trucs contradictoires, mais surtout je trouve que la plupart des gens qui font du debug avec Eclipse sur les STM32 sont sous Windows ... Misère ... EN tous cas, à chaque fois j'arrive PRESQUE à faire marcher le debug, mais ya un truc qui merde à la fin et qui fait que le debug se plante.

A priori il y a deux voies : GDB ou OpenOCD.

GDB

Je n'ai pas trop compris si on pouvait utiliser GDB "vanilla", ou s'il fallait la version arm-none-eabi.

Pour le arm-none-eabi-gdb je n'ai pas trop compris car dans le bin il y n'y a pas de arm-none-eabi-gdb équivalent à arm-none-eabi-gcc. Et dans les repos on trouve gdb-arm-none-eabi, mais je ne trouve pas exécutable ... WTF ?

Toujours est-il que quand je créé une config de debug dans Eclipse avec GDB ou arm-none-eabi-gdb, je n'arrive pas à entrer en debug, ça me met un message d'erreur.

J'ai suivi ce tuto.

Il utilise un outil st-util, que j'avais d'installé, mais je ne sais pas trop si c'est par les package st-link ou via autre chose. Bref, lancer st-util me dit qu'il arrive à se connecter à la carte: ~$ st-util
st-util 1.5.1
2019-08-18T15:02:52 INFO common.c: Loading device parameters....
2019-08-18T15:02:52 INFO common.c: Device connected is: F334 device, id 0x10016438
2019-08-18T15:02:52 INFO common.c: SRAM size: 0x3000 bytes (12 KiB), Flash: 0x10000 bytes (64 KiB) in pages of 2048 bytes
2019-08-18T15:02:52 INFO gdb-server.c: Chip ID is 00000438, Core ID is 2ba01477.
2019-08-18T15:02:52 INFO gdb-server.c: Listening at *:4242...

C'est bon signe ! Quand je créé la configuration Run dans Eclipse et que je le lance, idem, il me dit qu'il se connecte. Puis je lance la session de debug, et là ça devient bizarre, il me dit qu'il n'a pas d'info de debug, alors que je le fais pointer sur l'elf. Chelou ... Dans tous les cas ça ne marche pas, bien que j'ai l'impression que je suis proche du but !

Openocd

J'ai déjà vu que j'arrivais à télécharger le binaire avec openocd. J'ai créé une config avec Openocd comme indiqué ici. Ça plante avec le message suivant :

Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Error: Debug adapter does not support any transports? Check config file order.
Error: unable to select a session transport. Can't continue.
shutdown command invoked

Si je lance st-util avant -> idem. Grmpf ...

Je suis tombé sur un site assez bien foutu, en fraçais de surcroît, qui explique comment utiliser OpenOCD et GDB. Ce n'est pas exhaustif, mais ça m'a permis d'avancer.

Suite des essais, avec une carte Nucleo-f746ZG : J'ai ajouté une règle dans udev pour la gestion du debugger, suivant ce site. Un coup de lsusb (avec la carte connectée, sinon ça ne sert à rien) pour vérifier le numéro d'ID de ma carte, qui est - bien entendu - différent ceux proposés par ce site, donc j'ai aussi ajouté une ligne pour le numéro d'ID que ma carte renvoie : ATTR{idProduct}=="374b", ATTR{idVendor}=="0483", MODE="666", GROUP="plugdev"
Puis un coup de sudo service udev restart

Donc, connection en ligne de commande avec openOCD : sudo openocd -f /usr/share/openocd/scripts/interface/stlink-v2-1.cfg -f /usr/share/openocd/scripts/target/stm32f7x.cfg

Boom, la connection se fait, cool :)

Ensuite je me connecte dessus soit avec gdb, en donnant le lien de l'elf, ou alors en Telnet avec Putty (ouy autre) : ça marche aussi, j'arrive à Halt, reset, run, lire les registres ... Donc ça marche.

Retour sous Eclipse, erreur : Truncated register 16 in remote 'g' packet

Même en lançant Openocd en ligne de commande et en disant à Eclipse de ne pas le lancer (décocher "Start Openocd locally" dans la config de debug, onglet "Debugger"), idem. En cherchant sur le net, ça parle de bug, de mise à jour du firmware de la carte (ce que j'ai fait, même sous linux ça se passe sans souci, voir ici) ... Rien à faire, ça ne passe pas, Eclipse n'arrive pas à se connecter à la carte. Bigre ... Pourtant ça marche en ligne de commande ! J'ai essayé avec la version Neon d'Eclipse (plus ancienne, là j'étais avec Photon), pareil.

Ca m'a gonflé, j'ai abandonné.

Conclusion

  • IDE / compilateur payant : trop cher mon fils ...
  • Version d'évaluation d'un IDE / compilateur payant : trop limité.
  • MBED : trop lourd, trop buggé, trop relou.
  • CubeMX : oui c'est dégueulasse et pas optimisé, mais ça génère du caode qui permet de comprendre comment initialiser les périphériques, ça permet de vérifier les conflits ... C'est du temps gagné mine de rien. Donc je ne vais pas le rejeter.
  • AC6 / System Workbench : fonctionne, mais est chiant à installer (il faut faire un compte sur le site d'AC6 ...), et ne permet pas d'initialiser grand-chose. Mais fonctionne.
  • Atollic / CubeIDE : pour l'instant la seule solution qui fonctionne - dans mon cas d'usage en tous cas. Permet d'utiliser le code généré par CubeMX, permet de débugger, facile à installer. Ça juste marche, je prends.
  • Nuttx : il faut que je plonge plus profondément dedans, ça a l'air intéressant, mais c'est assez hostile je trouve ...
  • Linux : il y a toujours un truc qui merde. La génération des binaires se passe bien et est plus robuste que sous Windows - je trouve - par contre c'est le debug qui merde, OpenOCD, st-util et GDB ne couchent pas bien avec Eclipse, ce qui est bloquant pour moi (j'ai déjà donné le dev sans debug avec Mbed, merci bien).

Donc je vais passer à court-terme sous CubeIDE. C'est la facilité, ouais, mais j'ai besoin d'avancer, j'ai déjà passé des jours entiers pour trouver un setup fonctionnel, c'est juste ridicule et j'en ai ras-les-bottes.

Ajouter un rétrolien

URL de rétrolien : http://blog.randagodron.eu/index.php?trackback/75

Haut de page