Il y a des envies qui traînent des années dans un coin de la tête, sans jamais trouver le bon moment ni le bon outil pour se concrétiser. Faire tourner MOGWAI sur un microcontrôleur en faisait partie.
Une vieille envie, un nouvel outil
MOGWAI, mon moteur de scripting RPN, existe depuis une dizaine d’années. Open-sourcé en février dernier, il tourne très bien sur desktop, en .NET classique, avec toute la richesse et le confort que ça permet : mémoire quasi illimitée à l’échelle d’un microcontrôleur, un vrai double, des generics, un ramasse-miettes qui ne se pose jamais vraiment de questions existentielles. Il tourne aussi sur iOS et Android grâce à .NET MAUI — le même moteur, embarqué dans une app mobile plutôt que sur un poste de travail.
Le mobile, ce n’est pas un territoire découvert sur le tard pour moi : à côté de mon activité salariée où je développe en .NET MAUI, j’ai une solide expérience du développement natif Android et iOS (Java, Kotlin, Objective-C, Swift). Et côté .NET, je l’utilise depuis sa toute première version, en 1999 — de quoi avoir vu l’écosystème grandir, changer plusieurs fois de visage, et rester malgré tout mon terrain de jeu de prédilection.
Mais j’ai toujours eu cette idée derrière la tête : et si MOGWAI pouvait tourner directement sur une puce ? Pas juste piloter un microcontrôleur depuis un PC via un port série, mais vraiment vivre dessus, avec son propre interpréteur RPN embarqué, capable de lire un GPIO, de piloter un capteur, de réagir à un événement matériel — tout ça en quelques dizaines de kilo-octets de RAM.
Le problème, c’était l’outil. Je code depuis mes 11 ans, sur papier avant d’avoir un ordinateur, puis sur Amstrad sous CP/M, puis sur mes premiers PC en Turbo Pascal — et j’ai fini par construire toute mon expertise professionnelle autour de .NET. L’écosystème embarqué « traditionnel » (C/C++, Arduino, ESP-IDF) ne m’était pas inconnu, mais ce n’était pas mon terrain de jeu naturel. Refaire tout MOGWAI dans un langage que je maîtrise moins bien, juste pour le faire tourner sur un ESP32, ça n’avait jamais été assez tentant pour que je m’y attelle vraiment.
Et puis j’ai découvert .NET nanoFramework.
.NET, mais en (beaucoup) plus petit
nanoFramework, c’est un CLR .NET réécrit pour tourner sur des microcontrôleurs — ESP32, STM32, TI, et plus récemment le Raspberry Pi Pico. On écrit du vrai C#, dans Visual Studio, avec le vrai confort de debug (breakpoints, inspection de variables, Device Explorer) — mais le code s’exécute sur une puce à quelques centaines de kilo-octets de RAM, pas sur un serveur.
Autrement dit : les outils que je connais par cœur, appliqués à un terrain que je voulais explorer depuis longtemps. Il n’en fallait pas plus pour que l’envie redevienne concrète.
L’idée m’est venue tout naturellement : plutôt que de porter MOGWAI tel quel (avec tout son sucre syntaxique, son système de types riche, ses fonctions desktop), pourquoi ne pas concevoir un second runtime, minimaliste, qui ne parlerait que la forme la plus pure du langage — du RPN canonique, sans aucune fioriture — et laisser toute la complexité du confort d’écriture au runtime desktop existant ?
C’est devenu MOGWAI NANO.
Deux runtimes, une seule philosophie
L’architecture s’est dessinée assez vite : le grand MOGWAI, sur PC, garde tout son sucre syntaxique (if...then...else, for...do, l’opérateur ->) et devient l’endroit où on écrit confortablement son code. Une fois ce code prêt, il est désucré — réduit à sa forme canonique, RPN pure — avant d’être transmis à un second runtime, minuscule et rigoureusement discipliné, qui tourne directement sur le microcontrôleur.
# Ce qu'on écrit, confortablement, côté PC
if (a 10 >) then { "grand" ? } else { "petit" ? }
# Ce que le device reçoit et exécute réellement
{ a 10 > } eval { "grand" ? } { "petit" ? } IFELSE
Le device ne connaît que cette seconde forme. Pas de parser complexe à embarquer, pas de gestion de sucre syntaxique à maintenir sur deux fronts — juste un tokenizer, une pile, et un dispatch de primitives. Toute la richesse reste où les ressources sont abondantes ; toute la rigueur va où les ressources sont comptées.
Un bénéfice inattendu de cette séparation : l’extension VS Code de MOGWAI, qui ne connaît que le langage desktop, fonctionne pour MOGWAI NANO sans la moindre modification. Coloration syntaxique, autocomplétion, tout suit — parce que du point de vue de l’éditeur, on écrit juste… du MOGWAI.
Ce que les contraintes vous apprennent
J’aime les systèmes contraints. Ils obligent à construire quelque chose de solide et de malin plutôt que de simplement empiler des couches de confort. nanoFramework n’a pas manqué d’en fournir, des contraintes.
Pas de generics complets (Dictionary<TKey,TValue> reste en travaux) — donc Hashtable et ArrayList, comme au bon vieux temps du .NET 1.x, redeviennent les outils du quotidien. Pas de FPU double précision sur ESP32 — donc MOGNumber embarque un float, pas un double, pour profiter du calcul flottant matériel plutôt que de payer une émulation logicielle coûteuse. Et une vraie leçon inattendue : une simple liste qui grossit progressivement peut déclencher un OutOfMemoryException alors qu’il reste encore 25 Ko de libre — parce que la mémoire, aussi disponible soit-elle en théorie, doit encore se trouver contiguë pour qu’un tableau interne puisse doubler de taille. Implémenter le sigil & (référence directe plutôt que copie) a permis de stocker près du double d’éléments avant de saturer — la même optimisation qui donnait un gain de ×1600 sur le grand MOGWAI se révèle ici un vrai levier de capacité, pas seulement de vitesse.
Il a aussi fallu redécouvrir des vieux réflexes : le clavier « Entrée » de PuTTY qui envoie un CR tout seul en héritage direct des téléscripteurs des années 60, les histoires de CR/LF qui ne se sont jamais totalement résolues entre Unix et Windows — des souvenirs qui ne sont pas sans rappeler mes années CP/M et MS-DOS.
Les moments qui font qu’on continue
Il y a des instants, dans un projet comme celui-ci, qui valent toutes les heures de debug qui les précèdent. La première LED qui clignote vraiment, pilotée par du RPN qui tourne sur la puce elle-même, pas juste envoyé depuis un PC. Le premier bouton qui déclenche un événement, avec le MOGRecord contenant le numéro de pin et la nouvelle valeur, injecté proprement dans le scope du handler. Un test d’endurance de 100 000 itérations qui tourne pendant près de trois heures avec une mémoire parfaitement stable au premier octet près — la preuve, en conditions réelles, qu’aucune fuite ne se cache dans les fondations.
Et puis ce moment particulier où un timer et une boucle infinie se sont mis à tourner en parallèle sur le device, pilotés à distance depuis mon PC via WiFi : "HELLO" toutes les 250 millisecondes, "YO!" toutes les secondes, entrelacés avec une régularité parfaite — la preuve que tout l’édifice (threads, file d’attente, callbacks) tenait vraiment debout, pas seulement sur le papier.
Un guide dans l’aventure
Découvrir un nouvel écosystème seul, à coups de recherches et d’essais-erreurs, ça a son charme — mais ça va nettement plus vite avec quelqu’un qui connaît déjà les coins et recoins du terrain. Mon ami Laurent Ellerbach (LinkedIn), qui contribue activement au projet nanoFramework, a répondu à toutes mes questions au fil de cette aventure — des choix de carte de développement jusqu’aux subtilités du support GPIO selon les plateformes.

Son parcours dans ce projet force le respect. Contributeur majeur de .NET IoT, il a rejoint nanoFramework fin 2020 avec une idée simple mais ambitieuse : aligner les API bas niveau (GPIO, SPI, I2C, UART) entre .NET IoT et nanoFramework, pour que le code écrit pour un Raspberry Pi puisse, autant que possible, se réutiliser tel quel sur un microcontrôleur. De ce chantier sont nés, entre autres, un serveur web complet pour nanoFramework, un vrai framework de tests capable de tourner aussi bien sur poste de développement que sur device réel, le portage de plus de cinquante bindings de capteurs .NET IoT, et le SDK permettant de connecter un device nanoFramework à Azure IoT en quelques lignes de code. Le tout, comme il le raconte lui-même, essentiellement sur son temps libre — tôt le matin, le soir, les week-ends — porté par cette même curiosité d’ingénieur qui pousse à comprendre un système jusque dans ses détails les plus bas niveau.
Un détail m’a particulièrement parlé en le relisant : son travail sur le support d’écrans pour les cartes M5Stack rencontre exactement les mêmes difficultés que celles que j’ai pu croiser avec mon petit écran OLED I2C — les drivers d’affichage restent, de son propre aveu, l’un des points les plus délicats de tout l’écosystème. Une bonne indication que je ne suis pas le seul à buter sur ce genre d’obstacle, et que la communauté nanoFramework continue activement d’y travailler.
Pour aller plus loin
Si l’envie vous prend d’explorer .NET nanoFramework de votre côté, voici où commencer :
- Site officiel — présentation générale du projet, blog, actualités
- Documentation complète — API, architecture, guides de démarrage, cibles supportées
- Guide de démarrage pas à pas — installation de Visual Studio, de l’extension, flash du premier firmware, et son premier « Hello World » clignotant
- Dépôt GitHub — le point d’entrée vers tous les repos du projet, code source compris
- Chaîne YouTube — tutoriels vidéo et démonstrations
- Le récit de Laurent Ellerbach — une année entière plongé dans nanoFramework, racontée de l’intérieur
De quoi flasher son premier microcontrôleur et faire clignoter une LED en quelques minutes — la porte d’entrée la plus simple vers un monde qui, une fois qu’on y a mis les pieds, donne rapidement envie d’aller beaucoup plus loin.
MOGWAI NANO tourne aujourd’hui sur ESP32 et sur Raspberry Pi Pico W — deux architectures matérielles complètement différentes, le même fichier binaire déployé sur les deux sans la moindre adaptation. Rien dans l’architecture ne le limite à ces deux cibles : nanoFramework supporte aussi STM32 et TI, et rien n’empêche à terme MOGWAI NANO d’y tourner également, le jour où j’aurai ce genre de cartes sous la main pour le vérifier. Le langage est complet : arithmétique, comparaisons, contrôle de flux, fonctions utilisateur, timers, événements. Le matériel répond : GPIO, et bientôt I2C, SPI, PWM, ADC. Un protocole réseau permet de découvrir un device sur le réseau local et de lui envoyer du code à distance, avec une gestion propre des déconnexions.
Il est temps de l’ouvrir. Le repo GitHub arrive très bientôt, sous licence Apache 2.0 comme le grand MOGWAI, avec tout ce qu’il faut pour flasher un ESP32 ou un Pico en quelques commandes et voir MOGWAI NANO démarrer tout seul, dès la mise sous tension.
Une vieille envie, un nouvel outil, et beaucoup de patience pour apprivoiser les contraintes d’un monde où chaque octet compte vraiment. Il ne me restait plus qu’à m’y mettre.
La suite — le repo, la documentation, le premier tutoriel — dans un prochain article.


1 réflexion au sujet de « MOGWAI descend sur Terre (et sur silicium) : la genèse de MOGWAI NANO »