{"id":6529,"date":"2024-10-29T06:00:54","date_gmt":"2024-10-29T05:00:54","guid":{"rendered":"https:\/\/www.blaess.fr\/christophe\/?p=6529"},"modified":"2024-10-29T08:17:47","modified_gmt":"2024-10-29T07:17:47","slug":"zephyr-os-2-application-personnalisee","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2024\/10\/29\/zephyr-os-2-application-personnalisee\/","title":{"rendered":"Zephyr OS &#8211; 2 &#8211; Application personnalis\u00e9e"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"alignright size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"941\" height=\"786\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-pico-00-2.png\" alt=\"\" class=\"wp-image-6522\" style=\"width:200px\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-pico-00-2.png 941w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-pico-00-2-300x251.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-pico-00-2-768x641.png 768w\" sizes=\"auto, (max-width: 941px) 100vw, 941px\" \/><\/figure><\/div>\n\n\n<p>Nous avons vu dans <a href=\"https:\/\/www.blaess.fr\/christophe\/2024\/10\/15\/zephir-os-et-raspberry-pico-premiere-prise-en-main\/\" data-type=\"post\" data-id=\"6435\"><strong>le premier article<\/strong><\/a> de cette s\u00e9rie comment construire une image de Zephyr OS pour Raspberry Pi Pico en utilisant un exemple basique (\u00ab\u00a0<code>blinky<\/code>\u00ab\u00a0).<\/p>\n\n\n\n<p>Nous allons \u00e0 pr\u00e9sent voir comment d\u00e9velopper une <mark style=\"background-color:#ffff80\" class=\"has-inline-color\">application personnelle<\/mark> tr\u00e8s simple, toujours sur le microcontr\u00f4leur pour Raspberry Pico.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Nous devons commencer par nous replacer dans le r\u00e9pertoire de travail cr\u00e9\u00e9 dans l&rsquo;article pr\u00e9c\u00e9dent, puis initialiser l&rsquo;environnement virtuel de Python&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Zephyr-lab]$ <strong>ls<\/strong>\nzephyr-project  zephyr-sdk-0.16.8\n\n&#91;Zephyr-lab]$ <strong>source  .venv\/bin\/activate<\/strong>\n(.venv)&#91;Zephyr-lab]$ <\/code><\/pre>\n\n\n\n<p>Contrairement \u00e0 un d\u00e9veloppement sur un OS comme Linux, on ne s\u00e9pare pas avec Zephyr la production du <em>kernel<\/em> et des librairies de celle du code applicatif. L&rsquo;outil <code><strong>west<\/strong><\/code> se charge de produire simultan\u00e9ment notre code et de l&rsquo;ins\u00e9rer dans une image contenant le <em>kernel<\/em>.<\/p>\n\n\n\n<p class=\"has-text-align-center\">&#8211;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Code personnel<\/h2>\n\n\n\n<p>Nous allons cr\u00e9er un r\u00e9pertoire pour accueillir nos essais successifs. On peut le placer \u00e0 diff\u00e9rents endroits. J&rsquo;aime bien installer ce r\u00e9pertoire \u00e0 c\u00f4te de celui qui contient le <em>kernel<\/em> Zephyr et de ceux qui incluent les modules et les outils.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(.venv)&#91;Zephyr-lab]$ <strong>cd zephyr-project\/<\/strong>\n\n(v.venv)&#91;zephyr-project]$ <strong>ls<\/strong>\nbootloader  modules  tools  zephyr\n\n(.venv)&#91;zephyr-project]$ <strong>mkdir  zephyr-apps<\/strong>\n\n(.venv)&#91;zephyr-project]$ <strong>ls<\/strong>\nbootloader  modules  zephyr-apps  tools  zephyr<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"821\" height=\"562\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-01-2.png\" alt=\"\" class=\"wp-image-6583\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-01-2.png 821w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-01-2-300x205.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-01-2-768x526.png 768w\" sizes=\"auto, (max-width: 821px) 100vw, 821px\" \/><\/figure>\n\n\n\n<p>Pour cette premi\u00e8re application personnalis\u00e9e nous allons nous contenter d&rsquo;une variation sur le th\u00e8me de l&rsquo;exemple <code>blinky<\/code> o\u00f9 nous allons ajouter une LED externe et un mini bouton-poussoir. J&rsquo;appelle cette application <code>gpio-01<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(.venv)&#91;zephyr-project]$ <strong>mkdir  zephyr-apps\/gpio-01<\/strong><\/code><\/pre>\n\n\n\n<p>Une application typique pour Zephyr qui manipule des GPIOs contiendra au minimum trois sous-r\u00e9pertoires&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">boards\/<\/mark><\/strong><\/code> regroupera les <strong><em>overlays<\/em> de <em>device tree<\/em><\/strong> des microcontr\u00f4leurs que nous supporterons. Un <em>overlay<\/em> de <em>device tree<\/em> est une surcharge de la description des p\u00e9riph\u00e9riques pour ajouter, supprimer ou modifier une configuration d&rsquo;un \u00e9quipement. Dans notre cas <code>boards\/<\/code> contiendra un seul fichier <code><strong>rpi_pico.overlay<\/strong><\/code> qui affecte deux fonctionnalit\u00e9s (<code>my-led<\/code> et <code>my-switch<\/code>) \u00e0 deux GPIOs du Raspberry Pi Pico.<\/li>\n\n\n\n<li><code><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">dts\/<\/mark><\/strong><\/code> contient les fonctionnalit\u00e9s sp\u00e9cifiquement d\u00e9finies que nous utilisons dans le <em>device tree<\/em>. Dans notre cas, <code>dts\/<\/code> contiendra un sous-r\u00e9pertoire <code><strong>bindings\/<\/strong><\/code> qui regroupera les deux classes <code><strong>my-led.yaml<\/strong><\/code> et <code><strong>my-switch.yaml<\/strong><\/code>.<\/li>\n\n\n\n<li><code><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">src\/<\/mark><\/strong><\/code> contient les sources de l&rsquo;application. Nous nous contenterons d&rsquo;un simple <code><strong>main.c<\/strong><\/code>.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Si l&rsquo;application contient plusieurs fichiers sources, il est habituel de placer les fichiers <em>headers<\/em>, contenant les d\u00e9finitions des m\u00e9thodes et variables publiques dans un sous r\u00e9pertoire <code><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">include\/<\/mark><\/strong><\/code> \u00e0 c\u00f4t\u00e9 de <code>src\/<\/code>.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>En outre deux fichiers devront \u00eatre ajout\u00e9s \u00e0 la racine de notre r\u00e9pertoire d&rsquo;application&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">CMakeLists.txt<\/mark><\/strong><\/code> : le fichier de compilation utilis\u00e9 par <code>cmake<\/code> (invoqu\u00e9 par <code>west<\/code> pour produire le code).<\/li>\n\n\n\n<li><code><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">prj.conf<\/mark><\/strong><\/code> : un \u00ab\u00a0fragment\u00a0\u00bb de configuration pour le noyau Zephyr. Il s&rsquo;agit des options de compilation du <em>kernel<\/em> n\u00e9cessaires pour notre application.<\/li>\n<\/ul>\n\n\n\n<p>Enfin, il est courant d&rsquo;ajouter un fichier  <code><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">README<\/mark><\/strong><\/code> au format <em>Markdown<\/em> (<code>.md<\/code>) ou <em>ReStructuredText<\/em> (<code>.rst<\/code>).<\/p>\n\n\n\n<p>Voici un sch\u00e9ma de notre arborescence personnelle.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"520\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-02-1024x520.png\" alt=\"Application directory map\" class=\"wp-image-6543\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-02-1024x520.png 1024w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-02-300x152.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-02-768x390.png 768w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-02.png 1107w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Je cr\u00e9e mon arborescence avec quelques commandes&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(.venv)&#91;zephyr-project]$ <strong>mkdir  zephyr-apps\/gpio-01\/boards<\/strong>\n\n(.venv)&#91;zephyr-project]$ <strong>mkdir  -p  zephyr-apps\/gpio-01\/dts\/bindings\/<\/strong>\n\n(.venv)&#91;zephyr-project]$ <strong>mkdir  zephyr-apps\/gpio-01\/src<\/strong>\n\n(.venv)&#91;zephyr-project]$ \n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Connexions \u00e9lectriques<\/h2>\n\n\n\n<p>J&rsquo;ajoute sur mon Raspberry Pi Pico <strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">une LED<\/mark><\/strong> (prot\u00e9g\u00e9e par une r\u00e9sistance de quelques dizaines d&rsquo;Ohms) et un <strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">mini bouton-poussoir<\/mark><\/strong> avec une r\u00e9sistance de <em>pulldown<\/em> de 10 kOhms environ. (Il est possible que le <em>pulldown<\/em> soit d\u00e9j\u00e0 int\u00e9gr\u00e9 dans l&rsquo;entr\u00e9e GPIO, je n&rsquo;ai pas v\u00e9rifi\u00e9). J&rsquo;ai choisi arbitrairement deux lignes GPIO, l&rsquo;une en entr\u00e9e (<strong>GPIO 15<\/strong>) et l&rsquo;autre en sortie (<strong>GPIO 6<\/strong>).<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1015\" height=\"1010\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-03.png\" alt=\"\" class=\"wp-image-6552\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-03.png 1015w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-03-300x300.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-03-150x150.png 150w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02-03-768x764.png 768w\" sizes=\"auto, (max-width: 1015px) 100vw, 1015px\" \/><\/figure>\n\n\n\n<p>Pour plus de d\u00e9tails sur les connexions \u00e9lectriques du Raspberry Pico, on pourra se reporter \u00e0 sa documentation officielle (<strong><a href=\"#sources\">lien ci-dessous<\/a><\/strong>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fichiers de configuration<\/h2>\n\n\n\n<p>Je commence par cr\u00e9er la modification du <em><strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">device tree<\/mark><\/strong><\/em> qui d\u00e9crit ces deux lignes GPIO&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong><span style=\"text-decoration: underline;\">zephyr-apps\/gpio-01\/boards\/rpi_pico.overlay<\/span><\/strong>:\n\/ {\n\tled1: led1 {\n\t\tcompatible = \"my-led\";\n\t\tgpios = &lt;&amp;gpio0 6 GPIO_ACTIVE_HIGH&gt;;\n\t};\n\n\tswitch1: switch1 {\n\t\tcompatible = \"my-switch\";\n\t\tgpios = &lt;&amp;gpio0 15 GPIO_ACTIVE_HIGH&gt;;\n\t};\n};<\/code><\/pre>\n\n\n\n<p>Puis je d\u00e9finis <strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">les deux cat\u00e9gories <code>my-switch<\/code> et <code>my-led<\/code><\/mark><\/strong>. La seule propri\u00e9t\u00e9 qui m&rsquo;int\u00e9resse est <code>gpios<\/code>, elle est obligatoire et d\u00e9crit une ligne GPIO en regroupant trois param\u00e8tres&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>identifiant du contr\u00f4leur de GPIO concern\u00e9<\/li>\n\n\n\n<li>num\u00e9ro de la ligne GPIO dans le contr\u00f4leur<\/li>\n\n\n\n<li>polarit\u00e9 de la ligne.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong><span style=\"text-decoration: underline;\">zephyr-apps\/gpio-01\/dts\/bindings\/my-led.yaml:<\/span><\/strong>\n\ndescription: Custom Output GPIO.\n\ncompatible: \"my-led\"\n\nproperties:\n  gpios:\n    type: phandle-array\n    required: true\n    description: The output GPIO description.<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong><span style=\"text-decoration: underline;\">zephyr-apps\/gpio-01\/dts\/bindings\/my-switch.yaml:<\/span><\/strong>\n\ndescription: Custom Input GPIO.\n\ncompatible: \"my-switch\"\n\nproperties:\n  gpios:\n    type: phandle-array\n    required: true\n    description: The input GPIO description.<\/code><\/pre>\n\n\n\n<p>J&rsquo;ajoute \u00e9galement le fichier de <strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">fragment de configuration<\/mark><\/strong> qui s&rsquo;assure que l&rsquo;option <code>GPIO<\/code> du kernel Zephyr soit activ\u00e9e&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><span style=\"text-decoration: underline;\"><strong>zephyr-apps\/gpio-01\/prj.conf:<\/strong><\/span>\n\nCONFIG_GPIO=y\n<\/code><\/pre>\n\n\n\n<p>Ainsi qu&rsquo;un fichier de <strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">configuration pour <code>cmake<\/code><\/mark><\/strong> que j&rsquo;ai \u00e9crit en m&rsquo;inspirant de ceux fournis en exemple avec Zephyr&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong><span style=\"text-decoration: underline;\">zephyr-apps\/gpio-01\/CMakeLists.txt:<\/span><\/strong>\n\ncmake_minimum_required(VERSION 3.20.0)\n\nfind_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})\n\nproject(gpio-01)\n\ntarget_sources(app PRIVATE src\/main.c)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Code applicatif<\/h2>\n\n\n\n<p>Enfin, voici le <strong><mark style=\"background-color:#ffff80\" class=\"has-inline-color\">fichier source principal<\/mark><\/strong>. Pour plus de pr\u00e9cisions sur les fonctions et macros utilis\u00e9es, reportez-vous <strong><a href=\"#sources\">au lien ci-dessous<\/a><\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code><strong><span style=\"text-decoration: underline;\">zephyr-apps\/gpio-01\/src\/main.c:<\/span><\/strong>\n\n#include &lt;zephyr\/kernel.h&gt;\n#include &lt;zephyr\/drivers\/gpio.h&gt;\n\n#if !DT_NODE_EXISTS(DT_NODELABEL(led1))\n#   error \"led1 component not properly defined.\"\n#endif\n\n#if !DT_NODE_EXISTS(DT_NODELABEL(switch1))\n#   error \"switch1 component not properly defined.\"\n#endif\n\n\nint main(void)\n{\n    struct gpio_dt_spec led_1    = GPIO_DT_SPEC_GET(DT_NODELABEL(led1), gpios);\n    struct gpio_dt_spec switch_1 = GPIO_DT_SPEC_GET(DT_NODELABEL(switch1), gpios);\n\n    if (!gpio_is_ready_dt(&amp;led_1))\n        return 0;\n\n    if (gpio_pin_configure_dt(&amp;led_1, GPIO_OUTPUT_ACTIVE) &lt; 0)\n        return 0;\n\n    for (;;) {\n        if (gpio_pin_get_dt(&amp;switch_1)) {\n            while(gpio_pin_get_dt(&amp;switch_1))\n                k_msleep(1);\n\n            if (gpio_pin_toggle_dt(&amp;led_1) &lt; 0)\n\t        return 0;\n        }\n    }\n    return 0;\n}\n<\/code><\/pre>\n\n\n\n<p>On peut voir dans ce code plusieurs \u00e9l\u00e9ments int\u00e9ressants. Tout d&rsquo;abord l&rsquo;<mark style=\"background-color:#ffff80\" class=\"has-inline-color\">initialisation des lignes GPIO<\/mark> :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>la v\u00e9rification de l&rsquo;existence des composants <code>led1<\/code> et <code>switch1<\/code> dans le <em>device tree<\/em> sous peine d&rsquo;\u00e9chec de compilation, gr\u00e2ce aux macros <code>DT_NODE_EXIST()<\/code> et <code>DT_NODELABEL()<\/code>,<\/li>\n\n\n\n<li>la r\u00e9cup\u00e9ration de la propri\u00e9t\u00e9 <code>gpios<\/code> de ces composants gr\u00e2ce \u00e0 la macro <code>GPIO_DT_SPEC_GET()<\/code>,<\/li>\n\n\n\n<li>la configuration en sortie de la LED. Les GPIO sont par d\u00e9faut en entr\u00e9e, ce n&rsquo;est donc pas n\u00e9cessaire pour le bouton.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Ensuite <mark style=\"background-color:#ffff80\" class=\"has-inline-color\">la boucle principale<\/mark> se passe en deux temps&nbsp;:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lecture par <em>polling<\/em> du bouton <code>switch_1<\/code> avec la fonction <code>gpio_pin_get_dt()<\/code>.<\/li>\n\n\n\n<li>Si le bouton n&rsquo;est pas press\u00e9, on reprend la boucle.<\/li>\n\n\n\n<li>Si le bouton est press\u00e9, on attend qu&rsquo;il soit rel\u00e2ch\u00e9 en faisant des petites attentes d&rsquo;une milliseconde avec la fonction <code>k_msleep()<\/code>.<\/li>\n\n\n\n<li>Une fois qu&rsquo;il est rel\u00e2ch\u00e9 on bascule l&rsquo;\u00e9tat de la LED avec <code>gpio_pin_toggle_dt()<\/code>.<\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Donc la LED changera d&rsquo;\u00e9tat \u00e0 chaque pression sur le bouton.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Compilation et installation<\/h2>\n\n\n\n<p>Pour compiler notre code nous allons nous placer dans le r\u00e9pertoire <code>zephyr-project<\/code>, et appeler&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(.venv)&#91;zephyr-project]$<strong> west  build  -p always  -b rpi_pico  zephyr-apps\/gpio-01<\/strong>\n &#91;...]\n\n(.venv)&#91;zephyr-project]$ <strong>ls<\/strong>\nbootloader  <strong>build<\/strong>  modules  tools  zephyr  zephyr-apps\n<\/code><\/pre>\n\n\n\n<p>Lorsque nous lan\u00e7ons cette commande,  <code>west<\/code> re-g\u00e9n\u00e8re \u00e0 chaque fois (option <code>-p always<\/code>) un r\u00e9pertoire <code>build\/<\/code> qui contient les r\u00e9sultats de la compilation&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(.venv)&#91;zephyr-project]$ <strong>ls  build\/<\/strong>\napp          CMakeCache.txt       compile_commands.json  sysbuild_modules.txt  zephyr_settings.txt\nbootloader   CMakeFiles           Kconfig                zephyr\nbuild.ninja  cmake_install.cmake  modules                zephyr_modules.txt\n<\/code><\/pre>\n\n\n\n<p>Dans le sous-r\u00e9pertoire <code>build\/zephyr\/<\/code> nous trouvons le fichier <code>zephyr.uf2<\/code> \u00e0 placer dans la m\u00e9moire flash du Raspberry Pico. On le branche sur le PC en conservant le bouton <code>bootsel<\/code> appuy\u00e9 et au bout de cinq secondes, il devient accessible sous forme d&rsquo;interface USB <em>storage<\/em>. On peut alors copier le fichier produit&nbsp;:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>(.venv)&#91;zephyr-project]$ <strong>cp  build\/zephyr\/zephyr.uf2  \/media\/cpb\/RPI-RP2\/<\/strong><\/code><\/pre>\n\n\n\n<p>Le Pico red\u00e9marre aussit\u00f4t la copie termin\u00e9e et nous pouvons voir les changements d&rsquo;\u00e9tats de la LED.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"324\" height=\"576\" src=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2024\/08\/zephyr-02.gif\" alt=\"\" class=\"wp-image-6566\"\/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"sources\">Sources<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>API de programmation avec Zephyr&nbsp;: <a href=\"https:\/\/docs.zephyrproject.org\/apidoc\/latest\/index.html\" target=\"_blank\" rel=\"noreferrer noopener nofollow\"><strong>https:\/\/docs.zephyrproject.org\/apidoc\/latest\/index.html<\/strong><\/a><\/li>\n\n\n\n<li>Documentation du Raspberry Pico&nbsp;: <a href=\"https:\/\/datasheets.raspberrypi.com\/pico\/pico-datasheet.pdf\" target=\"_blank\" rel=\"noreferrer noopener nofollow\"><strong>https:\/\/datasheets.raspberrypi.com\/pico\/pico-datasheet.pdf<\/strong><\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>Nous avons vu comment \u00e9crire et compiler une application minimale pour piloter les lignes GPIO d&rsquo;un micro-contr\u00f4leur Raspberry Pi Pico. Nous reviendrons sur la gestion des GPIO dans un prochain article, mais en utilisant un autre microcontr\u00f4leur tr\u00e8s r\u00e9pandu (ESP32).<\/p>\n\n\n\n<p class=\"has-text-align-center\">&#8211;<\/p>\n\n\n\n<p>Dans le prochain chapitre nous verrons un premier aper\u00e7u de l&rsquo;apport principal de Zephyr par rapport \u00e0 une programmation \u00ab\u00a0<em>bare metal<\/em>\u00a0\u00bb sans OS&nbsp;: le multit\u00e2che et l&rsquo;ordonnancement.<\/p>\n\n\n\n<p class=\"has-text-align-center\">&#8211;<\/p>\n\n\n\n<p>Si vous pr\u00e9f\u00e9rez assister \u00e0 une session de formation sur \u00ab&nbsp;Zephyr OS&nbsp;\u00bb en mode pr\u00e9sentiel ou distanciel, ou disposer d\u2019une assistance technique personnalis\u00e9e pour vos d\u00e9veloppement n\u2019h\u00e9sitez pas \u00e0 <a href=\"mailto:christophe.blaess@logilin.fr\"><strong><mark style=\"background-color:#c7efdb\" class=\"has-inline-color\">me contacter<\/mark><\/strong><\/a>.<\/p>\n\n\n\n<p class=\"has-text-align-center\">.<\/p>","protected":false},"excerpt":{"rendered":"<p>Nous avons vu dans le premier article de cette s&eacute;rie comment construire une image de Zephyr OS pour Raspberry Pi Pico en utilisant un exemple basique (&laquo;&nbsp;blinky&laquo;&nbsp;). Nous allons &agrave; pr&eacute;sent voir comment d&eacute;velopper une application personnelle tr&egrave;s simple, toujours sur le microcontr&ocirc;leur pour Raspberry Pico.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,16,11,25],"tags":[],"class_list":["post-6529","post","type-post","status-publish","format-standard","hentry","category-embarque","category-microcontroleur","category-raspberry-pi","category-zephyros"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/6529","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/comments?post=6529"}],"version-history":[{"count":34,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/6529\/revisions"}],"predecessor-version":[{"id":6967,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/6529\/revisions\/6967"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=6529"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=6529"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=6529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}