Python intégré : MicroPython est incroyable

Au cas où vous ne l’auriez pas entendu, il y a environ un mois, MicroPython a fêté son 11e anniversaire. J’ai eu la chance de pouvoir commencer à pirater avec peu de temps après la sortie des pyboards – la première conférence technique dont je me souviens était sur MicroPython, et c’est grâce à cette conférence que j’ai pu entrer dans le hackerspace dans lequel j’ai ensuite passé des années. Depuis lors, MicroPython est devenu un élément essentiel de mes projets, ateliers et incursions dans le hacking.

Si vous connaissez Python ou si vous avez envie d’apprendre, vous pourriez aussi l’apprécier. De plus, MicroPython est un ajout inestimable à la boîte à outils d’un hacker, et j’aimerais vous montrer pourquoi.

Piratage à la vitesse d’une touche

Vous avez une puce compatible MicroPython ? Il y a de fortes chances que MicroPython vous soit utile de plusieurs manières auxquelles vous ne vous attendriez pas. Voici un exemple éclatant de ce que vous pouvez faire. Flashez MicroPython sur votre carte – j’utiliserai une carte RP2040 comme un Pi Pico. Pour un Pico, connectez un périphérique I2C à votre carte avec SDA sur la broche 0 et SCL sur la broche 1, ouvrez un terminal série de votre choix et saisissez ceci :

>>> from machine import I2C, Pin
>>> i2c = I2C(0, sda=Pin(0), scl=Pin(1))
>>> i2c.scan()

Cette interactivité est connue sous le nom de REPL – Read, Evaluate, Print, Loop. Le REPL à lui seul rend MicroPython incroyable pour la mise en place de cartes, la construction rapide d’appareils, la rétro-ingénierie, le débogage de problèmes et de code de bibliothèque d’appareils, le prototypage d’extraits de code, l’écriture de code de test et bien d’autres choses encore. Vous pouvez explorer votre MCU et ses périphériques à la vitesse de l’éclair, depuis l’intérieur du MCU.

Lorsque je reçois un nouveau périphérique I2C avec lequel je veux jouer, la première chose que je fais est de le connecter à une carte fonctionnant sous MicroPython et de fouiller dans ses registres. C’est aussi simple que cela :

>>> for i in range(16):
>>>     # read out registers 0-15
>>>     # print "address value" for each
>>>     print(hex(i), i2c.readfrom_mem(0x22, i))
>>> # write something to a second (0x01) register
>>> i2c.writeto_mem(0x22, 0x01, bytes([0x01]) )

Que i2c.scan() La ligne seule remplace un programme de scanner I2C que vous auriez autrement à télécharger dans votre MCU de choix, et vous pouvez l’exécuter en trois à cinq secondes. Vous avez Micropython en cours d’exécution ? Utilisez le terminal série, Ctrl+C, et cela vous amènera dans un REPL, tapez simplement i2c.scan() et appuyez sur Entrée. De plus, vous pouvez inspecter les variables de votre code à partir du REPL, et si vous structurez bien votre code, même redémarrer votre code là où il s’est arrêté ! C’est tout simplement incroyable pour déboguer les plantages de code, les problèmes rares et les bugs tels que « il s’arrête de fonctionner après 20 jours de disponibilité ». De nombreuses manières importantes, cela élimine le besoin d’un débogueur – vous pouvez désormais utiliser votre MCU pour déboguer votre code de l’intérieur.

Oh, encore une fois, ça i2c.scan()? Vous pouvez le modifier rapidement si vous avez besoin d’ajouter des fonctionnalités à la volée. Vous souhaitez que les adresses soient imprimées en hexadécimal ? (hex(addr) for addr in i2c.scan()). Vous souhaitez scanner votre bus pendant que vous testez votre câblage à la recherche d’un fil défectueux ? Placez le scan dans un while True: et Ctrl+C lorsque vous avez terminé. Lorsque vous utilisez un langage compilé typique, ce type de bidouillage nécessite un cycle d’édition-compilation-flash-connexion-répétition, prenant environ une douzaine de secondes à chaque fois que vous effectuez un petit changement. MicroPython vous permet de bidouiller à la vitesse de votre frappe au clavier. Vous avez confondu les broches ? Appuyez sur le bouton « up », modifiez la ligne et exécutez le i2c = ligne à nouveau.

Pour être clair, tout le code s’exécute sur votre microcontrôleur, il vous suffit de le saisir dans la RAM de votre puce et il est exécuté par votre MCU. Voici comment vérifier les GPIO sur votre Pi Pico, au cas où vous craigniez que certains d’entre eux aient grillé :

>>> from machine import Pin
>>> from time import sleep
>>> pin_nums = range(30) # 0 to 29
>>> # all pins by default - remove the ones connected to something else if needed
>>> pins = [Pin(num, Pin.OUT) for num in pin_nums]
>>> 
>>> while True:
>>>   # turn all pins on
>>>   for i in range(len(pins)):
>>>     pins[i].value(True)
>>>   sleep(1)
>>>   # turn all pins off
>>>   for i in range(len(pins)):
>>>     pins[i].value(False)
>>>   sleep(1)
>>>   # probe each pin with your multimeter and check that each pin changes its state

Il y a de nombreux éléments qui font de MicroPython un interpréteur de premier ordre pour votre MCU. Ce n’est pas seulement la couche d’abstraction matérielle (HAL), mais c’est aussi la HAL, car déplacer votre code d’une carte à l’autre est généralement aussi simple que de changer les définitions des broches. Mais ce sont toutes les autres bibliothèques que vous obtenez gratuitement qui rendent Python génial sur un microcontrôleur.

Batteries incluses

Il s’agit vraiment des batteries – toutes les bibliothèques que l’interpréteur de stock vous apporte, et bien d’autres que vous pouvez télécharger. Il suffit d’une importation pour les trouver time, socket, json, requests, select, re et bien d’autres encore, et dans l’ensemble, ils fonctionnent de la même manière que CPython. Vous pouvez faire la même chose r = requests.get("https://retro.hackaday.com"); print(r.text)[:1024] comme vous le feriez sur Python de bureau, tant que vous disposez d’une connexion réseau. Il y aura quelques changements, par exemple, time.time() est un entier, pas un flottant, donc si vous avez besoin de suivre le temps de manière très granulaire, il existe différentes fonctions que vous pouvez utiliser.

Supposons que vous souhaitiez analyser du JSON à partir d’un point de terminaison Web. Si vous le faites dans un environnement Arduino, il y a de fortes chances que vous soyez limité dans ce que vous pouvez faire et que vous obteniez des erreurs entre crochets triangulaires si vous utilisez mal les constructions de la bibliothèque JSON, car d’une manière ou d’une autre, la bibliothèque utilise des modèles ; les messages d’erreur d’exécution sont à vous d’implémenter. Si vous analysez du JSON sur MicroPython et que vous vous attendez à un dict mais que vous obtenez une liste lors de l’exécution, il affiche un message d’erreur lisible. Si vous manquez de mémoire, vous obtenez un message très lisible MemoryError imprimé, vous pouvez vous y attendre et vous en protéger, voire réparer les choses depuis REPL et réexécuter le code si nécessaire.

Le code fourni par l’utilisateur est également assez bon. Si vous voulez du PIO ou de l’USB-HID sur le RP2040, ou des fonctions spécifiques au processeur ESP sur la famille ESP, elles sont exposées dans des bibliothèques pratiques. Si vous voulez une bibliothèque pour piloter un écran, elle a probablement déjà été implémentée par quelqu’un et mise sur GitHub. Et, si elle n’existe pas, vous en portez une depuis Arduino et la publiez ; il y a de fortes chances qu’elle soit plus courte et plus facile à lire. Bien sûr, MicroPython a des problèmes. En fait, j’ai moi-même rencontré un bon nombre de problèmes, et je ne voudrais pas les mentionner.

Attention à la portée

D’après mon expérience, le plus gros problème avec MicroPython est que l’écriture de « MicroPython » requiert une attention plus grande que ce que je peux me permettre. Personnellement, je le raccourcis à uPy ou juste upyde manière informelle. Un autre problème est que le nouveau logo modernisé de MicroPython n’a pas de sources ou d’images haute résolution disponibles, donc je ne peux pas imprimer mes propres autocollants, et MicroPython n’a pas visité FOSDEM cette année, donc je n’ai pas pu réapprovisionner mon stock d’autocollants.

Plus sérieusement, MicroPython en tant que langage offre un large champ d’applications ; parfois, il ne fonctionnera pas pour vous. Un ATMega328P ne peut pas le gérer, mais un ESP8266 ou un ESP32 le feront facilement, sans aucun souci, et vous bénéficierez du Wi-Fi gratuitement. Si vous souhaitez contrôler exactement ce que fait votre matériel, compter les cycles d’horloge ou rencontrer des problèmes de performances, MicroPython pourrait ne pas fonctionner pour vous, à moins que vous n’écriviez du code Viper.

Si vous souhaitez disposer d’un microcontrôleur à très faible consommation d’énergie fonctionnant par exemple à partir d’une récupération d’énergie, MicroPython ne fonctionnera probablement pas. Si vous souhaitez que votre code s’exécute instantanément une fois que votre microcontrôleur est alimenté, sachez que l’interpréteur prend un peu de temps pour s’initialiser – environ une seconde, d’après mon expérience. Si vous souhaitez faire une sortie HDMI sur un RP2040, restez peut-être en C – bien que vous puissiez toujours faire du code PIO, il existe de bonnes bibliothèques pour cela.

Une certaine quantité de cycles d’horloge sera consacrée aux subtilités apportées par Python. Vous avez besoin de plus de performances ? Il y a des choses que vous pouvez faire. Par exemple, si vous avez un écran couleur connecté via SPI et que vous souhaitez réduire le temps de rendu des images, vous pouvez passer au C, mais vous n’êtes pas obligé d’abandonner MicroPython : il suffit de mettre davantage de votre code intensif dans des pilotes de périphériques écrits en C ou des modules que vous compilez, et de le prototyper en MicroPython avant de l’écrire.

Comme vu sur Hackaday

Si vous avez suivi la série de discussions sur l’USB-C PD, vous avez dû voir que le code a été écrit en MicroPython, et j’ai ajouté des fonctionnalités comme le sniffing PD, la gestion DisplayPort et le mode PSU sans effort ; c’était aussi simple que ça de les ajouter et plus encore. J’ai commencé avec le REPL, un FUSB302 connecté à un RP2040, en fouillant dans les registres et en lisant la fiche technique, et même si j’avais besoin d’aide extérieure, le travail sur le REPL était tellement amusant !

Il y a quelque chose d’immensément satisfaisant à manipuler un élément technologique de manière interactive et à essayer d’en extraire des fonctionnalités, d’autant plus si cela fonctionne, ce qui n’a pas été le cas, mais cela a fonctionné à de nombreuses reprises ! J’ai bidouillé cette pile de développement professionnel, et maintenant je la reformate lentement à partir d’un ensemble de fonctions en code basé sur des objets – Python rend cela facile.

Vous vous souvenez de la carte Sony Vaio ? Son contrôleur embarqué (EC) est un RP2040, toujours sous tension tant que les piles sont insérées, et il va exécuter MicroPython. Les tâches de l’EC incluent la gestion de l’alimentation, le fait d’être un périphérique HID sur I2C, le contrôle des boutons et des LED, et éventuellement la transmission des événements du clavier et des trackpoints pour enregistrer un port USB du deuxième RP2040, qui exécutera QMK et le serveur comme contrôleur de clavier. MicroPython me permet de créer rapidement le firmware, de l’agrémenter d’une douzaine de fonctionnalités pendant que je le fais, et de garder la base de code extensible à volonté. L’implémentation du firmware sera un voyage amusant, et j’espère pouvoir en parler à un moment donné.

Avez-vous utilisé MicroPython dans vos projets ? Qu’est-ce que cela vous a apporté ?

François Zipponi
Je suis François Zipponi, éditorialiste pour le site 10-raisons.fr. J'ai commencé ma carrière de journaliste en 2004, et j'ai travaillé pour plusieurs médias français, dont le Monde et Libération. En 2016, j'ai rejoint 10-raisons.fr, un site innovant proposant des articles sous la forme « 10 raisons de... ». En tant qu'éditorialiste, je me suis engagé à fournir un contenu original et pertinent, abordant des sujets variés tels que la politique, l'économie, les sciences, l'histoire, etc. Je m'efforce de toujours traiter les sujets de façon objective et impartiale. Mes articles sont régulièrement partagés sur les réseaux sociaux et j'interviens dans des conférences et des tables rondes autour des thèmes abordés sur 10-raisons.fr.