Retour au catalogue
Season 46 7 Épisodes 24 min 2026

MicroPython

Édition 2026. Un guide complet sur MicroPython pour les microcontrôleurs. Apprenez à exécuter un interpréteur Python 3 complet sur du matériel bare-metal.

Systèmes embarqués Microcontrôleurs Fondamentaux de Python
MicroPython
Lecture en cours
Click play to start
0:00
0:00
1
Le Python qui tient dans 256K
Découvrez comment MicroPython fait tenir un interpréteur Python 3 complet dans des microcontrôleurs bare-metal. Nous explorons son identité fondamentale, ses différences avec CPython, et comment il parvient à s'exécuter dans des environnements hautement contraints.
3m 49s
2
La passerelle matérielle : Le module machine
Apprenez à contrôler les périphériques du microcontrôleur directement depuis Python. Nous plongeons dans le module machine, en explorant comment interagir avec les Pins, le PWM et la mémoire brute.
3m 12s
3
Live Coding sur MCU : REPL et mpremote
Révolutionnez votre flux de travail en développement embarqué. Nous couvrons le REPL de MicroPython et l'outil en ligne de commande mpremote pour automatiser les connexions séries et l'exécution en direct.
3m 28s
4
Trois lignes pour le WiFi : Le module network
Transformez un microcontrôleur en un nœud IoT connecté. Nous explorons le module network, en détaillant comment se connecter au WiFi en tant que station ou héberger votre propre Access Point.
3m 32s
5
Survivre aux contraintes : La RAM et le GC
Maîtrisez l'art d'écrire du code Python économe en mémoire. Nous discutons de la fragmentation du heap, de la pré-allocation de buffers et du garbage collection manuel pour que votre microcontrôleur continue de fonctionner de manière fluide.
3m 22s
6
Compilé vs Gelé : Déploiement en production
Apprenez à déployer des applications massives sans manquer de RAM. Nous explorons les fichiers .mpy pré-compilés et le gel du bytecode directement dans la mémoire flash du microcontrôleur.
3m 29s
7
Déterminisme en Python : Timers et Interruptions
Obtenez un comportement temps réel dans MicroPython en utilisant des timers matériels et des routines de service d'interruption. Nous couvrons les règles strictes de l'écriture d'ISRs et comment éviter l'allocation de mémoire.
3m 16s

Épisodes

1

Le Python qui tient dans 256K

3m 49s

Découvrez comment MicroPython fait tenir un interpréteur Python 3 complet dans des microcontrôleurs bare-metal. Nous explorons son identité fondamentale, ses différences avec CPython, et comment il parvient à s'exécuter dans des environnements hautement contraints.

Télécharger
Salut, ici Alex de DEV STORIES DOT EU. MicroPython, épisode 1 sur 7. Python sur desktop consomme généralement des mégaoctets de mémoire rien qu'au démarrage. Essaie de mettre ça sur une minuscule puce à deux dollars et le système se retrouve immédiatement à court de ressources. Pour écrire du Python pour des microcontrôleurs, tu as besoin d'un interpréteur qui tient dans une fraction de cet espace sans perdre les features principales du langage sur lesquelles tu t'appuies. C'est précisément ce que propose MicroPython. MicroPython est une implémentation légère et très performante du langage de programmation Python 3. Il est conçu spécifiquement pour tourner dans des environnements contraints. Le Python standard, souvent appelé CPython, part du principe qu'il tourne sur un système d'exploitation complet comme Linux ou Windows, avec des gigaoctets de stockage et plein de RAM. MicroPython inverse cette logique. Il est conçu pour tourner en bare metal. Il n'y a pas d'OS sous-jacent pour gérer le hardware. À la place, c'est MicroPython qui fait office d'OS. Il s'interface directement avec le hardware pour que tu puisses écrire des scripts de haut niveau afin de contrôler des périphériques physiques. L'ingénierie derrière tout ça se concentre entièrement sur des contraintes de ressources extrêmes. MicroPython peut s'exécuter entièrement dans à peine 256 kilo-octets d'espace de code compilé. Encore plus impressionnant, il ne demande que 16 kilo-octets de RAM pour tourner. Dans ces limites strictes, il offre un environnement Python pleinement fonctionnel. Le Python standard inclut une énorme standard library, bien connue pour son approche batteries included. MicroPython réduit ça à un sous-ensemble de modules soigneusement choisis, en gardant uniquement ce qui a du sens pour un système embarqué. Malgré ces lourdes optimisations, le langage en lui-même reste du vrai Python 3. Ça veut dire que le code que tu écris sur ton desktop se transpose directement sur le device embarqué. MicroPython supporte des features avancées du langage comme les closures, les list comprehensions, les generators, et la gestion standard des exceptions. Il gère même les entiers de précision arbitraire. Si ta logique nécessite de multiplier des nombres immenses, MicroPython scale la mémoire dynamiquement pour te donner la bonne réponse sans te heurter à une limite architecturale stricte, exactement comme le Python sur desktop. Voici le point clé. Parce que tout le moteur Python tient sur la puce, tu obtiens un prompt interactif en direct, directement sur le hardware. Cette read-eval-print loop change la façon dont tu écris du code embarqué. Normalement, programmer un microcontrôleur implique d'écrire du code en C, de le compiler sur ton desktop, de le flasher sur la carte, et d'attendre qu'il s'exécute. Avec MicroPython, tu branches la carte à ton ordinateur, tu ouvres un terminal série, et tu tapes des commandes Python directement dans la puce. Tu peux tester ta logique, lire les valeurs des capteurs ou déclencher des actions instantanément. Pour rendre ça possible, MicroPython inclut des modules built-in spécifiques qui vont au-delà du Python standard. Vu que le Python standard ne sait rien de la lecture de pins physiques ou de la configuration de timers hardware, MicroPython fournit des interfaces spécialisées et hautement optimisées pour ces tâches. Elles sont intégrées directement dans le firmware de ta puce spécifique, ce qui te donne un contrôle brut sur le monde physique sans alourdir l'empreinte mémoire. En supprimant l'OS et en réduisant l'interpréteur pour qu'il tienne dans 256 kilo-octets, MicroPython transforme du hardware bon marché et limité en ressources en un environnement de développement dynamique et interactif. Si tu veux soutenir l'émission, tu peux nous trouver en cherchant DevStoriesEU sur Patreon. Merci de ton écoute. À la prochaine !
2

La passerelle matérielle : Le module machine

3m 12s

Apprenez à contrôler les périphériques du microcontrôleur directement depuis Python. Nous plongeons dans le module machine, en explorant comment interagir avec les Pins, le PWM et la mémoire brute.

Télécharger
Salut, ici Alex de DEV STORIES DOT EU. MicroPython, épisode 2 sur 7. Arrête de recompiler du code C et de flasher du firmware juste pour tester un capteur ou actionner un interrupteur. Tu veux un contrôle direct sur ton microcontrôleur sans le boilerplate, et c'est exactement ce que propose le module machine. Le module machine est ton pont vers le hardware. Il traduit le code Python en signaux électriques qui pilotent les pins physiques de ta carte. Il te donne accès aux fonctionnalités hardware de base comme la fréquence du CPU, les sleep modes, et les inputs et outputs numériques. Mais comme il tourne au plus près du métal, il vient avec un avertissement. Ce module ne te prend pas par la main. Si tu configures le mauvais registre hardware ou que tu écris à une adresse mémoire protégée, ta carte va crasher et rebooter. La fondation de ce module, c'est la classe Pin. Un pin est une connexion physique sur le microcontrôleur qui peut envoyer ou recevoir des tensions électriques. Pour contrôler un composant de base comme une LED, tu dois envoyer une tension à un pin spécifique. Tu fais ça en important le module machine et en créant un objet Pin. Tu fournis le numéro du pin physique, et tu définis si le pin doit agir comme un input ou un output. Pour une LED, tu le configures comme un output en passant une constante d'output. Une fois l'objet créé, tu l'utilises pour définir l'état. Appliquer une valeur de un passe la ligne hardware en high et allume la LED. Appliquer une valeur de zéro la passe en low et l'éteint. Tu manipules l'état digital du hardware en temps réel depuis un prompt Python. Parfois, les états basiques on et off ne suffisent pas. Si tu veux faire varier l'intensité de cette LED ou contrôler la vitesse d'un moteur, tu as besoin du Pulse Width Modulation, ou PWM. Le module machine a une classe PWM dédiée pour ça. Au lieu d'un flux continu de tension, le PWM allume et éteint le pin extrêmement vite. Tu crées un objet PWM en lui passant l'objet Pin que tu as déjà configuré. Ensuite, tu définis deux paramètres hardware : la fréquence et le duty cycle. Voici le point clé. La fréquence dicte combien de fois par seconde le signal fait un cycle, pendant que le duty cycle dicte quel pourcentage de ce temps le signal est réellement sur on. Si tu règles le duty cycle à cinquante pour cent, la LED ne reçoit du courant que la moitié du temps, ce qui la fait paraître deux fois moins lumineuse pour l'œil humain. En changeant graduellement cette valeur de duty cycle à l'intérieur d'une boucle, tu indiques au hardware de créer un effet de fading fluide. Pour les cas d'usage avancés, le module machine offre un accès direct aux registres hardware sous-jacents via des objets appelés mem8, mem16 et mem32. Ils te permettent de lire et d'écrire des bytes bruts, des half-words ou des mots de 32 bits directement à des adresses mémoire spécifiques. Tu n'utilises pas d'objet Pin pour ça. Tu utilises la notation standard entre crochets, en passant l'adresse mémoire physique à laquelle tu veux accéder, exactement comme pour chercher une clé dans un dictionnaire. Assigner une valeur à une adresse mem32 écrase instantanément ce registre hardware. C'est comme ça que tu interagis avec des fonctionnalités obscures du microcontrôleur que MicroPython n'a pas encore explicitement wrappées dans une classe. Ça te donne une autorité absolue sur le silicium. La vraie puissance du module machine, ce n'est pas juste qu'il rend le hardware accessible, mais qu'il supprime complètement la barrière entre l'écriture d'une logique logicielle de haut niveau et la manipulation de la tension physique. Merci d'avoir écouté. Prenez soin de vous, tout le monde.
3

Live Coding sur MCU : REPL et mpremote

3m 28s

Révolutionnez votre flux de travail en développement embarqué. Nous couvrons le REPL de MicroPython et l'outil en ligne de commande mpremote pour automatiser les connexions séries et l'exécution en direct.

Télécharger
Salut, c'est Alex de DEV STORIES DOT EU. MicroPython, épisode 3 sur 7. Oublie ton cycle fastidieux de compile, de flash et de reboot. Dans un projet embarqué classique, tu modifies une variable, tu attends plusieurs minutes pour le build, tu écris dans la mémoire flash et tu espères que ça marche. MicroPython contourne complètement ça en te permettant de parler directement à la puce en temps réel. Cet épisode parle du Live Coding sur le MCU en utilisant le REPL et mpremote. Le REPL signifie Read-Eval-Print Loop. C'est un prompt interactif qui tourne directement sur ton microcontrôleur. Tu connectes ta board en USB, tu ouvres un terminal série, tu tapes du code Python, et la puce l'exécute instantanément. Le REPL standard est conçu pour les humains. Il offre l'auto-indentation, l'historique des commandes et l'auto-complétion basique. C'est parfait pour tester un petit pin toggle hardware rapide. Cependant, il y a un deuxième mode appelé le raw REPL. Les gens confondent souvent ça avec une version limitée de MicroPython, mais c'est en fait juste un mode d'input différent, déclenché en envoyant un caractère de contrôle spécifique sur le port série. Le raw REPL désactive l'écho des caractères et l'auto-indentation. Les outils utilisent le raw REPL pour injecter de manière programmatique de gros blocs de code dans le microcontrôleur. Si un script essayait de coller du texte dans le REPL standard, l'auto-indentation pensée pour les humains s'enchaînerait et détruirait complètement le formatage Python. Le raw REPL garantit que le code entre exactement comme il est écrit. Ce qui nous amène à mpremote. C'est l'outil en ligne de commande officiel pour interagir avec les devices MicroPython, et il pilote le raw REPL sous le capot pour faire le gros du travail. Pour le live coding, mpremote offre deux commandes puissantes : run et mount. Tu utilises la commande run pour exécuter un script local depuis ton ordinateur directement sur la board. Tu écris ton code dans ton éditeur de texte préféré, tu ouvres ton terminal, et tu lances mpremote run suivi de ton nom de fichier. Voici le point clé. Le code est envoyé sur la ligne série et exécuté entièrement dans la RAM du microcontrôleur. Il n'est jamais écrit dans la mémoire flash du device. Si tu écris une mauvaise boucle et que tu fais crasher la board, tu fais juste un hard reset de la puce. La flash reste intacte, ce qui économise des cycles d'écriture, et ta boucle de développement prend quelques secondes. Quand ton projet dépasse le stade d'un simple script, tu utilises la commande mount. Cette commande dit à mpremote de prendre un dossier local sur ton PC et de le mapper sur la connexion série. Le microcontrôleur surcharge temporairement son propre stockage et traite ce dossier sur ton ordinateur comme si c'était son filesystem interne. Imagine un scénario où tu écris un driver d'affichage complexe. D'habitude, tu devrais copier le fichier du driver sur la board, lancer ton script principal, observer un glitch à l'écran, éditer le fichier sur ton PC, et le copier à nouveau. Avec la commande mount, le microcontrôleur exécute le driver directement depuis le stockage de ton PC. Tu fais save dans ton éditeur de texte sur ton laptop, tu redémarres le script sur la board, et les changements s'appliquent immédiatement. Tu itères aussi vite que tu tapes, ce qui élimine complètement l'étape de flash de ton workflow. La vraie puissance de MicroPython, ce n'est pas juste la syntaxe Python en elle-même, mais comment des outils comme mpremote effacent la frontière entre ton environnement de développement local et le hardware embarqué physique. C'est tout pour cet épisode. Merci de ton écoute, et continue de développer !
4

Trois lignes pour le WiFi : Le module network

3m 32s

Transformez un microcontrôleur en un nœud IoT connecté. Nous explorons le module network, en détaillant comment se connecter au WiFi en tant que station ou héberger votre propre Access Point.

Télécharger
Bonjour, ici Alex de DEV STORIES DOT EU. MicroPython, épisode 4 sur 7. Connecter un microcontrôleur nu à un réseau Wi-Fi avec du code C traditionnel nécessite généralement des centaines de lignes de boilerplate rien que pour initialiser la radio et gérer le handshake. C'est fastidieux et source d'erreurs. Avec MicroPython, tu peux établir une connexion sans fil en littéralement trois lignes. C'est le rôle du module network, et plus précisément de la classe WLAN. Le module network abstrait les interfaces réseau matérielles sous-jacentes. Pour les opérations Wi-Fi, tu utilises la classe network dot WLAN. Une puce Wi-Fi standard peut fonctionner selon deux rôles distincts. Tu dois définir explicitement le rôle que tu veux lors de la création de l'objet WLAN. Le premier rôle est le mode Station, spécifié par la constante STA underscore IF. Tu utilises le mode Station quand ton hardware doit se connecter en tant que client à un routeur en amont, exactement comme un smartphone qui rejoint un réseau domestique. Le second rôle est le mode Access Point, spécifié par la constante AP underscore IF. Dans ce mode, le microcontrôleur agit lui-même comme un routeur, diffusant son propre réseau sans fil pour que des périphériques externes puissent s'y connecter directement. Le mode Access Point est incroyablement utile quand tu déploies du hardware dans des endroits isolés où aucun réseau externe n'existe, ce qui te permet de te connecter localement pour la configuration. Mettre ta carte en ligne nécessite une séquence spécifique. Tu crées d'abord l'objet WLAN en utilisant la constante du mode Station. Par défaut, la radio Wi-Fi physique est éteinte pour économiser de l'énergie. Tu dois l'allumer en passant True à la méthode active sur ton objet WLAN. Une fois l'interface active, tu invoques la méthode connect avec le nom et le mot de passe de ton réseau sans fil. Voici le point essentiel. La méthode connect est strictement non-blocking. Quand tu l'invoques, MicroPython transmet les credentials au processeur réseau et continue immédiatement l'exécution de ton script. Il ne va délibérément pas attendre que l'authentification réseau se termine. Ce design permet à ton application principale de mettre à jour un affichage ou de lire un capteur pendant que la radio négocie avec le routeur en background. Cependant, si ton code tente d'envoyer des données immédiatement après avoir appelé connect, l'opération va crasher car la carte n'a pas encore réellement de connexion. Tu gères ça en faisant du polling sur l'interface. L'objet WLAN fournit une méthode appelée isconnected, qui renvoie une simple valeur boolean. Le pattern standard est d'écrire une boucle while qui évalue si isconnected est False. À l'intérieur de cette boucle, tu introduis un court délai, comme faire un sleep d'une demi-seconde. L'exécution fait une pause ici, vérifiant l'état du hardware de manière répétée jusqu'à ce que le routeur accepte enfin la connexion et que isconnected renvoie True. Une fois que la boucle se termine, le hardware est officiellement en ligne. Pour vérifier les détails du réseau, tu appelles la méthode ifconfig sur ton objet WLAN. Cette méthode sort une collection de quatre éléments spécifiques : l'adresse IP attribuée, le subnet mask, la gateway, et le serveur DNS principal. Tu peux extraire le premier élément de cette collection et le print dans la console pour voir exactement quelle adresse IP le routeur a accordée à ta carte. La nature non-blocking de la méthode connect signifie que tu es toujours responsable de vérifier l'état du hardware avant d'essayer de router des données sur le réseau. C'est tout pour aujourd'hui. Merci pour ton écoute — va construire un truc cool.
5

Survivre aux contraintes : La RAM et le GC

3m 22s

Maîtrisez l'art d'écrire du code Python économe en mémoire. Nous discutons de la fragmentation du heap, de la pré-allocation de buffers et du garbage collection manuel pour que votre microcontrôleur continue de fonctionner de manière fluide.

Télécharger
Salut, ici Alex de DEV STORIES DOT EU. MicroPython, épisode 5 sur 7. Python adore allouer dynamiquement de la mémoire, créant de nouveaux objets pour chaque calcul. Ça marche parfaitement sur un serveur, mais sur un microcontrôleur, cette habitude finira par faire planter ta carte, te laissant face à une erreur de mémoire même quand tu as apparemment de la RAM disponible. Aujourd'hui, on se concentre sur la survie face aux contraintes : la RAM et le GC. La mémoire où vivent tes objets Python s'appelle le heap. En MicroPython, le heap est incroyablement petit. Quand tu crées des objets, ils prennent des blocs d'espace. Quand ces objets ne sont plus nécessaires, ils sont nettoyés. Ça laisse des trous dans ta mémoire. Avec le temps, à mesure que des objets de différentes tailles sont créés et détruits, ton heap ressemble à un gruyère. C'est ce qu'on appelle la fragmentation du heap. Voici le point crucial. Quand tu as besoin d'allouer un nouvel objet, MicroPython a besoin d'un seul bloc de mémoire contigu pour le caser. Si ton heap est très fragmenté, tu peux avoir vingt kilo-octets de RAM libre au total, mais aucun trou de plus d'un kilo-octet. Si tu demandes deux kilo-octets, ton programme plante. Tu dois arrêter de gaspiller de la RAM, à commencer par tes variables globales. Si tu as des valeurs entières qui ne changent jamais, comme des numéros de pin ou des adresses hardware, ne les assigne pas normalement. MicroPython propose une déclaration spéciale appelée const. Si tu mets ton entier dans cette déclaration const, le compilateur remplace le nom de la variable par le nombre réel partout dans ton code pendant la compilation. Ça empêche complètement la création d'une variable dans la RAM. Ensuite, regarde tes boucles. La création dynamique d'objets dans une boucle rapide est la cause principale de fragmentation. Tu lis un capteur sur un bus SPI cent fois par seconde. Si tu utilises une commande read standard, MicroPython crée une toute nouvelle séquence de bytes en mémoire pour chaque lecture. Ces objets s'accumulent rapidement, remplissant les trous et détruisant ton espace contigu. Au lieu de créer de nouveaux objets, réutilise ceux que tu as déjà. Avant que ta boucle commence, crée un bytearray de la bonne taille. Un bytearray est un bloc de mémoire mutable. Ensuite, à l'intérieur de ta boucle, utilise une méthode hardware appelée readinto. Tu passes ton bytearray préexistant à readinto. Le hardware balance les données du capteur directement dans ce même bloc de mémoire, en écrasant les anciennes données. Tu traites les données, la boucle se répète, et aucune nouvelle mémoire n'est allouée. Même en codant proprement, la création de certains objets est inévitable, ce qui nous amène au Garbage Collector. Par défaut, le Garbage Collector s'exécute automatiquement quand une allocation de mémoire échoue. Il scanne les objets inutilisés et libère leur espace. Cependant, ce processus prend du temps. S'il se déclenche automatiquement pendant une opération critique en temps, ton code va se mettre en pause de façon imprévisible. Pour régler ça, tu prends le contrôle. Appelle explicitement la fonction collect du module gc. Trouve un endroit sûr dans ton code, comme la fin de ta boucle principale, et déclenche la collection à cet endroit. Ça permet de garder le heap propre selon ton propre planning, évitant ainsi les retards inattendus. En Python desktop, la mémoire est quelque chose que le langage gère pour toi, mais en MicroPython, la mémoire est un conteneur physique que tu dois remplir à la main. C'est tout pour cet épisode. Merci pour ton écoute, et continue à développer !
6

Compilé vs Gelé : Déploiement en production

3m 29s

Apprenez à déployer des applications massives sans manquer de RAM. Nous explorons les fichiers .mpy pré-compilés et le gel du bytecode directement dans la mémoire flash du microcontrôleur.

Télécharger
Salut, c'est Alex de DEV STORIES DOT EU. MicroPython, épisode 6 sur 7. Tu uploades un fichier Python parfaitement valide sur ton microcontrôleur, tu tapes import, et la carte plante instantanément avec une erreur out-of-memory. Le code en lui-même est bon, mais le processus de chargement vient de consommer toute ta mémoire disponible. Pour corriger ça, il faut contourner le compilateur de l'appareil, ce qui nous amène au code compilé versus le code frozen pour les déploiements en production. Quand tu lances un script Python standard sur un ordi de bureau, la mémoire est pratiquement infinie. Sur un microcontrôleur, la mémoire est strictement contrainte. Quand tu glisses un fichier source Python standard sur ton appareil et que tu lances la commande import, MicroPython ne se contente pas de lire le fichier. Le compilateur se lance directement là, sur le microcontrôleur. Il parse le texte, construit un abstract syntax tree, et génère du bytecode. Chacune de ces étapes alloue de la mémoire en RAM. Prends l'exemple d'un gros framework IoT qui gère le réseau, la sécurité et les données des capteurs. Si tu essaies d'importer cet énorme module depuis un fichier source standard, le compilateur va probablement épuiser la mémoire heap disponible avant même que la première ligne de ton application ne s'exécute. Le pic d'utilisation de la RAM pendant la phase de compilation tue le process. Pour contourner ça, tu dois retirer l'étape de compilation du microcontrôleur. Tu fais ça en pré-compilant ton code avec un outil de bureau appelé le cross-compiler, ou mpy-cross. Tu lances cet outil sur ton ordi principal. Il ingère ton fichier source Python et sort un fichier compilé avec une extension M-P-Y. Ce fichier contient le bytecode pré-généré. Quand tu transfères ce fichier compilé sur le microcontrôleur et que tu l'importes, MicroPython reconnaît le format et saute complètement la phase de compilation. Tu évites complètement le pic de mémoire causé par le compilateur. C'est là que ça devient intéressant. Même si la pré-compilation t'évite le pic de mémoire de la compilation, le microcontrôleur charge quand même le bytecode depuis le file system vers la RAM pour l'exécuter. Si ton framework IoT est assez gros, le bytecode à lui seul consommera encore trop de RAM, te laissant très peu d'espace pour les variables et les données de ton application. Quand les fichiers pré-compilés ne suffisent pas, l'étape finale c'est le freezing du bytecode. Le freezing, ça veut dire intégrer le code compilé directement dans le firmware MicroPython. Au lieu de copier le fichier compilé sur le file system de la carte, tu le places dans un répertoire modules spécifique au sein du code source de MicroPython sur ton ordi. Tu rebuilds ensuite toute l'image du firmware MicroPython depuis zéro et tu flashes ce firmware custom sur ta carte. Ça change exactement la façon dont le code est exécuté. Quand tu importes un module frozen, MicroPython ne copie pas du tout le bytecode en RAM. Comme le code est intégré au firmware, il réside en permanence dans la mémoire flash du microcontrôleur. MicroPython exécute le bytecode directement depuis la flash. En l'exécutant depuis la flash, l'empreinte RAM de l'import de cet énorme framework IoT tombe à presque zéro. Toute ta RAM reste entièrement libre pour traiter des données en temps réel. La différence fondamentale, c'est l'endroit où ton code vit pendant qu'il tourne. La pré-compilation économise de la mémoire pendant l'étape d'import, mais le freezing économise de la mémoire pour toute la durée de vie du programme en forçant l'exécution à se faire entièrement en mémoire flash. Si tu veux aider à soutenir l'émission, tu peux chercher DevStoriesEU sur Patreon. C'est tout pour cet épisode. Merci d'avoir écouté, et continue de coder !
7

Déterminisme en Python : Timers et Interruptions

3m 16s

Obtenez un comportement temps réel dans MicroPython en utilisant des timers matériels et des routines de service d'interruption. Nous couvrons les règles strictes de l'écriture d'ISRs et comment éviter l'allocation de mémoire.

Télécharger
Salut, c'est Alex de DEV STORIES DOT EU. MicroPython, épisode 7 sur 7. Écrire une hardware interrupt service routine dans un langage de haut niveau avec un garbage collector, ça donne l'impression de chercher un crash système immédiat. Mais MicroPython le permet, à condition que tu respectes une règle d'or : zéro allocation mémoire. Cet épisode parle du déterminisme en Python : les timers et les interrupts. Quand tu as besoin de lire un capteur exactement mille fois par seconde, une boucle standard avec une fonction sleep va échouer. Le garbage collection et les tâches en background introduisent des délais aléatoires, ce qui détruit ton timing. Pour obtenir un comportement déterministe, tu as besoin d'un hardware timer. En utilisant le module machine, tu configures un objet Timer pour qu'il se déclenche périodiquement et exécute une fonction callback spécifique. Ce callback est ton Interrupt Service Routine, ou ISR. Les timers déclenchent des soft ou des hard interrupts. Un soft interrupt est planifié par la machine virtuelle MicroPython quand c'est sûr de le faire. Tu écris une soft ISR exactement comme du code Python normal. Elle peut créer des objets, faire des append sur des listes, et gérer des floats. L'inconvénient, c'est la latence. Si le garbage collector est en train de tourner quand le timer se déclenche, ton soft interrupt fait simplement la queue. Si tu as besoin d'une précision de timing stricte, tu configures le timer pour déclencher un hard interrupt. Un hard interrupt arrête immédiatement le processeur. Il bypasse la machine virtuelle et exécute ton callback instantanément. C'est là qu'est le point clé. Parce qu'un hard interrupt préempte l'état actuel du système, il pourrait interrompre le memory manager lui-même. Si ton ISR essaie d'allouer de la mémoire sur la heap pendant que la heap est en train d'être modifiée, le microcontrôleur va crasher. Cette contrainte dicte exactement comment tu écris tes hard ISRs. Tu ne peux allouer aucune mémoire. Pas de création de listes. Pas de construction de dictionnaires. Pas de manipulation de strings. Même les calculs en virgule flottante sont strictement interdits, parce qu'en Python, chaque float est un nouvel objet alloué sur la heap. Ton code doit s'exécuter vite, se baser sur des calculs d'entiers, et utiliser des structures mémoire préexistantes. Imagine un scénario où un hardware timer se déclenche à 1000 Hertz. Chaque milliseconde, la hard ISR lit la valeur d'un capteur. Puisque tu ne peux pas faire un append de la lecture dans une liste, tu dois pré-allouer ton stockage avant de démarrer le timer. Tu crées un bytearray de mille bytes dans ton programme principal. Tu définis aussi une variable d'index globale. Quand le timer se déclenche, l'ISR lit le capteur. Elle met à jour l'index global, stocke l'entier brut dans le bytearray à cette position, et quitte. L'espace mémoire a été entièrement réservé à l'avance. L'interrupt le met juste à jour sur place, garantissant une exécution sans jitter. Une fois que le buffer est plein, l'ISR doit passer les données au programme principal. Tu ne peux pas déclencher une fonction de traitement de données complexe directement depuis la hard ISR. À la place, tu utilises micropython dot schedule. Cette fonction prend une référence vers un callback et le met dans la queue pour s'exécuter dès que le système retourne à un état d'exécution soft et sûr. Gérer des hardware interrupts te force à arrêter de penser à Python comme un pool de ressources infini, et à commencer à traquer exactement quand et où ta mémoire est assignée. Regarde la documentation officielle de MicroPython pour les comportements spécifiques des interrupts de ton port hardware, et essaie de casser intentionnellement les règles de mémoire sur ta propre board pour voir comment le système réagit. Si tu veux suggérer des sujets pour notre prochaine série, passe sur devstories dot eu. Je voudrais prendre un moment pour te remercier d'avoir écouté — ça nous aide beaucoup. Passe une très bonne journée !