<rss version="2.0">
 <channel>
  <title>Une Tanche</title>
  <link>https://ylbn.fr/</link>
  <description>Recent content</description>
  <generator>Zine -- https://zine-ssg.io</generator>
  <language>fr-fr</language>
  <lastBuildDate>Fri, 10 Jul 2026 16:48:14 +0000</lastBuildDate>
  
   <item>
    <title>Note sur les moteurs électriques synchrone</title>
    <description>&lt;div class=&quot;block warning&quot;&gt;&lt;h1&gt;Attention&lt;/h1&gt;&lt;p&gt;Cet article est amené à évoluer et être complété.&lt;/p&gt;&lt;/div&gt;&lt;h1 id=&quot;intro&quot;&gt;Intro&lt;/h1&gt;&lt;p&gt;Dans le cadre pro, j’ai réalisé une veille conséquente quant au pilotage de moteurs synchrones, du coup j’écris cet article comme un mémo. Je ne suis pas un spécialiste du contrôle moteur, encore moins de la conception de moteurs électriques, donc si vous trouvez une erreur n’hésitez pas à m’en faire part.&lt;/p&gt;&lt;p&gt;Je me suis intéressé à trois technologies de moteur synchrone:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Les moteurs à reluctance variable (SynRM)&lt;/li&gt;&lt;li&gt;Les moteurs à aimants permanents (PMSM)&lt;/li&gt;&lt;li&gt;Les moteurs à reluctance variable assistés par aimants permanents (PMa_SynRM)&lt;/li&gt;&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Attention&lt;/strong&gt;, ne pas confondre les machines à reluctance variable (SynRM) avec les machines à double saillance (SRM).&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Pour rédiger ce mémo, je me suis appuyé sur les travaux suivants:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;la thèse &lt;a href=&quot;https://hal.univ-lorraine.fr/tel-03699829v1&quot; target=&quot;_blank&quot;&gt;High-Performance Nonlinear Control for Permanent Magnet Assisted Synchronous Reluctance Motor (HAL Id: tel-03699829)&lt;/a&gt; de &lt;em&gt;Songklod Sriprang&lt;/em&gt; publiée en 2022 (Université de Lorraine)&lt;/li&gt;&lt;li&gt;la thèse &lt;a href=&quot;https://theses.hal.science/tel-04142255v1&quot; target=&quot;_blank&quot;&gt;Modélisation et commande avancées d’une génératrice synchrone à réluctance variable auto-excitée (HAL Id: tel-04142255)&lt;/a&gt; de &lt;em&gt;Laurent Schuller&lt;/em&gt; publiée en 2023 (INSA Lyon)&lt;/li&gt;&lt;li&gt;la thèse &lt;a href=&quot;https://theses.hal.science/tel-00814276v1&quot; target=&quot;_blank&quot;&gt;Contribution à la commande vectorielle sans capteur mécanique des machines synchrones à aimants permanents (MSAP) (HAL Id: tel-00814276)&lt;/a&gt; de &lt;em&gt;Amor Khlaief&lt;/em&gt; publié en 2013 (Aix-Marseille Université)&lt;/li&gt;&lt;li&gt;le papier de recherche &lt;a href=&quot;https://hal.science/hal-04887233v1&quot; target=&quot;_blank&quot;&gt;Vector control strategies for synchronous reluctance motor: constant current control, MTPA, MTPW and MPFC (HAL Id: hal-04887233)&lt;/a&gt; de &lt;em&gt;Yassine Zahraoui, Mohamed Moutchou, Souad Tayane&lt;/em&gt; publiée en 2025 (Hassan II University)&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;motor_type&quot;&gt;Dénomination des différents type de moteur&lt;/h2&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;Type de moteur&lt;/th&gt;&lt;th&gt;Anglais&lt;/th&gt;&lt;th&gt;Français&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Moteur synchrone à reluctance variable&lt;/td&gt;&lt;td&gt;SynRM, SynRel ou SynR&lt;/td&gt;&lt;td&gt;MSRV&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Moteur synchrone à reluctance variable assisté par aimants permanents&lt;/td&gt;&lt;td&gt;PMa-SynRM ou IPM-SynRM&lt;/td&gt;&lt;td&gt;??&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Moteur synchrone à aimants permanents&lt;/td&gt;&lt;td&gt;PMSM&lt;/td&gt;&lt;td&gt;MSAP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Moteur synchrone à aimants permanents intérieurs&lt;/td&gt;&lt;td&gt;IPMSM&lt;/td&gt;&lt;td&gt;??&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Moteur synchrone à aimants permanents en surface&lt;/td&gt;&lt;td&gt;SPMSM&lt;/td&gt;&lt;td&gt;??&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;hr&gt;&lt;h1 id=&quot;motorType&quot;&gt;Architecture des moteurs synchrone&lt;/h1&gt;&lt;p&gt;Ces moteurs, qu’ils soient à aimants permanents ou à reluctance variable possèdent un rotor non bobiné et un stator composé de N phases. Dans mon cas, je ne m’intéresse qu’aux machines à trois phases (triphasé). Ces technologies se distinguent de part la constitution de leur rotor:&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ylbn.fr/blog/electrical_synchronous_motors/motor.png&quot; width=&quot;291&quot; height=&quot;291&quot;&gt;
&lt;figcaption&gt;Composition d’un moteur synchrone&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ylbn.fr/blog/electrical_synchronous_motors/motor_classification.png&quot; width=&quot;929&quot; height=&quot;397&quot;&gt;
&lt;figcaption&gt;Illustration de la composition des rotors (thèse de &lt;em&gt;Songklod Sriprang&lt;/em&gt;)&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;Sur le schéma ci-dessus, on retrouve les aimants permanents en violet et les barrières de flux sont indiquées par les zones blanches à l’intérieur du rotor. Comme on peut le voir, les machines MSAP ont un rotor avec N aimants permanent et sans aucunes barrières de flux. À l’inverse les machines à reluctance variable ne possèdent pas d’aimants mais ont N barrières de flux réparties tout autour du rotor. Entre les deux on trouve différentes nuances de ces deux technologies.&lt;/p&gt;&lt;p&gt;Je n’ai pas trouvé de tableaux détaillant exactement les avantages/inconvénients de chacune de ces technologies. Voici les informations que j’ai pu regrouper:&lt;/p&gt;&lt;table&gt;&lt;tr&gt;&lt;th&gt;Type de moteur&lt;/th&gt;&lt;th&gt;Avantages&lt;/th&gt;&lt;th&gt;Inconvénients&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SynRM&lt;/td&gt;&lt;td&gt;absence d’aimant, robustesse, indépendance à la température&lt;/td&gt;&lt;td&gt;encombrement, facteur de puissance, ondulation couple&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PMSM&lt;/td&gt;&lt;td&gt;Très bon couple, rendement, encombrement, rapport poids/puissance&lt;/td&gt;&lt;td&gt;coûts, aimants permanents, sensible à la température, désaimentation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PMa_SynRM&lt;/td&gt;&lt;td&gt;Haut rendement à haute et basse vitesse, moins oscillation de couple que SynRM pure&lt;/td&gt;&lt;td&gt;aimants permanents&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;h1 id=&quot;equation&quot;&gt;Équations et Models&lt;/h1&gt;&lt;p&gt;Les équations suivantes, sont exprimées dans le repère &lt;em&gt;dq0&lt;/em&gt; obtenu à partir de la transformée de &lt;a href=&quot;https://fr.wikipedia.org/wiki/Transform%C3%A9e_de_Park&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;Park&lt;/strong&gt;&lt;/a&gt; conservant les amplitudes (basée sur la transformée de Clarke).&lt;/p&gt;&lt;p&gt;Ces différentes technologies de moteurs sont régies par les mêmes équations:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;\omega_e = npp \times \omega
&lt;/script&gt;&lt;script type=&quot;math/tex&quot;&gt;V_d = R \times i_d + L_d \times \frac{d}{dt} i_d - \omega_e \times L_q \times i_q
&lt;/script&gt;&lt;script type=&quot;math/tex&quot;&gt;V_q = R \times i_q + L_q \times \frac{d}{dt} i_q + \omega_e (L_d \times i_d + \Psi_m)
&lt;/script&gt;&lt;script type=&quot;math/tex&quot;&gt;C_{em} = \frac{3}{2} npp (\Psi_m i_q + (L_d - L_q)i_d i_q)
&lt;/script&gt;&lt;script type=&quot;math/tex&quot;&gt;C_m = C_{em} - B_m \omega - J_m \frac{d}{dt}\omega - C_r
&lt;/script&gt;&lt;p&gt;avec:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;script type=&quot;math/tex&quot;&gt;\omega&lt;/script&gt;: la vitesse de rotation mécanique du rotor (rad/s)&lt;/p&gt;&lt;p&gt;&lt;script type=&quot;math/tex&quot;&gt;\omega_e&lt;/script&gt;: la vitesse de rotation électrique du rotor (rad/s)&lt;/p&gt;&lt;p&gt;&lt;em&gt;npp&lt;/em&gt;: le nombre de paires de pôles du rotor&lt;/p&gt;&lt;p&gt;&lt;script type=&quot;math/tex&quot;&gt;\Psi_m&lt;/script&gt;: Le flux maximum de l’aimant (Wb) (Max Flux Linkage)&lt;/p&gt;&lt;p&gt;lié aux aimants permanents (égal à 0 pour les machines SynRM)&lt;/p&gt;&lt;p&gt;&lt;em&gt;Bm&lt;/em&gt;: frottements visqueux liés au rotor&lt;/p&gt;&lt;p&gt;&lt;em&gt;Jm&lt;/em&gt;: Moment d’inertie du rotor&lt;/p&gt;&lt;p&gt;&lt;em&gt;Cr&lt;/em&gt;: Le couple résistant externe&lt;/p&gt;&lt;/blockquote&gt;&lt;div class=&quot;block warning&quot;&gt;&lt;h1&gt;Important&lt;/h1&gt;&lt;p&gt;On trouve un lien entre &lt;script type=&quot;math/tex&quot;&gt;\Psi_m&lt;/script&gt; et Ke (backEMF constant) la constante de tension liée à la &lt;em&gt;fem&lt;/em&gt; tel que:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;\Psi_m = \frac{K_e}{npp}
&lt;/script&gt;&lt;p&gt;&lt;strong&gt;Ke doit être référencé entre phase et neutre.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://fr.mathworks.com/help/sps/ref/pmsm.html?s_tid=srchtitle_support_results_1_PMSM&quot; target=&quot;_blank&quot;&gt;Source: mathworks&lt;/a&gt; au chapitre “Alternative Flux linkage parametrization”.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;On peut réécrire ces équations pour les mettre sous la forme &lt;em&gt;dx/dt = …&lt;/em&gt; afin de pouvoir facilement les exploiter dans un &lt;a href=&quot;https://fr.wikipedia.org/wiki/Repr%C3%A9sentation_d%27%C3%A9tat&quot; target=&quot;_blank&quot;&gt;modèle de représentation d’états&lt;/a&gt;:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;\frac{di_d}{dt} = \frac{1}{L_d}(V_d - R i_d + \omega_e * L_q  i_q)
&lt;/script&gt;&lt;script type=&quot;math/tex&quot;&gt;\frac{di_q}{dt} = \frac{1}{L_q}(V_q - R i_q + \omega_e L_d i_d - \omega_e \Psi_m)
&lt;/script&gt;&lt;script type=&quot;math/tex&quot;&gt;\frac{d\omega_e}{dt} = \frac{3}{2}\frac{1}{J_m}(npp^{2} (\Psi_m i_q + (L_d - L_q) i_d i_q) - B_m \omega_e - C_r npp)
&lt;/script&gt;&lt;h2 id=&quot;part_msap&quot;&gt;Particularité MSAP&lt;/h2&gt;&lt;p&gt;Dans le cas d’une machine à aimants permanents montés en surface, la saillance est nulle, c’est-à-dire que &lt;em&gt;Ld&lt;/em&gt; = &lt;em&gt;Lq&lt;/em&gt;. Dans ce cas l’équation de couple devient:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;\frac{d\omega_e}{dt} = \frac{3}{2}\frac{1}{J_m}(npp^{2} (\Psi_m i_q) - B_m \omega_e - C_r npp)
&lt;/script&gt;&lt;p&gt;On remarque que le couple est directement lié à &lt;em&gt;Iq&lt;/em&gt; et que le courant &lt;em&gt;Id&lt;/em&gt; ne fera que générer des pertes.&lt;/p&gt;&lt;h2 id=&quot;part_synrm&quot;&gt;Particularité SynRM&lt;/h2&gt;&lt;p&gt;En ce qui concerne les machines à reluctance variable, elles ne possèdent pas d’aimants donc &lt;script type=&quot;math/tex&quot;&gt;\Psi_m = 0&lt;/script&gt;. Ce qui nous donne l’équation de couple suivante:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;\frac{d\omega_e}{dt} = \frac{3}{2}\frac{1}{J_m}(npp^{2} ((L_d - L_q) i_d i_q) - B_m \omega_e - C_r npp)
&lt;/script&gt;&lt;p&gt;Donc le couple est proportionnel à &lt;em&gt;Id x Iq&lt;/em&gt;.&lt;/p&gt;&lt;div class=&quot;block note&quot;&gt;&lt;h1&gt;Note: Changement de repère&lt;/h1&gt;&lt;p&gt;Pour passer du repère triphasé au repère &lt;em&gt;dq0&lt;/em&gt; (repère du rotor), on utilise la transformée de Park, mais on peut décomposer ça en deux étapes:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;abc&lt;/strong&gt; (triphasé) –&gt; &lt;script type=&quot;math/tex&quot;&gt;\alpha \beta&lt;/script&gt; (stator) –&gt; &lt;em&gt;dq0&lt;/em&gt; (rotor)&lt;/p&gt;&lt;p&gt;En fonction de la transformée utilisée pour passer de &lt;em&gt;abc&lt;/em&gt; vers &lt;script type=&quot;math/tex&quot;&gt;\alpha \beta&lt;/script&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;concordia: conservation des puissances&lt;/li&gt;&lt;li&gt;Parke: conservation des amplitudes&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Dans le cadre de la mise au point d’algorithme de régulation, il est plus intéressant de conserver les amplitudes que les puissances. Ainsi on a: &lt;script type=&quot;math/tex&quot;&gt;V_{d_{max}} = \frac{V_{abc_{max}}}{2}&lt;/script&gt;&lt;/p&gt;&lt;div class=&quot;block warning&quot;&gt;&lt;h1&gt;Attention:&lt;/h1&gt;&lt;p&gt;Ces transformées ne sont utilisables que si les courants sont équilibrés. Ce qu’on suppose être le cas pour les moteurs cablés en étoile (le courant du neutre fictif est null).&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;block note&quot;&gt;&lt;h1&gt;Note: Les signaux PWM&lt;/h1&gt;&lt;p&gt;Pour générer ces signaux, deux possibilités:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;la méthode sinus: on génère trois signaux sinusoïdaux déphasés de 120° chacun&lt;/li&gt;&lt;li&gt;la méthode du &lt;a href=&quot;https://fr.wikipedia.org/wiki/M%C3%A9thode_du_vecteur_spatial&quot; target=&quot;_blank&quot;&gt;vecteur spatial (SVPWM)&lt;/a&gt;: on génère un signal qui ressemble à un sinus mais avec deux lobs. Cette méthode permet de réduire d’environs 15% la tension de bus maximum requise.&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;h1 id=&quot;cmd&quot;&gt;Commande des moteurs synchrone&lt;/h1&gt;&lt;p&gt;Dans ce chapitre j’essaie de répertorier les différents modes de pilotage des moteurs synchrones. Il existe deux grandes familles de “&lt;em&gt;méthode de contrôle&lt;/em&gt;”, la méthode scalaire et vectorielle.&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ylbn.fr/blog/electrical_synchronous_motors/motor-cmd.png&quot; width=&quot;431&quot; height=&quot;271&quot;&gt;
&lt;figcaption&gt;Les différentes méthodes de commande&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;Pour l’instant, je ne me suis intéressé qu’aux méthodes scalaire et FOC. Mais la méthode &lt;a href=&quot;https://fr.wikipedia.org/wiki/Commande_directe_du_couple&quot; target=&quot;_blank&quot;&gt;DTC&lt;/a&gt; semble aussi intéressante, en particulier par le fait qu’elle ne nécessite pas de connaitre la position du rotor (on travaille dans le repère du stator).&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Je ne me suis intéressé qu’à la commande en vitesse de ces moteurs.&lt;/strong&gt;&lt;/p&gt;&lt;h2 id=&quot;msap&quot;&gt;Moteur à Aimants Permanents&lt;/h2&gt;&lt;p&gt;J’ai trouvé deux manières de piloter les MSAP:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;En boucle ouverte via la méthode Vbyf constant&lt;/li&gt;&lt;li&gt;En boucle fermée en contrôlant Id et Iq&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Scalaire: VbyF&lt;/h3&gt;&lt;p&gt;Le principe de cette commande est de maintenir un ratio constant entre l’amplitude et la fréquence de la tension de chacune des phases. &lt;a href=&quot;https://community.nxp.com/t5/Model-Based-Design-Toolbox-MBDT/Module-5-V-F-Scalar-Control/m-p/726087&quot; target=&quot;_blank&quot;&gt;Ce post sur le forum NXP&lt;/a&gt; explique de manière détaillée les principes de ce mode de commande pour un moteur synchrone à aimants permanents.&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ylbn.fr/blog/electrical_synchronous_motors/motor-scalar.png&quot; width=&quot;491&quot; height=&quot;166&quot;&gt;
&lt;figcaption&gt;Schéma de la commande scalaire&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;div class=&quot;block note&quot;&gt;&lt;h1&gt;Remarque suite à mes essais en simulation&lt;/h1&gt;&lt;p&gt;J’ai fait de nombreux essais de simulation sur un moteur MSAP avec ce mode de pilotage.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;La stabilité du moteur n’est pas garantie et atteindre sa vitesse nominale sans connaitre la position du rotor peut être impossible. En effet, si la différence entre la position estimée du rotor et sa position réelle est trop grande, le moteur devient instable. Il est possible d’améliorer nettement la stabilité de ce dernier en utilisant la position réelle du rotor (nécessite un capteur) pour la transformée &lt;em&gt;dq0&lt;/em&gt; inverse à la place de la position souhaitée.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Ce mode de pilotage ne permet pas de contrôler les courants &lt;em&gt;Id&lt;/em&gt; et &lt;em&gt;Iq&lt;/em&gt;. De ce fait, si on ajoute un couple résistant sur le rotor, le courant &lt;em&gt;Id&lt;/em&gt; s’envole et &lt;em&gt;Iq&lt;/em&gt; plafonne à des valeurs assez faibles. Or le couple d’un MSAP est directement proportionnel à &lt;em&gt;Iq&lt;/em&gt;. Donc on se retrouve avec un  rendement désastreux.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ylbn.fr/blog/electrical_synchronous_motors/idiq_synrm.png&quot; width=&quot;741&quot; height=&quot;481&quot;&gt;
&lt;figcaption&gt;Iq &amp; Iq SynRM VbyF&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;/div&gt;&lt;h3&gt;Commande vectorielle FOC&lt;/h3&gt;&lt;p&gt;La commande vectorielle FOC consiste à asservir &lt;em&gt;Id&lt;/em&gt; et &lt;em&gt;Iq&lt;/em&gt; afin de minimiser les pertes dans le moteur. Comme on l’a vu précédemment, dans le cas d’une machine à aimants montés en surface, seul &lt;em&gt;Iq&lt;/em&gt; permet de générer un couple. On va donc chercher à minimiser &lt;em&gt;Id&lt;/em&gt; et maximiser &lt;em&gt;Iq&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ylbn.fr/blog/electrical_synchronous_motors/motor-msap-foc.png&quot; width=&quot;656&quot; height=&quot;330&quot;&gt;
&lt;figcaption&gt;Commande FOC&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;h3&gt;Commande vectorielle DTC&lt;/h3&gt;&lt;p&gt;Sujet à creuser. Mais pour faire simple d’après &lt;a href=&quot;https://fr.wikipedia.org/wiki/Commande_directe_du_couple&quot; target=&quot;_blank&quot;&gt;Wikipedia&lt;/a&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt;pas besoin de connaitre la position du rotor&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt;algorithme de contrôle très simple&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt;nécessite une fréquence d’exécution très élevée (~100kHz)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;ul&gt;&lt;li&gt;La fréquence de découpage est variable.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;msrv&quot;&gt;Moteur à Reluctance Variable&lt;/h2&gt;&lt;h3&gt;Commande scalaire VbyF&lt;/h3&gt;&lt;p&gt;J’ai trouvé assez peu d’informations sur ce mode de pilotage pour une MSRV. Le peu que j’ai trouvé indique que ce mode de pilotage entraine d’importantes oscillations du couple et donc de possible instabilités du moteur.&lt;/p&gt;&lt;h3&gt;Commande vectorielle FOC&lt;/h3&gt;&lt;p&gt;Comme pour le moteur MSAP on cherche, avec ce mode de contrôle, à asservir les courants &lt;em&gt;Id &amp; Iq&lt;/em&gt;. Mais contrairement à la MSAP pour les machines à reluctance variable, le couple est proportionnel à &lt;em&gt;Id &amp; Iq&lt;/em&gt;.&lt;/p&gt;&lt;div class=&quot;block note&quot;&gt;&lt;h1&gt;Note&lt;/h1&gt;&lt;p&gt;On note &lt;script type=&quot;math/tex&quot;&gt;\delta&lt;/script&gt; l’angle correspondant à &lt;script type=&quot;math/tex&quot;&gt;tan(\delta)=\frac{i_q}{i_d}&lt;/script&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;Il existe donc différentes méthodes de régulation de ces courants:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;MTPA: Maximum Torque Per Ampere&lt;/p&gt;&lt;p&gt;Cette méthode consiste à fixer l’angle &lt;script type=&quot;math/tex&quot;&gt;\delta = \pm \pi/4&lt;/script&gt;. Elle fonctionne pour les vitesses de rotation inférieures ou égales à la vitesse nominale.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;MTPW: Maximum Torque Per Weber (parfois aussi noté MTPV –&gt; V pour volt)&lt;/p&gt;&lt;p&gt;En mode MTPW on fixe &lt;script type=&quot;math/tex&quot;&gt;\frac{i_q}{i_d}=\pm\frac{L_d}{L_q}&lt;/script&gt; soit &lt;script type=&quot;math/tex&quot;&gt;\delta = atan(\frac{L_d}{L_q})&lt;/script&gt;. Ce mode de pilotage permet de piloter le moteur à une vitesse supérieure à sa vitesse nominale.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;MPFC: Maximum Power Factor Control&lt;/p&gt;&lt;p&gt;Je ne suis pas entré dans les détails de ce mode de pilotage qui consiste à calculer &lt;em&gt;Id &amp; Iq&lt;/em&gt; de façon à obtenir le facteur de puissance désiré.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;block note&quot;&gt;&lt;h1&gt;Bilan&lt;/h1&gt;&lt;p&gt;Ces trois techniques ont des performances similaires. MTPW et MTPC permettent de réduire légèrement l’oscillation de couple par rapport à MTPA.&lt;/p&gt;&lt;/div&gt;&lt;h3&gt;Commande vectorielle DTC&lt;/h3&gt;&lt;p&gt;Idem MSAP.&lt;/p&gt;&lt;h2 id=&quot;pmasynrm&quot;&gt;PMa-SynRM&lt;/h2&gt;&lt;h3&gt;Commande scalaire&lt;/h3&gt;&lt;p&gt;Je n’ai encore rien trouvé à ce sujet.&lt;/p&gt;&lt;h3&gt;Commande vectorielle FOC&lt;/h3&gt;&lt;p&gt;Je n’ai trouvé qu’un exemple basé sur MTPA. &lt;strong&gt;Attention&lt;/strong&gt;, MTPA pour un moteur PMA-SynRM ne correspond pas à la même méthode que pour les moteurs à reluctance variable!&lt;/p&gt;&lt;p&gt;Pour résumer, cette méthode vise à maximiser le couple et minimiser les pertes par effet Joule:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;Maximiser: C_em = \frac{3}{2}npp(\Psi_m i_q + (L_d-L_q)i_di_q)
&lt;/script&gt;&lt;script type=&quot;math/tex&quot;&gt;Minimiser: Pertes = R(i_d^2 + i_q^2)
&lt;/script&gt;&lt;p&gt;On peut donc exprimer les pertes en fonction de &lt;em&gt;Iq&lt;/em&gt;:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;Pertes(i_q) = R(\frac{2}{3}\frac{C_em}{npp((L_d-L_q)i_q+\Psi_m)}+i_q^2)
&lt;/script&gt;&lt;p&gt;Ensuite à partir de la dérivée de cette fonction par rapport à &lt;em&gt;Iq&lt;/em&gt; et grâce à la méthode de &lt;a href=&quot;https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Newton&quot; target=&quot;_blank&quot;&gt;Newton-Raphson&lt;/a&gt;, on peut déterminer la valeur optimale de &lt;em&gt;Iq&lt;/em&gt; en fonction du couple souhaité.&lt;/p&gt;&lt;p&gt;Enfin on calcule &lt;em&gt;Id&lt;/em&gt; à partir du &lt;em&gt;Iq optimal&lt;/em&gt; via:&lt;/p&gt;&lt;script type=&quot;math/tex&quot;&gt;i_d = \frac{2}{3}\frac{C_em}{npp((L_d-L_q)i_q+Ke)}
&lt;/script&gt;&lt;p&gt;Pour l’implémentation sur cible, soit on arrive à mettre le résultat sous forme polynomiale, soit on fait une table de référence.&lt;/p&gt;&lt;h1 id=&quot;rpos&quot;&gt;Position du rotor&lt;/h1&gt;&lt;p&gt;Comme on a pu le voir dans les précédents chapitres, la connaissance de la position exacte du rotor est cruciale dans les algorithmes FOC. Il faut donc répondre aux deux problématiques suivantes:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Comment calibrer le capteur de position&lt;/li&gt;&lt;li&gt;Comment faire pour se passer de capteur de position&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;calib&quot;&gt;Calibration de la position du rotor&lt;/h2&gt;&lt;p&gt;TODO&lt;/p&gt;&lt;h2 id=&quot;sscapteur&quot;&gt;Rotor sans capteur&lt;/h2&gt;&lt;p&gt;TODO&lt;/p&gt;</description>
    <link>https://ylbn.fr/blog/electrical_synchronous_motors/</link>
    <pubDate>Fri, 10 Jul 2026 00:00:00 +0000</pubDate>
    <guid>https://ylbn.fr/blog/electrical_synchronous_motors/</guid>
   </item>
  
   <item>
    <title>Rust sur mcu: Écriture d&apos;un driver</title>
    <description>&lt;h1 id=&quot;intro&quot;&gt;Intro&lt;/h1&gt;&lt;p&gt;Suite à &lt;a href=&quot;https://ylbn.fr/blog/rust_embedded_1/&quot;&gt;l’article précédent&lt;/a&gt; où j’ai mis en place l’environnement de développement et pris en main les crates de base, je continue m’a découverte de RUST avec à la conception d’un driver très simple.&lt;/p&gt;&lt;p&gt;Les objectifs sont:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;utiliser les interruptions&lt;/li&gt;&lt;li&gt;Créer une interface permettant d’utiliser un périphérique matériel&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Pour ce faire je vais implémenter une api de délai non bloquant utilisant le périphérique &lt;strong&gt;SYSTICK&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;L’idée est de créer une api qui ressemble à:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt; &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;mon_timer&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

 &lt;span class=&quot;constructor constant&quot;&gt;mon_timer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant_builtin&quot;&gt;250&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

 &lt;span class=&quot;keyword&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;mon_timer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;expired&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; == &lt;span class=&quot;constant_builtin&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;constructor constant&quot;&gt;mon_timer&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant_builtin&quot;&gt;543&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;   
         &lt;span class=&quot;constructor constant function&quot;&gt;led_toggle&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&quot;config&quot;&gt;Configuration du Systick&lt;/h1&gt;&lt;p&gt;Pour la suite j’utiliserai le crate hal &lt;a href=&quot;https://github.com/stm32-rs/stm32l0xx-hal&quot; target=&quot;_blank&quot;&gt;stm32l0-hal&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;En partant du fichier &lt;code&gt;main.rs&lt;/code&gt; suivant:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m_rt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;panic_abort&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;stm32l0xx_hal&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;pac&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;prelude&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; ! &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;dp&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;pac&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;comment&quot;&gt;// On configure le quartz interne en source d&amp;apos;horloge&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;dp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;RCC&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;freeze&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;hsi16&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;comment&quot;&gt;// init du GPIO de la LED&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;gpiob&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;dp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;GPIOB&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;led&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;gpiob&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;pb3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;into_push_pull_output&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;led&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;set_high&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;keyword&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Je commence par configurer le périphérique &lt;code&gt;systick&lt;/code&gt; pour que son compteur déborde tout les 1ms. Ce qui donne la fonction “&lt;em&gt;main&lt;/em&gt;” suivante:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m_rt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;panic_abort&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;stm32l0xx_hal&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;pac&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;prelude&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; ! &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;dp&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;pac&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;cp&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;// On configure le quartz interne en source d&amp;apos;horloge&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;dp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;RCC&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;freeze&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;hsi16&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;// configuration du systick via l&amp;apos;api HAL&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// On le configure pour qu&amp;apos;il ait une cadence de 1ms&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;SYST&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;set_clock_source&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;peripheral&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;syst&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;SystClkSource&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Core&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;SYST&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;set_reload&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant_builtin&quot;&gt;16_000&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;SYST&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;enable_counter&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;SYST&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;enable_interrupt&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;SYST&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;clear_current&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; !&lt;span class=&quot;constructor constant&quot;&gt;cp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;SYST&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;has_wrapped&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;// init du GPIO de la LED&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;gpiob&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;dp&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;GPIOB&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;led&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;gpiob&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;pb3&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;into_push_pull_output&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;led&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;set_high&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette configuration me permet d’utiliser l’interruption du &lt;code&gt;systick&lt;/code&gt; comme repère temporel.&lt;/p&gt;&lt;h1 id=&quot;interface&quot;&gt;Création de l’interface&lt;/h1&gt;&lt;p&gt;Maintenant que le &lt;code&gt;systick&lt;/code&gt; est prêt, je peux implémenter le driver. Pour cela, j’ai besoin de deux choses:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;une base de temps&lt;/li&gt;&lt;li&gt;une consigne de temps limite&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Pour ce qui est de la base temps, j’utiliserai l’interruption du &lt;code&gt;systick&lt;/code&gt;. Et pour le temps limite, je propose d’utiliser la structure suivante:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette structure permet de stocker la consigne de limite temporelle. Pour faciliter son utilisation j’ajoute les fonctions suivantes:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;is_elapse&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;comment&quot;&gt;// reach error not implemented&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant variable_parameter&quot;&gt;tick_to_wait&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;comment&quot;&gt;// reach error not implemented&lt;/span&gt;
        &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;tick_to_wait&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Maintenant, passons à l’implémentation de la gestion du temps via l’interruption de systick.&lt;/p&gt;&lt;h1 id=&quot;irq&quot;&gt;Interruption de SysTick&lt;/h1&gt;&lt;p&gt;Si je devais écrire ce code en &lt;code&gt;C&lt;/code&gt;, je me contenterai sans doute de déclarer une variable globale et de l’incrémenter dans l’interruption. En utilisant une variable de type &lt;code&gt;u32&lt;/code&gt; on s’assure d’un accès atomique (pour notre cible) donc pas de risque de concurrence d’accès.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;c&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;volatile&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;constant variable&quot;&gt;tick&lt;/span&gt;  &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;number&quot;&gt;0u&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;type&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;constant variable function&quot;&gt;Systick_IRQHandler&lt;/span&gt;(&lt;span class=&quot;type&quot;&gt;void&lt;/span&gt;){
	&lt;span class=&quot;constant variable&quot;&gt;tick&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;delimiter&quot;&gt;;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ce que je traduis naïvement en rust part:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m_rt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt; = &lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;is_elapse&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt; &amp;gt;= &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant variable_parameter&quot;&gt;tick_to_wait&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt; = &lt;span class=&quot;keyword&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt; + &lt;span class=&quot;constructor constant&quot;&gt;tick_to_wait&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;// Interruption de SysTick. Pour que la fonction soit identifier&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;// comme une interruption, on utilise la directive *exception*&lt;/span&gt;
&lt;span class=&quot;comment&quot;&gt;// de cortex-m-rt&lt;/span&gt;
&lt;span class=&quot;attribute&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;SysTick&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;unsafe&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt; += &lt;span class=&quot;constant_builtin&quot;&gt;1_u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;En rust, la manipulation de variable globales nécessite de passer par des sections &lt;code&gt;unsafe&lt;/code&gt;. Attention, il est cependant strictement interdit de déréférencer la variable &lt;code&gt;COUNT&lt;/code&gt;. Il s’agit d’un comportement non définit en rust (UB).&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html&quot; target=&quot;_blank&quot;&gt;Explications et détails&lt;/a&gt;&lt;/p&gt;&lt;p&gt;De plus, je ne sais pas si cette implémentation garantie que le compilateur n’optimisera pas l’accès à la variable COUNT (l’équivalent du &lt;code&gt;volatile&lt;/code&gt; en C) mais une fois compiler et flasher sur le microcontrôleur, tout semble fonctionner. Sans doute un coup de chance…&lt;/p&gt;&lt;p&gt;Il existe cependant d’autres options permettant de ne pas passer par des sections &lt;code&gt;unsafe&lt;/code&gt;. La première  est d’expliciter l’atomicité de l’accès en utilisant: &lt;code&gt;core::sync::atomic::{AtomicU32, Ordering}&lt;/code&gt;. Une autre est d’utiliser la structure &lt;code&gt;mutex&lt;/code&gt; du crate &lt;code&gt;cortex_m&lt;/code&gt;.&lt;/p&gt;&lt;h2 id=&quot;mutex&quot;&gt;Mutex&lt;/h2&gt;&lt;p&gt;Voici une implémentation de l’accès à une variable globale via le crate &lt;code&gt;cortex_m::interrupt::Mutex&lt;/code&gt;. Vous trouverez un exemple officiel &lt;a href=&quot;https://docs.rust-embedded.org/book/concurrency/#mutexes&quot; target=&quot;_blank&quot;&gt;ici&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;cell&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;RefCell&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;interrupt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Mutex&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m_rt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Mutex&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;RefCell&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;&amp;gt;&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;Mutex&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;RefCell&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;is_elapse&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt; = &lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;interrupt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;cs&lt;/span&gt;| &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;constructor constant&quot;&gt;count&lt;/span&gt; = &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;borrow&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;borrow&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt; &amp;lt;= &lt;span class=&quot;constructor constant&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant variable_parameter&quot;&gt;tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;u32&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;interrupt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;cs&lt;/span&gt;| &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt; = &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;borrow&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;borrow&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; + &lt;span class=&quot;constructor constant&quot;&gt;tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;SysTick&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;interrupt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;free&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;cs&lt;/span&gt;| &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;count&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;borrow&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;cs&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;borrow_mut&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;count&lt;/span&gt; += &lt;span class=&quot;constant_builtin&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cette solution offerte par le crate &lt;code&gt;cortex_m&lt;/code&gt; est fonctionnel. Cependant, je trouve quelle alourdie pas mal le code. Pour quelqu’un qui vient du C, c’est même assez déroutant.&lt;/p&gt;&lt;h2 id=&quot;atomic&quot;&gt;Atomic&lt;/h2&gt;&lt;p&gt;Une autre solution consiste à passer par le type &lt;code&gt;Atomic&lt;/code&gt; proposé par le crate &lt;code&gt;core::sync::atomic&lt;/code&gt;. Il nous permet d’indiquer au compilateur que la variable qu’il manipule est accédée atomiquement. Ce qui nous donne le code suivant:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;core&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;atomic&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;AtomicUsize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m_rt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;exception&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;AtomicUsize&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;AtomicUsize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;impl&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;Delay&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;is_elapse&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; &lt;span class=&quot;type_builtin&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt; &amp;lt;= &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Relaxed&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;pub&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant variable_parameter&quot;&gt;tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;type_builtin&quot;&gt;usize&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;variable_builtin&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;end_tick&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Relaxed&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; + &lt;span class=&quot;constructor constant&quot;&gt;tick&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;SysTick&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;store&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;COUNT&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;load&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Relaxed&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; + &lt;span class=&quot;constant_builtin&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;Ordering&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Relaxed&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Je trouve cette solution bien plus facile à lire que celle utilisant le mutex.&lt;/p&gt;&lt;h1&gt;Bilan&lt;/h1&gt;&lt;p&gt;La première implémentation est certainement la plus intuitive pour quelqu’un ayant l’habitude du C, mais elle reste à éviter à cause de l’utilisation de sections &lt;code&gt;unsafe&lt;/code&gt;. La troisième solution (&lt;code&gt;atomic&lt;/code&gt;) est  celle que je trouve la plus explicite et facile à lire. Cependant, ces deux solutions ne permettent de travailler qu’avec une variable à accès atomic. Si l’on souhaite éditer une variable plus complexe comme une structure, il faudra alors se tourner vers la solution &lt;code&gt;mutex&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Enfin, un autre avantage des méthodes &lt;code&gt;unsafe&lt;/code&gt; et &lt;code&gt;atomic&lt;/code&gt;, est quelles ne sont pas dépendants de la cible. Contrairement à la méthode à base de &lt;code&gt;mutex&lt;/code&gt; qui impose de compiler pour une cible &lt;code&gt;cortex_m&lt;/code&gt;. Pour l’instant on s’en moque un peu mais lorsque l’on voudra utiliser la directive &lt;code&gt;#cfg[test]&lt;/code&gt; afin de valider le fonctionnement des fonctions par des tests unitaires, ça prendra une tout autre importance.&lt;/p&gt;</description>
    <link>https://ylbn.fr/blog/rust_embedded_2/</link>
    <pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate>
    <guid>https://ylbn.fr/blog/rust_embedded_2/</guid>
   </item>
  
   <item>
    <title>Rust sur mcu: Découverte</title>
    <description>&lt;h1 id=&quot;intro&quot;&gt;Intro&lt;/h1&gt;&lt;p&gt;J’ai déjà pu expérimenter l’utilisation du langage rust et de son environnement dans le cadre du dev d’outil &lt;em&gt;cli&lt;/em&gt;, mais pas encore pour de l’embarqué &lt;em&gt;bare metal&lt;/em&gt;. Cet article va donc me servir de mémo quant à ces essais.&lt;/p&gt;&lt;p&gt;Pour ces tests, j’utiliserai une carte de dev ST &lt;em&gt;nucleo&lt;/em&gt; stm32l031k6. Pour ce qui est de la toolchain rust, j’utilise la version 1.89.0. Vous pouvez retrouver le &lt;a href=&quot;https://codeberg.org/tanche/embedded_rust_test&quot; target=&quot;_blank&quot;&gt;répertoire du projet ici&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Premièrement petit tour de la doc:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/stable/book&quot; target=&quot;_blank&quot;&gt;le rustbook générique&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/stable/embedded-book/index.html&quot; target=&quot;_blank&quot;&gt;le rustbook embarqué&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.rust-embedded.org/embedonomicon/preface.html&quot; target=&quot;_blank&quot;&gt;embedonomicon&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://doc.rust-lang.org/stable/cargo/index.html&quot; target=&quot;_blank&quot;&gt;le rustbook de cargo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://rust-training.ferrous-systems.com/latest/book/ferrocene-installing&quot; target=&quot;_blank&quot;&gt;ferrous system&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;recette&quot;&gt;Système de recette&lt;/h1&gt;&lt;p&gt;Première bonne surprise, cargo (l’utilitaire de construction rust), gère nativement la cross-compilation. Pour cela, on peut soit lui passer l’option &lt;code&gt;--target&lt;/code&gt; avec le &lt;em&gt;code triple&lt;/em&gt; de la cible. Soit créer un fichier &lt;code&gt;.cargo/config.toml&lt;/code&gt; à la racine de notre projet, dans lequel on spécifie lui indique la cible.&lt;/p&gt;&lt;p&gt;Donc pour le stm32l032k6, on utilse soit:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;cargo build --target thumbv6m-none-eabi&lt;/code&gt;&lt;/li&gt;&lt;li&gt;le fichier de config cargo avec:&lt;pre&gt;&lt;code class=&quot;toml&quot;&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;property&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;thumbv6m-none-eabi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
Ainsi lorsqu’on appellera &lt;code&gt;cargo build&lt;/code&gt; il utilisera la cible spécifier dans le fichier de config&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;pac&quot;&gt;Description du matériel&lt;/h2&gt;&lt;p&gt;Contrairement au C, &lt;em&gt;st&lt;/em&gt; ne fournis pas de &lt;em&gt;HAL&lt;/em&gt; ou de &lt;em&gt;LL&lt;/em&gt; rust. En revanche, la communauté rust étant très active, on trouve des crates faisant un travail équivalent.&lt;/p&gt;&lt;p&gt;On distingue trois niveaux d’intégration&lt;/p&gt;&lt;ol&gt;&lt;li&gt;les crates &lt;em&gt;cortex-m&lt;/em&gt; et &lt;em&gt;cortex-m-rt&lt;/em&gt; réalisant l’abstraction des périphériques standard des coeur &lt;em&gt;arm cortex-m&lt;/em&gt;&lt;/li&gt;&lt;li&gt;les crates de description matériel (PAC pour Peripherals Abstraction Crate). Ils gèrent le mapping des périphériques du microcontrôleur. Ils sont donc spécifique à la cible. ils nous permettent d’accéder aux registres de chaque périphérique par un ensemble de fonction/structure de données plutôt qu’en spécifiant des adresses mémoire.&lt;/li&gt;&lt;li&gt;Les crates d’abstraction matériel (HAL pour Hardware Abstraction Layer). Ils sont basés sur les &lt;em&gt;PAC&lt;/em&gt; et offrent une interface &lt;em&gt;haut niveau&lt;/em&gt; et standardisée pour configurer et intéragire avec les périphériques.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Dans cette première partie, nous n’utiliserons pas de HAL.&lt;/p&gt;&lt;h2 id=&quot;crates&quot;&gt;Les crates&lt;/h2&gt;&lt;p&gt;Les crates est le nom donné en rust aux dépendances du projet. Elles sont la plupart du temps disponibles sur le site &lt;a href=&quot;https://crates.io&quot; target=&quot;_blank&quot;&gt;crates.io&lt;/a&gt;, mais on peut aussi spécifier des dépendances locales ou des répertoires git.&lt;/p&gt;&lt;p&gt;Pour utiliser une crate, il y a deux possibilités:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;via cargo avec &lt;code&gt;cargo add le_nom_du_crate&lt;/code&gt; Cargo va alors chercher le crate en question sur &lt;a href=&quot;https://crates.io&quot; target=&quot;_blank&quot;&gt;crates.io&lt;/a&gt; et s’il existe, il va ajouter la dépendance dans le fichier &lt;code&gt;Cargo.toml&lt;/code&gt; et la télécharger dans le cache local.&lt;/li&gt;&lt;li&gt;En éditant le fichier &lt;code&gt;Cargo.toml&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Dans le cas de notre mcu, il s’agit d’un coeur cortex M0+, nous allons donc utiliser les crates suivant:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://docs.rs/cortex-m/latest/cortex_m&quot;&quot; target=&quot;_blank&quot;&gt;cortex-m&lt;/a&gt; pour la description des périphériques liés au coeur arm.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.rs/cortex-m-rt/latest/cortex_m_rt/&quot; target=&quot;_blank&quot;&gt;cortex-m-rt&lt;/a&gt; pour la gestion de la compilation et de l’édition de liens.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.rs/panic-abort/latest/panic_abort/&quot; target=&quot;_blank&quot;&gt;panic-abort&lt;/a&gt; pour avoir une implémentation par défaut de la gestion des erreurs non recouvrable.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.rs/stm32l0/latest/stm32l0/&quot; target=&quot;_blank&quot;&gt;stm32l0&lt;/a&gt; pour la description des périphériques du stm32l031.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://docs.rs/crate/stm32l0xx-hal/latest&quot; target=&quot;_blank&quot;&gt;stm32l0xx-hal&lt;/a&gt; pour la HAL (nous l’utiliserons dans un second temps).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Pour les crates &lt;em&gt;cortex-m&lt;/em&gt;, &lt;em&gt;stm32l0&lt;/em&gt; nous devons spécifier des options pour pouvoir les utiliser.&lt;/p&gt;&lt;p&gt;Ce qui nous donne la liste de dépendance suivante:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;toml&quot;&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;dependencies&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;property&quot;&gt;cortex-m-rt&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;0.7.5&amp;quot;&lt;/span&gt;
&lt;span class=&quot;property&quot;&gt;panic-abort&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;0.3.2&amp;quot;&lt;/span&gt;
&lt;span class=&quot;property&quot;&gt;cortex-m&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;0.7.7&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;features&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;critical-section-single-core&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;property&quot;&gt;stm32l0&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;0.16.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;property&quot;&gt;features&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;stm32l0x1&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;rt&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;linker&quot;&gt;Édition de liens&lt;/h2&gt;&lt;p&gt;Le crate *cortex-m-rt fournis un script d’édition de liens par défaut. Il nous réclame simplement de créer un fichier &lt;code&gt;memory.x&lt;/code&gt; à la racine du projet indiquant la configuration de la &lt;em&gt;RAM&lt;/em&gt; et la &lt;em&gt;FLASH&lt;/em&gt;. Pour ce qui est de la configuration de la table des vecteurs d’interruption, le crate &lt;em&gt;cortex-m-rt&lt;/em&gt; offre un mécanisme permettant à l’utilisateur ou à d’autre crate &lt;a href=&quot;https://docs.rs/cortex-m-rt/latest/cortex_m_rt/#incorporating-device-specific-interrupts&quot; target=&quot;_blank&quot;&gt;d’insérer leur définition.&lt;/a&gt; Dans notre cas c’est le crate &lt;em&gt;stm32l0&lt;/em&gt; qui s’en charge via la feature &lt;em&gt;rt&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;En ce qui concerne la configuration mémoire, notre micro (stm32l031k6) dispose de 32ko de flash et 8ko de ram. On va donc créer un fichier &lt;code&gt;memory.x&lt;/code&gt; contenant:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;MEMORY
{
  RAM  (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
  FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 32K
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Il ne nous reste plus qu’à éditer le fichier de config de cargo (.cargo/config.toml) pour ajouter un flag de compilation indiquant à rustc d’utiliser le script d’édition de liens du crate &lt;em&gt;cortex-m-rt&lt;/em&gt; nommé &lt;code&gt;link.x&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;toml&quot;&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;property&quot;&gt;target&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;thumbv6m-none-eabi&amp;quot;&lt;/span&gt;

&lt;span class=&quot;comment&quot;&gt;# flag pour l&amp;apos;édition de lien&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;thumbv6m-none-eabi&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;property&quot;&gt;rustflags&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;-C&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&amp;quot;link-arg=-Tlink.x&amp;quot;&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Pour aller plus loin&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Si on le souhaite, on peut aussi utiliser un script de liens personnel (&lt;a href=&quot;https://docs.rs/cortex-m-rt/latest/cortex_m_rt/#custom-linker-script&quot; target=&quot;_blank&quot;&gt;doc&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Si on souhaite analyser le fichier elf avec &lt;code&gt;objdump&lt;/code&gt; &lt;a href=&quot;https://docs.rs/cortex-m-rt/latest/cortex_m_rt/#inspection&gt;&quot; target=&quot;_blank&quot;&gt;ce morceau de doc&lt;/a&gt; explicite les différentes sections.&lt;/li&gt;&lt;li&gt;script de liens par défaut: &lt;a href=&quot;https://github.com/rust-embedded/cortex-m/blob/master/cortex-m-rt/link.x.in&quot; target=&quot;_blank&quot;&gt;link.x&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;helloworld&quot;&gt;Un simple clignotement&lt;/h1&gt;&lt;p&gt;Commençons par le &lt;em&gt;hello world&lt;/em&gt; de l’embarqué: faire clignoter une led…&lt;/p&gt;&lt;p&gt;On commence par créer un dossier: &lt;code&gt;mkdir rust_stm32l031 &amp;amp;&amp;amp; cd rust_stm32l031&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Ensuite on initialise le projet avec cargo: &lt;code&gt;cargo init --bin&lt;/code&gt;. Cette commande va créer les fichiers de config (Cargo.toml et Carlo.lock) ainsi qu’un répertoire &lt;em&gt;src&lt;/em&gt; et le fichier &lt;em&gt;main.rs&lt;/em&gt;.&lt;/p&gt;&lt;h2 id=&quot;blinky_main&quot;&gt;Mise en place de la fonction main&lt;/h2&gt;&lt;p&gt;Pour pouvoir compiler notre projet pour la cible stm32l0, on doit spécifier que le programme n’utilise pas la bibliothèque standard. Pour cela on utilise la directive: &lt;code&gt;#![no_std]&lt;/code&gt;&lt;/p&gt;&lt;p&gt;On doit aussi indiquer au compilateur que l’on souhaite utiliser une fonction de démarrage custom (fonction qui initialise les variables et appelle la fonction &lt;em&gt;main&lt;/em&gt;). En effet, notre &lt;code&gt;main()&lt;/code&gt; sera appelée depuis la fonction &lt;code&gt;Reset&lt;/code&gt; implémentée par &lt;em&gt;cortex-m-rt&lt;/em&gt;. Pour ce faire on utilise la directive: &lt;code&gt;#![no_main]&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;De son côté, le crate &lt;em&gt;cortex-m-rt&lt;/em&gt; expose la directive &lt;code&gt;#[entry]&lt;/code&gt; pour spécifier la fonction d’entrée.&lt;/p&gt;&lt;p&gt;Enfin, on doit indiquer au compilateur comment la programme doit réagir en cas de détection de comportement interdit (panic). Pour ce faire, le compilateur attend une fonction:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;panic_handler&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;panic&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;constructor constant variable_parameter&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;type&quot;&gt;PanicInfo&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; !&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Plutôt que de créer notre propre implémentation, on utilise le crate &lt;em&gt;panic_abort&lt;/em&gt; afin qu’en cas d’erreur on déclenche un &lt;em&gt;&lt;a href=&quot;https://doc.rust-lang.org/core/intrinsics/fn.abort.html&quot; target=&quot;_blank&quot;&gt;hardfault&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;On va donc avoir un fichier &lt;em&gt;main.rs&lt;/em&gt; qui ressemble à ça:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;no_main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;attribute&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;no_std&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m_rt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;constructor constant&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;panic_abort&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; ! &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;keyword&quot;&gt;loop&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Voila vous pouvez maintenant compiler et flasher ce programme sur votre carte électronique. Ça n’a aucun intérêt puisque ce programme ne fait rien mais ça fonctionne!&lt;/p&gt;&lt;h2 id=&quot;blinky_run&quot;&gt;configuration des périphériques&lt;/h2&gt;&lt;p&gt;Nous avons mis en place notre chaîne de compilation, nous pouvons maintenant attaquer la configuration des périphériques. Pour cela, nous allons utiliser deux crates:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;cortex-m&lt;/em&gt; pour l’accès aux périphériques &lt;em&gt;arm&lt;/em&gt;, par exemple: systick, nvic …&lt;/li&gt;&lt;li&gt;&lt;em&gt;stm32l0&lt;/em&gt; pour l’accès aux périphériques stm32, par exemple: adc, gpio …&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Les objectifs sont:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;configurer l’horloge pour utiliser le HSI 16MHz comme source&lt;/li&gt;&lt;li&gt;configurer le GPIO B3 en sortie pour faire clignoter une led&lt;/li&gt;&lt;li&gt;configurer le Systick pour cadencer le clignotement de la led&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Ce qui donne le fichier &lt;em&gt;main.rs&lt;/em&gt; suivant:&lt;/p&gt;&lt;pre&gt;&lt;code class=&quot;rust&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;no_std&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;attribute&quot;&gt;#!&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;no_main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;cortex_m&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;Peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;cortex_m_rt&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;panic_abort&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;constructor constant type&quot;&gt;stm32l0&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;stm32l0x1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;attribute&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;constructor constant attribute&quot;&gt;entry&lt;/span&gt;&lt;span class=&quot;punctuation_bracket attribute&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;constructor constant function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; -&amp;gt; ! &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// acces aux périphériques&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;peripherals&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;stm32l0x1&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// on récupère le périphérique d&amp;apos;horloge et on configure le HSI&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;RCC&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;apb2enr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;| &lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;syscfgen&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;cr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;| &lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;hsi16on&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;cr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;hsi16rdyf&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;bit_is_clear&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;cfgr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;| &lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;sw&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;hsi16&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;// configuration du Systick pour une clock à 16 MHz et&lt;/span&gt;
    &lt;span class=&quot;comment&quot;&gt;// utilisation de la structure delay de cortex-m&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;peripheral&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;Peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;unwrap&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;mut&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;delay&lt;/span&gt; = &lt;span class=&quot;constructor constant type&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant type&quot;&gt;Delay&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;constructor constant function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constructor constant&quot;&gt;peripheral&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;SYST&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constant_builtin&quot;&gt;16_000_000&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;// on active l&amp;apos;horloge pour le GPIOB&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;rcc&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;iopenr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;| &lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;iopben&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;comment&quot;&gt;// On configure le GPIOB3 en sortie push-pull&lt;/span&gt;
    &lt;span class=&quot;keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;gpiob&lt;/span&gt; = &lt;span class=&quot;constructor constant&quot;&gt;peripherals&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property&quot;&gt;GPIOB&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;constructor constant&quot;&gt;gpiob&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;moder&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;| &lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;mode3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;keyword&quot;&gt;loop&lt;/span&gt; &lt;span class=&quot;punctuation_bracket&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;// on commence par lire l&amp;apos;état de la sortie via &amp;apos;r&amp;apos; -&amp;gt; r.od3().bit()&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;// On inverse la valeur à écrire par rapport à la valeur lu via &amp;apos;!&amp;apos;&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;// et on écrit met à jour la sortie &amp;apos;w&amp;apos; -&amp;gt; w.od3().bit(x)&lt;/span&gt;
        &lt;span class=&quot;constructor constant&quot;&gt;gpiob&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;odr&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;modify&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;|&lt;span class=&quot;constructor constant&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;| &lt;span class=&quot;constructor constant&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;od3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;bit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;!&lt;span class=&quot;constructor constant&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;od3&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;bit&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;comment&quot;&gt;// attente de 500 ms&lt;/span&gt;
        &lt;span class=&quot;constructor constant&quot;&gt;delay&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;property function_method&quot;&gt;delay_ms&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;constant_builtin&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;punctuation_bracket&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;punctuation_delimiter&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;punctuation_bracket&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Et voilà un clignotement de led en bonne et due forme.&lt;/p&gt;</description>
    <link>https://ylbn.fr/blog/rust_embedded_1/</link>
    <pubDate>Fri, 06 Mar 2026 00:00:00 +0000</pubDate>
    <guid>https://ylbn.fr/blog/rust_embedded_1/</guid>
   </item>
  
   <item>
    <title>Linker scripts</title>
    <description>&lt;h1 id=&quot;intro&quot;&gt;Intro&lt;/h1&gt;&lt;p&gt;Dans les grandes lignes, le linker script (fichier .ld) permet d’indiquer au programme “&lt;em&gt;ld&lt;/em&gt;” comment le contenu des fichiers objet (.o) doit être assemblé pour créer le fichier ELF.&lt;/p&gt;&lt;p&gt;Dans le cas qui m’intéresse - les firmwares ciblant des microcontrôleurs - le fichier elf sera soit converti en fichier hexa ou binaire soit directement utilisé par openocd pour programmer le MCU.&lt;/p&gt;&lt;p&gt;Un exemple de linker script est disponible &lt;a href=&quot;https://ylbn.fr/blog/linker_script/sample.ld&quot;&gt;ici sample.ld&lt;/a&gt;.&lt;/p&gt;&lt;h1 id=&quot;archi&quot;&gt;Architecture du fichier &lt;em&gt;.ld&lt;/em&gt;&lt;/h1&gt;&lt;p&gt;Les fichiers &lt;em&gt;.ld&lt;/em&gt; sont de simples fichiers texte. On peut y écrire des commentaires via la syntaxe &lt;code&gt;/* mon commentaire */&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Pour indiquer à l’éditeur de liens comment agencer les objets en mémoire, nous avons à disposition quelques mots-clés (liste non exhaustive, je me contente ici des mots-clés qui me sont utiles):&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;MEMORY&lt;/code&gt; Déclare les zones mémoire utilisables, leurs adresses et leurs tailles.&lt;/li&gt;&lt;li&gt;&lt;code&gt;SECTIONS&lt;/code&gt; Permet de déclarer les différentes sections, où les &lt;em&gt;ranger&lt;/em&gt; et dans quel ordre.&lt;/li&gt;&lt;li&gt;&lt;code&gt;.&lt;/code&gt; Le point n’est pas un mot-clé à proprement parler mais une variable spéciale. Elle enregistre la dernière adresse mémoire utilisée durant &lt;em&gt;l’assemblage&lt;/em&gt; des objets. Elle nous permet donc de récupérer la position actuelle de *l’assemblage en mémoire: &lt;code&gt;_myvar = .&lt;/code&gt;. Elle permet aussi de forcer la position d’une section: &lt;code&gt;. = 0xFF&lt;/code&gt; (semblable à l’instruction &lt;code&gt;AT(x)&lt;/code&gt;).&lt;/li&gt;&lt;li&gt;&lt;code&gt;KEEP&lt;/code&gt; Indique à l’éditeur de liens de garder cette section même si elle est vide. Ce mot-clé a toute son importance lorsque l’on passe l’option &lt;code&gt;--gc-sections&lt;/code&gt; à l’éditeur.&lt;/li&gt;&lt;li&gt;&lt;code&gt;AT(x)&lt;/code&gt;: Est un attribut de section (optionnel) qui permet de spécifier l’adresse à laquelle doit être placé la section.&lt;/li&gt;&lt;li&gt;&lt;code&gt;&amp;gt; Y AT &amp;gt; X&lt;/code&gt;: Cette utilisation de &lt;code&gt;AT&lt;/code&gt; diffère de la précédente. Dans ce cas, on l’utilise pour indiquer la zone mémoire de &lt;em&gt;stockage&lt;/em&gt; (Y) et la zone mémoire dans laquelle la section doit être chargée (X).&lt;/li&gt;&lt;li&gt;&lt;code&gt;ALIGN(x)&lt;/code&gt; spécifie l’alignement en mémoire, x étant le nombre d’octets&lt;/li&gt;&lt;li&gt;&lt;code&gt;NOLOAD&lt;/code&gt; Indique au sein du fichier ELF que la section n’a pas besoin d’être chargée au démarrage du système. Ce mot-clé ne semble pas pertinent dans notre cas puisque le démarrage n’est pas fait à partir du fichier ELF mais cela nous permet de &lt;em&gt;décrire&lt;/em&gt; les sections.&lt;/li&gt;&lt;li&gt;&lt;code&gt;LOADADDR&lt;/code&gt; permet de récupérer l’adresse d’une section en mémoire.&lt;/li&gt;&lt;li&gt;&lt;code&gt;PROVIDE&lt;/code&gt; Il y a deux manières de définir un symbole, soit par un assignement, soit via &lt;code&gt;PROVIDE&lt;/code&gt;. &lt;code&gt;PROVIDE&lt;/code&gt; permet de définir le symbole s’il n’est pas déjà défini dans les fichiers objets à assembler.&lt;/li&gt;&lt;li&gt;&lt;code&gt;PROVIDE_HIDDEN&lt;/code&gt; Permet de définir une variable mais sans l’exporter ; donc définir une variable locale plutôt que globale.&lt;/li&gt;&lt;li&gt;&lt;code&gt;ASSERT&lt;/code&gt; assertion classique permet de déclencher une erreur si le résultat du test est égal à zéro.&lt;/li&gt;&lt;li&gt;&lt;code&gt;SIZEOF&lt;/code&gt; permet de récupérer la taille d’une section.&lt;/li&gt;&lt;li&gt;&lt;code&gt;SORT&lt;/code&gt; permet de trier une liste&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;De manière naïve, nous pouvons dire que ces scripts sont découpés en trois parties:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;La déclaration des variables Via l’assignation &lt;code&gt;=&lt;/code&gt; ou &lt;code&gt;PROVIDE&lt;/code&gt;, on peut assigner une valeur à une variable que l’on pourra réutiliser plus tard dans le script. Dans notre exemple, on s’en sert pour définir la taille maximale de la stack.&lt;/li&gt;&lt;li&gt;La description de la mémoire du périphérique. Grâce au mot-clé &lt;code&gt;MEMORY&lt;/code&gt;, on indique l’adresse des zones mémoire à utiliser et leurs tailles.&lt;/li&gt;&lt;li&gt;La description de &lt;em&gt;comment ranger le code en mémoire&lt;/em&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h1 id=&quot;desc&quot;&gt;Description de la mémoire&lt;/h1&gt;&lt;p&gt;Cette section permet de décrire la zone mémoire utilisable. Dans notre exemple, nous avons trois zones, la RAM, le BOOTLOADER et la FLASH.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;FLASH_SIZE = 0x10000000
RAM_SIZE = 0x30000

MEMORY{
    FLASH(rx) : ORIGIN = 0x00000000, LENGTH = FLASH_SIZE
    RAM(rwx) : ORIGIN = 0x20000000, LENGTH = RAM_SIZE
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On remarque que la déclaration de variable et leur assignement nous permet de facilement &lt;em&gt;séparer&lt;/em&gt; une même mémoire physique en deux mémoires virtuelles (BOOTLOADER et FLASH).&lt;/p&gt;&lt;p&gt;La déclaration des zones mémoire nous permet aussi d’indiquer les droits d’accès pour chacune de ces zones.&lt;/p&gt;&lt;h1 id=&quot;section&quot;&gt;La gestion des sections&lt;/h1&gt;&lt;p&gt;Le mot-clé &lt;code&gt;SECTIONS{}&lt;/code&gt; permet de définir plus finement l’organisation du code dans les différentes zones mémoire.&lt;/p&gt;&lt;h2 id=&quot;vector_table&quot;&gt;La table des vecteurs d’interruption&lt;/h2&gt;&lt;p&gt;Dans le cas d’un MCU basé sur l’architecture ARM Cortex-M, la première section &lt;strong&gt;doit&lt;/strong&gt; être la table des vecteurs d’interruption.&lt;/p&gt;&lt;p&gt;Nous allons donc commencer le script avec:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SECTIONS{
  /* force la position à l&amp;apos;adresse relative 0 */
  . = 0x0;
  .vectors : {
  /* indique que les données doivent être
     alignées sur 4 octets */
  . = ALIGN(4);
    KEEP(*(.vectors))
  } &amp;gt; BOOTLOADER;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Attention, il ne faut pas oublier d’ajouter  &lt;code&gt;__attribute__ ((section(&amp;quot;.vectors&amp;quot;)))&lt;/code&gt; à la déclaration de la table des vecteurs d’interruption afin de spécifier son lieu de stockage.&lt;/p&gt;&lt;p&gt;En ce qui concerne l’appellation des objets et des sections, GCC génère trois formes de “&lt;em&gt;section&lt;/em&gt;” différentes:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;mysection&lt;/code&gt;: la classique&lt;/li&gt;&lt;li&gt;&lt;code&gt;mysection.mafonction&lt;/code&gt; &lt;code&gt;mysection.mydata&lt;/code&gt; : générée automatiquement si l’on compile le programme avec les options &lt;code&gt;-ffunction-sections&lt;/code&gt; ou &lt;code&gt;-fdata-sections&lt;/code&gt;. Ces options permettent de générer une section par fonction/data. Cela peut être pratique pour placer précisément une donnée ou une fonction dans une zone particulière : par exemple en SRAM pour réduire les temps d’accès.&lt;/li&gt;&lt;li&gt;&lt;code&gt;gnu.linkonce.{type}.{nom}&lt;/code&gt; : liée au &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html&quot; target=&quot;_blank&quot;&gt;Vague Linkage&lt;/a&gt; Cette section ne semble concerner que le code C++&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;usuelle&quot;&gt;Les sections usuelles&lt;/h2&gt;&lt;p&gt;Les sections usuelles servent à stocker le code et les variables. On y retrouve :&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;.text&lt;/code&gt;: le code&lt;/li&gt;&lt;li&gt;&lt;code&gt;.rodata&lt;/code&gt;: les données en lecture seule&lt;/li&gt;&lt;li&gt;&lt;code&gt;.data&lt;/code&gt;: les données en lecture/écriture initialisées avec une valeur&lt;/li&gt;&lt;li&gt;&lt;code&gt;.bss&lt;/code&gt;: les données en lecture/écriture non initialisées&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Notons que les sections &lt;code&gt;.data&lt;/code&gt; et &lt;code&gt;.bss&lt;/code&gt; doivent être, respectivement, copiées et initialisées en RAM au démarrage du MCU. Dans notre cas de figure, cette opération est réalisée dans la fonction de démarrage (fonction appelée par l’interruption de &lt;em&gt;Reset&lt;/em&gt;).&lt;/p&gt;&lt;p&gt;Ce sont les quatre sections que l’on retrouve systématiquement. Nous pouvons aussi y ajouter nos propres sections pour stocker une partie spécifique du programme à un emplacement donné.&lt;/p&gt;&lt;p&gt;Par exemple on pourrait vouloir que certaines fonctions soient exécutées depuis une autre zone mémoire (ex: SRAM) afin d’optimiser la vitesse d’exécution. On aurait alors le linker script suivant:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;SECTIONS{
    .text : {
     
    } &amp;gt; FLASH
    .data : {
     
    } &amp;gt; RAM
    .bss : {
     
    } &amp;gt; RAM

    .superImportanteSection {
      speed_function.o
    } &amp;gt; SRAM AT &amp;gt; FLASH
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;L’indication &lt;code&gt;&amp;gt; SRAM AT &amp;gt; FLASH&lt;/code&gt; permet d’indiquer que ces données sont stockées en FLASH mais doivent être chargées en SRAM au démarrage. Attention, ce n’est pas fait automatiquement : il faut adapter la fonction de démarrage (dans le cas d’un MCU) pour copier la section (cf: &lt;code&gt;bss&lt;/code&gt; et &lt;code&gt;data&lt;/code&gt;).&lt;/p&gt;&lt;h2 id=&quot;specific&quot;&gt;Les sections spécifiques&lt;/h2&gt;&lt;p&gt;On retrouve ici les sections utilisées par le compilateur pour stocker les constructeurs et destructeurs d’objets (&lt;code&gt;new&lt;/code&gt; et &lt;code&gt;delete&lt;/code&gt; en C++ et &lt;code&gt;__attribute__((constructor))&lt;/code&gt; en C). N’utilisant pas le C++ en embarqué, l’étude de ce fonctionnement n’a pas été poussée.&lt;/p&gt;&lt;p&gt;Ce que j’ai pu en comprendre, c’est que ces sections sont utilisées par le compilateur pour stocker des pointeurs de fonction permettant d’initialiser/déinitialiser des variables.&lt;/p&gt;&lt;p&gt;Ces fonctions sont appelées via &lt;code&gt;__libc_init_array&lt;/code&gt; durant la phase de démarrage et via &lt;code&gt;__libc_fini_array&lt;/code&gt; à la fin de l’exécution (ce qui n’arrive jamais en embarqué). (cf &lt;a href=&quot;https://github.com/picolibc/picolibc/blob/main/doc/init.md&quot; target=&quot;_blank&quot;&gt;picolibc&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;Les sections d’initialisation et destruction sont:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;preinit_array : générer par le compilateur pour les classes C++ (vtable) (je n’ai pas creusé davantage)&lt;/li&gt;&lt;li&gt;init_array : les fonctions avec l’attribut &lt;em&gt;constructor&lt;/em&gt;. &lt;strong&gt;ATTENTION&lt;/strong&gt; les constructeurs sont initialisés avec un ordre de priorité. Donc &lt;em&gt;init_array&lt;/em&gt; doit être trié avec &lt;em&gt;SORT&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;fini_array : les fonctions avec l’attribut &lt;em&gt;destructeur&lt;/em&gt;&lt;/li&gt;&lt;li&gt;ctors: déprécié&lt;/li&gt;&lt;li&gt;dtors: déprécié&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;section_debug&quot;&gt;Les sections ARM Debug&lt;/h2&gt;&lt;p&gt;Pour pouvoir utiliser la fonction &lt;em&gt;backtraces&lt;/em&gt; en debug, if faut fournir deux sections:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;exidx&lt;/em&gt; : qui contient l’index permettant de décoder la stack&lt;/li&gt;&lt;li&gt;&lt;em&gt;extab&lt;/em&gt; : qui contient le nom des sections contenant des infos sur les exceptions en cours ??? &lt;strong&gt;pas clair&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Ressource:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/21527256/when-is-arm-exidx-is-used/57463515#57463515&quot; target=&quot;_blank&quot;&gt;stackoverflow&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/kernel/unwind.c&quot; target=&quot;_blank&quot;&gt;linux use&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Il semble que ces sections permettent d’analyser et restaurer la stack sans passer par le frame_pointer (fp). Ils parlent - sur so - d’utilisation pour les fonctions asynchrones. Freertos need it ?&lt;/p&gt;&lt;h1 id=&quot;ram&quot;&gt;Organisation de la RAM&lt;/h1&gt;&lt;p&gt;Une des raisons m’ayant poussé à comprendre plus finement le fonctionnement des scripts de liens et de leurs éditeurs est de pouvoir modifier l’agencement de la RAM pour éviter que la pile déborde sur la stack ou que la stack descende sur la pile. Ces bugs sont particulièrement pénibles à résoudre…&lt;/p&gt;&lt;p&gt;L’idée ici est d’organiser la RAM de la manière suivante:&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;img src=&quot;https://ylbn.fr/blog/linker_script/ram.png&quot; width=&quot;246&quot; height=&quot;432&quot;&gt;
&lt;figcaption&gt;ram orga&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;Ainsi, la pile, qui est descendante sur ARM Cortex-M, viendra déborder sur la section “NoMansLand”. Donc en configurant le périphérique de protection mémoire (MPU) correctement, on pourra “normalement” détecter le débordement de la stack.&lt;/p&gt;&lt;p&gt;Idem pour la HEAP, qui elle est croissante et viendra déborder sur une adresse non accessible en écriture et nous permettra de détecter le dépassement rapidement.&lt;/p&gt;&lt;p&gt;Cet &lt;a href=&quot;https://www.embedded.com/mastering-stack-and-heap-for-system-reliability-part-1-calculating-stack-size/&quot; target=&quot;_blank&quot;&gt;article&lt;/a&gt; explique clairement l’intérêt de cette configuration.&lt;/p&gt;&lt;h1 id=&quot;mold&quot;&gt;Autre linker&lt;/h1&gt;&lt;p&gt;J’ai voulu voir s’il était possible de remplacer &lt;code&gt;ld&lt;/code&gt; par &lt;code&gt;mold&lt;/code&gt; mais &lt;code&gt;mold&lt;/code&gt; ne supporte qu’un tout petit sous-ensemble de la syntaxe des linker-scripts. Il est donc impossible de l’utiliser pour l’embarqué en &lt;em&gt;none-eabi&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Il me reste à tester avec lld de clang.&lt;/p&gt;&lt;h1 id=&quot;ref&quot;&gt;Références&lt;/h1&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://allthingsembedded.com/post/2020-04-11-mastering-the-gnu-linker-script/&quot; target=&quot;_blank&quot;&gt;allthingsembedded&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://blog.thea.codes/the-most-thoroughly-commented-linker-script/&quot; target=&quot;_blank&quot;&gt;thea.codes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://ylbn.fr/blog/linker_script/DUI0101A_Elf.pdf&quot;&gt;Document de référence ARM ELF&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://wiki.osdev.org/Linker_Scripts&quot; target=&quot;_blank&quot;&gt;linker script syntax&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://home.cs.colorado.edu/~main/cs1300/doc/gnu/ld_3.html&quot; target=&quot;_blank&quot;&gt;https://home.cs.colorado.edu/~main/cs1300/doc/gnu/ld_3.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description>
    <link>https://ylbn.fr/blog/linker_script/</link>
    <pubDate>Sun, 01 Dec 2024 00:00:00 +0000</pubDate>
    <guid>https://ylbn.fr/blog/linker_script/</guid>
   </item>
  
 </channel>
</rss>

