J'ai profité de mes vacances de fin d'année pour (enfin) terminer un projet que j'avais entamé ... il y a quasiment 3 ans maintenant

Il n'y a pas énormément de module permettant de démoduler le DAB+ disponible pour le grand public, je me suis tourné vers le module "T4A" que j'ai trouvé sur ce site. Il s'agit d'une petite carte avec un SoC qui gère toute la partie démodulation FM/DAB+. Autour, il n'y a pas besoin de grand chose : des régulateurs pour le 3V3 et le 1V2, un DAC (PCM5102), une EEPROM et un STM32F4 qui gère le tout. J'ai aussi rajouté écran OLED 3.12" de chez Newhaven Display (le grand frère de celui du DSPIY !), quelques bouton poussoirs et un récepteur IR pour le contrôle et la visualisation. En gros, par grand chose d'exceptionnel côté électronique ! Voila un petit schéma de principe :
Le tout est mis dans un boitier HIFI2000 très largement surdimensionné mais qui match bien avec le reste de la chaine hifi. D'ailleurs je recommande à 100% les services d'usinages et impression du fabricant, c'est tellement simple que ça en enlève presque le plaisir

J'ai passé un peu plus de temps sur le code du STM32, car ça m'a servi d'excuse pour apprendre un peu dans ce domaine. En particulier, j'ai jusque la toujours utilisé les outils de développement de ST (cubeIDE et leur librairie HAL). Je voulais passer à autre chose car :
- Je déteste Eclipse
- Je déteste HAL
- Je voudrais pas trop dépendre d'un seul fabricant et utiliser un max d'outils open-source
- J'utilise quotidiennement VScode, et donc je voudrais avoir tous mes outils dessus
- Je voudrais programmer en C++ (cubeIDE/HAL techniquement le permet, mais pas fait pour)
Le C++ n'a pas forcément bonne presse pour l'embarqué, en parti à cause de l'allocation dynamique et du polymorphisme "dynamique" qui est assez couteux. Cependant, après quelques vidéos youtube et article de blog j'ai été convaincu que le C++ avait aussi de très bon argument. Vous pouvez trouver un petit resumé ici, mais en gros j'ai retenu 3 argument principaux :
- La programmation orienté objet. J'y ai goûté, ça sera difficile de revenir en arrière
- L'abstraction "zero-cost". C'est un principe qui permet de rajouter beaucoup de couche d'abstraction au code (à travers des objets par exemple) mais qui n'ajoute pas de "overhead", notamment grace à l'optimisation du compilateur.
- Le code exécuté au moment de la compilation (compile time execution). Cet aspect vient surtout avec les versions moderne du C++, en gros depuis C++11. On peut écrire du code qui sera exécuté au moment de la compilation, par exemple pour générer des lookup table. Mais c'est également utiliser pour l'abstraction "zero-cost". C'est un aspect très très puissant du C++, et de plus en plus de fonctionnalité du langage peuvent être exécuté à ce moment la.
- L'abstraction "zero-cost". C'est un principe qui permet de rajouter beaucoup de couche d'abstraction au code (à travers des objets par exemple) mais qui n'ajoute pas de "overhead", notamment grace à l'optimisation du compilateur.
Il y a d'autres aspects intéressant. Mais le gros point négatif pour moi c'est la complexité du langage. Notamment car le C++ dit "moderne" est assez différent du C++ plus ancien, mais la compatibilité avec les versions précédentes doit être garantie. Il y a donc par exemple plein de façon d'écrire la même chose, avec des petites subtilités qui sont souvent pas simple à appréhender. Bref, je suis toujours très débutant mais plutôt convaincu.
Côté STM32, je suis parti sur modm.io pour le côté bas niveau. C'est une sorte de générateur de librairie, qui s'inspire un peu du "device tree" de linux. L'idée c'est de décrire ce que l'on va utiliser dans le STM32 (eg: l'UART, le SPI, etc) et va générer les bons objets en C++ avec la configuration qui va bien. Cela permet de générer uniquement ce qu'il faut, et avec un overhead dans la plupart des cas nul par rapport à écrire dans les registres directements. L'outil offre aussi des fonctions de debug et des fonctions plus hauts niveau (eg une methode de scheduler par exemple) mais je n'ai pas trop testé ce dernier point pour l'instant. Ca s'intégre très bien dans VScode, donc pour l'instant je suis très satisfait. L'outil est assez bien documenté, et il y a des mise à jour régulière. Pour l'instant c'est majoritairement pour des STM32, mais il aussi d'autre target comme le RP2040 par exemple.
Côté architecture, j'ai fait quelque chose d'assez classique (un genre de "Superloop") qui me satisfait qu'à moitié. Dans ce cas précis il n'y a rien de très critique, et le code reste globalement très simple. Mais pour des projets plus complexes, je suis toujours à la recherche d'une approche plus satisfaisante. J'ai testé la librairie [Boost::ext].SML dans certain composant du tuner. Cette libraire permet de décrire le système comme une machine d'état, et de manière assez lisible :
Code : Tout sélectionner
return make_transition_table(
// Start Event Guard Action Next
//+---------------------+------------------------+----------------+---------------------------------------------+---------------------+
*"state1"_s + "e1"_e [guard1] /(action1) = "state2"_s,
"state2"_s + "e2"_e [guard2] /(action2) = "state1"_s,
);
Ce code décrit une machine d'état avec une table de transition. En fonction de l'état présent, et sous condition d'un événement et d'un "guard", la machine peut passer à l'état suivant et exécuter une action précise. C'est une approche que j'aime beaucoup car assez familière; je l'ai pas mal utilisé sur des FPGA notamment. Le gros avantage [Boost::ext].SML est que, grace aux méthode d'exécution à la compilation du C++, la table de transition est transformée par la librairie en un grand "switch case" ou "if else if ..." à la compilation, et donc l'overhead de la machine d'état est faible ou nul. Le développeur de librairie le démontre assez bien en montrant l'assembleur généré. Les points négatifs pour moi sont que c'est pas toujours très simple/clair de savoir ce qu'il se passe réellement, et que c'est assez dur comprendre les erreurs de compilations. Le temp de compilation est aussi pas mal allongé car beaucoup de chose à faire. Ces deux derniers point sont améliorés dans la V2 de la librairie mais je n'ai pas encore testé.
Sinon il y a des approches à base de scheduler type RTOS ou autre mais je ne suis pas vraiment convainvu pour l'instant. Intel met à disposition la librairie compile-time-init-build qui utilise une approche similaire mais avec beaucoup de chose exécutées à la compilation, et donc avec un overhead minimal. Il y aussi pas mal d'autres outils à dispo, pour du debugs par exemple. Je pense tester prochainement. Sinon côté debug pur, il y aussi les outils d'orbcode qui me font de l'oeil (en parti développé par un des developpeur de modm.io). Je pense qu'il y a un peu de boulot pour tout mettre en place mais ça me semble prometteur !
Bref, tout ça pour dire que le C++ pour l'embarqué c'est super, et qu'il y a plein d'outils open-source à disposition qui permettent de faire tout plein de chose sympa pour occuper les soirées et les week-end


Et surtout, mon père peut écouter la radio dans son salon !

Louis