Tout projet embarqué finit par se heurter au même obstacle : la concurrence. Un moteur doit continuer à tourner tandis qu’un système de sécurité surveille les capteurs, qu’une pile de communication répond à l’hôte et qu’un minuteur décompte une action automatique. Dès que deux de ces éléments interagissent, le code se remplit de threads, de mutex, de variables de condition — et d’une catégorie de bogues qui n’apparaissent que toutes les quelques milliers d’heures d’utilisation.
Il existe deux solutions bien connues. La première option consiste à écrire manuellement tout le code de contrôle — et j'ai déjà expliqué pourquoi cette approche n'est pas viable à grande échelle. La seconde consiste à confier l'ensemble du problème à une IA génératrice de code — et j'ai également expliqué pourquoi cette approche n'est pas acceptable pour les systèmes embarqués en production.
Cet article traite de la troisième voie : décrire le comportement dans un DSL textuel et laisser un générateur déterministe effectuer le travail mécanique. Je nomme ce type d'outil un robot logiciel — et la relation qu'il instaure avec le développeur n'est ni du travail manuel ni une délégation aveugle. Il s'agit d'un co-développement.
Pourquoi un DSL textuel change la donne
L'avantage évident d'un DSL est l'abstraction. L'avantage moins évident — et bien plus précieux au quotidien — est que le modèle est en texte brut.
Un fichier .umt est géré par Git comme n'importe quel fichier source. Les différences sont nettes : lorsqu'un collègue ajoute une transition, la demande de fusion affiche une seule ligne ajoutée, et non deux cents lignes de blocs switch régénérés. Il est compatible avec les fusions, les recherches (grep), et résiste à tous les éditeurs et à toutes les chaînes d'intégration continue. Un outil de modélisation graphique avec un stockage binaire ou XML ne vous offre aucun de ces avantages ; une comparaison de deux fichiers XMI n'est pas pertinente pour une revue de conception, elle génère du bruit.
Le format texte signifie également que le modèle est la source unique de vérité pour les humains et les machines. Un relecteur lit directement le comportement. Le générateur lit le même fichier et produit l'implémentation. Documentation, artefact de revue et données d'entrée de compilation ne font qu'un : rien ne peut diverger, car il n'y a rien de séparé.
Déclarer la concurrence au lieu de l'implémenter
UMTSM est basé sur UML State Machines 2.5 et prend en charge l'ensemble de ses fonctionnalités, y compris celles qui rendent la concurrence déclarative : régions orthogonales, synchronisation fork/join, activités do avec événements de fin et historique profond/superficiel/persistant.
Cela change la signification de « écrire du code concurrent ». Au lieu d'implémenter le parallélisme, vous le déclarez :
sm Conveyor
{
state Running
{
region Motion
{
init -> Moving;
state Moving
{
BeltStalled -> Fault;
}
}
region Safety
{
state Monitoring
{
do / checkLightCurtain;
[is_breached] -> Fault / stopBelt();
}
}
}
}
Deux régions de Running s'exécutent en parallèle. Le code C++ généré contient la gestion des threads, la protection des données partagées par mutex et la synchronisation à la fin de l'exécution des régions — le tout de manière déterministe, identique à chaque fois. Le développeur n'écrit jamais de std::mutex pour la gestion interne de la machine à états et n'a jamais à déboguer une condition de concurrence dans une infrastructure qu'il n'a pas conçue.
Le Soft-Robot : L'automatisation sans perte de contrôle
Les robots industriels n'ont pas remplacé les ingénieurs sur les chaînes de montage. Ils exécutent un programme précis et répétable, et l'ingénieur conserve l'entière maîtrise du produit fabriqué. Un robot soudeur qui improviserait serait immédiatement retiré de l'usine.
Un générateur de code déterministe est l'équivalent logiciel — un soft-robot. Il est rapide et infatigable comme un assistant IA, mais contrairement à ce dernier, il n'improvise jamais. Une même entrée .umt produit une sortie identique octet par octet. Chaque ligne de code généré est traçable jusqu'à une ligne du modèle. En cas de comportement incorrect, la correction est apportée au modèle, sous contrôle de version, dans un diff vérifiable.
C’est l’équilibre que promet le titre de cet article : le code de contrôle complexe n’est pas écrit à la main, mais le contrôle n’est jamais abandonné pour autant. Le développeur est responsable de la conception — états, événements, gardes, actions — exprimée dans un langage conçu précisément à cet effet. Le robot logiciel assure la traduction en une infrastructure concurrente adéquate. L’IA a toujours son rôle à jouer, comme évoqué précédemment : elle peut contribuer à la conception et à l’analyse critique du modèle. Mais la transformation finale en code appartient à une machine responsable, et non à une machine simplement convaincante.
Conclusion
La gestion de la concurrence ne se résume pas à un code écrit à la main avec une précision héroïque, ni à la délégation du jugement technique à un générateur. Elle devient gérable lorsque les comportements sont modélisés par un modèle textuel – comparable, révisable et versionné – et qu'un robot logiciel déterministe transforme ce modèle en une infrastructure que le développeur devrait autrement réimplémenter, imparfaitement, à chaque projet. L'ingénieur décide ; le robot construit ; le modèle garantit la cohérence du code.
Pour toute question ou projet relatif à UMTSM, n'hésitez pas à nous contacter.
