{"id":4488,"date":"2016-05-22T21:15:33","date_gmt":"2016-05-22T20:15:33","guid":{"rendered":"http:\/\/www.blaess.fr\/christophe\/?p=4488"},"modified":"2024-08-07T21:30:02","modified_gmt":"2024-08-07T20:30:02","slug":"xenomai-3-sur-raspberry-pi-2","status":"publish","type":"post","link":"https:\/\/www.blaess.fr\/christophe\/2016\/05\/22\/xenomai-3-sur-raspberry-pi-2\/","title":{"rendered":"Xenomai 3 sur Raspberry Pi 2"},"content":{"rendered":"<p style=\"text-align: justify;\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-4526\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/Xenomai-Raspberry-Pi-2.png\" alt=\"Xenomai 3 on Raspberry Pi 2\" width=\"250\" height=\"178\" \/>Depuis plusieurs ann\u00e9es l&rsquo;installation de Xenomai sur un Raspberry Pi 1 se fait assez facilement, et les r\u00e9sultats en sont plut\u00f4t satisfaisants. Malheureusement l&rsquo;installation sur un Raspberry Pi 2 ne fonctionnait pas. Le probl\u00e8me a \u00e9t\u00e9 r\u00e9solu depuis quelques mois par un patch de Mathieu Rondonneau qui permet d&rsquo;utiliser la toute derni\u00e8re version de Xenomai (3.0.2).<br \/>\n<!--more-->\n<\/p>\n<p style=\"text-align: justify;\">Xenomai 3 propose deux mod\u00e8les de fonctionnement&nbsp;:<\/p>\n<ul>\n<li style=\"text-align: justify;\">Dans le mode <em>Mercury<\/em>, les biblioth\u00e8ques de Xenomai permettent de faire fonctionner du code applicatif (utilisant \u00e9ventuellement l&rsquo;API d&rsquo;un autre syst\u00e8me comme <em>VxWorks<\/em> ou <em>pSOS)<\/em> sur un noyau Linux standard, de pr\u00e9f\u00e9rence une version <em>PREEMPT_RT<\/em>.<\/li>\n<li style=\"text-align: justify;\">Dans le mode <em>Cobalt<\/em>, le syst\u00e8me <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Adeos\" target=\"_blank\" rel=\"noopener\">Adeos<\/a> (<em>ipipe<\/em>) capture les interruptions avant le noyau Linux et est donc capable d&rsquo;activer des t\u00e2ches Xenomai dans un temps plus pr\u00e9visible. L&rsquo;int\u00e9gration est un peu plus complexe puisqu&rsquo;elle n\u00e9cessite de modifier le code du noyau Linux.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">C&rsquo;est ce dernier mode (<em>Cobalt<\/em>) que nous allons installer.<\/p>\n<h1 style=\"text-align: justify;\">Pr\u00e9paration<\/h1>\n<p style=\"text-align: justify;\">Commen\u00e7ons par t\u00e9l\u00e9charger et d\u00e9compresser l&rsquo;archive de Xenomai. Je prends la derni\u00e8re version disponible&nbsp;:<\/p>\n<pre>$ <strong>wget  http:\/\/xenomai.org\/downloads\/xenomai\/stable\/xenomai-3.0.2.tar.bz2<\/strong>\n [...]\n$ <strong>tar  xjf  xenomai-3.0.2.tar.bz2<\/strong><\/pre>\n<p style=\"text-align: justify;\">Voyons pour quelles versions du kernel le patch <em>ipipe<\/em> est disponible&nbsp;:<\/p>\n<pre>$ <strong>ls  xenomai-3.0.2\/kernel\/cobalt\/arch\/arm\/patches\/<\/strong>\nipipe-core-3.10.32-arm-13.patch\u00a0 ipipe-core-3.18.20-arm-9.patch\u00a0 README\nipipe-core-3.14.44-arm-16.patch\u00a0 ipipe-core-4.1.18-arm-4.patch<\/pre>\n<p style=\"text-align: justify;\">Le choix le plus adapt\u00e9 sera un noyau 4.1. T\u00e9l\u00e9chargeons le noyau Linux, plus particuli\u00e8rement sa version sp\u00e9cifique pour Raspberry Pi&nbsp;:<\/p>\n<pre>$ <strong>git  clone https:\/\/github.com\/raspberrypi\/linux<\/strong>\nClonage dans 'linux'...\nremote: Counting objects: 4883927, done.\nremote: Compressing objects: 100% (26\/26), done.\nremote: Total 4883927 (delta 20), reused 12 (delta 12), pack-reused 4883889\nR\u00e9ception d'objets: 100% (4883927\/4883927), 1.40 GiB | 1.63 MiB\/s, done.\nR\u00e9solution des deltas: 100% (4041858\/4041858), done.\nV\u00e9rification de la connectivit\u00e9... fait.\nChecking out files: 100% (52713\/52713), done.<\/pre>\n<p style=\"text-align: justify;\">Nous extrayons la branche 4.1 et v\u00e9rifions le num\u00e9ro complet&nbsp;:<\/p>\n<pre>$ <strong>cd  linux\/<\/strong>\n$ <strong>git  checkout  rpi-4.1.y<\/strong>\nChecking out files: 100% (22027\/22027), done.\nLa branche rpi-4.1.y est param\u00e9tr\u00e9e pour suivre la branche distante rpi-4.1.y depuis origin.\nBasculement sur la nouvelle branche 'rpi-4.1.y'\n$ <strong>head  -3  Makefile <\/strong>\nVERSION = 4\nPATCHLEVEL = 1\nSUBLEVEL = 21<\/pre>\n<p style=\"text-align: justify;\">Le noyau de la branche 4.1 pour Raspberry Pi est un 4.1.21. Le patch <em>ipipe<\/em> est pr\u00e9vu pour un noyau 4.1.18. Nous pourrions remonter l&rsquo;historique <em>git<\/em> pour trouver une version 4.1.18 exacte. N\u00e9anmoins, je pr\u00e9f\u00e8re \u00e9viter car nous aurons besoin d&rsquo;appliquer un second patch, qui a \u00e9t\u00e9 tr\u00e8s probablement produit sur un noyau 4.1.21, et qui entre en conflit avec l&rsquo;arborescence <code>arch\/arm\/mach-bcm<\/code> du 4.1.18.<\/p>\n<p style=\"text-align: justify;\">Pr\u00e9parons une branche de travail afin d&rsquo;isoler les modifications de Xenomai des sources d&rsquo;origine&nbsp;:<\/p>\n<pre>$ <strong>git  checkout  -b  xenomai-3.0.2<\/strong>\nBasculement sur la nouvelle branche 'xenomai-3.0.2'<\/pre>\n<p style=\"text-align: justify;\">Et v\u00e9rifions si le patch <em>ipipe<\/em> s&rsquo;applique bien&nbsp;:<\/p>\n<pre>$ <strong>patch  --dry-run  -p1  &lt;  ..\/xenomai-3.0.2\/kernel\/cobalt\/arch\/arm\/patches\/ipipe-core-4.1.18-arm-4.patch<\/strong>\nchecking file arch\/arm\/Kconfig\nHunk #3 succeeded at 533 (offset 36 lines).\nHunk #4 succeeded at 720 (offset 36 lines).\n[...]\nchecking file mm\/mmu_context.c\nchecking file mm\/mprotect.c\nchecking file mm\/vmalloc.c<\/pre>\n<p style=\"text-align: justify;\">Nous voyons les messages <em>Hunk succeeded<\/em> indiquant que le patch a d\u00fb \u00eatre d\u00e9cal\u00e9 pour \u00eatre appliqu\u00e9 correctement, mais aucune erreur ne se produit. L&rsquo;argument <code>--dry-run<\/code> de l&rsquo;ex\u00e9cution ci-dessus permettait de v\u00e9rifier si le patch s&rsquo;appliquait correctement sans faire de modifications.<\/p>\n<p style=\"text-align: justify;\">Pour appliquer v\u00e9ritablement le patch <em>ipipe<\/em>, un script est livr\u00e9 qui permet en outre d&rsquo;installer le domaine Xenomai proprement dit dans le noyau Linux. Utilisons-le&nbsp;:<\/p>\n<pre>$ <strong>cd  ..<\/strong>\n$ <strong>xenomai-3.0.2\/scripts\/prepare-kernel.sh  --linux=linux\/  --arch=arm  --ipipe=xenomai-3.0.2\/kernel\/cobalt\/arch\/arm\/patches\/ipipe-core-4.1.18-arm-4.patch<\/strong><\/pre>\n<p style=\"text-align: justify;\">Enregistrons les modifications apport\u00e9es&nbsp;:<\/p>\n<pre>$ <strong>cd  linux\/<\/strong>\n$ <strong>git  add  '*'<\/strong>\n$ <strong>git  commit  -a  -m  \"ipipe-core-4.1.18 patch\"<\/strong><\/pre>\n<p style=\"text-align: justify;\">Appliquons maintenant le patch de Mathieu Rondonneau que vous pouvez t\u00e9l\u00e9charger ici&nbsp;: <a href=\"http:\/\/www.blaess.fr\/christophe\/files\/article-2016-05-22\/patch-xenomai-3-on-bcm-2709.patch\"><code>patch-xenomai-3-on-bcm-2709.patch<\/code><\/a><\/p>\n<pre>$ <strong>cd  ..<\/strong>\n$ <strong>wget  http:\/\/www.blaess.fr\/christophe\/files\/article-2016-05-22\/patch-xenomai-3-on-bcm-2709.patch<\/strong>\n$ <strong>cd  linux\/<\/strong>\n$ <strong>patch  -p1  &lt;  ..\/patch-xenomai-3-on-bcm-2709.patch  --dry-run<\/strong>\nchecking file arch\/arm\/Kconfig\nchecking file arch\/arm\/mach-bcm2709\/armctrl.c\nchecking file arch\/arm\/mach-bcm2709\/bcm2708_gpio.c\nchecking file arch\/arm\/mach-bcm2709\/bcm2709.c\nchecking file arch\/arm\/mach-bcm2709\/include\/mach\/entry-macro.S<\/pre>\n<p style=\"text-align: justify;\">Le patch passe bien sur cette version, appliquons-le en retirant l&rsquo;argument <code>--dry-run<\/code> :<\/p>\n<pre>$ <strong>patch  -p1  &lt;  ..\/patch-xenomai-3-on-bcm-2709.patch<\/strong>\npatching file arch\/arm\/Kconfig\npatching file arch\/arm\/mach-bcm2709\/armctrl.c\npatching file arch\/arm\/mach-bcm2709\/bcm2708_gpio.c\npatching file arch\/arm\/mach-bcm2709\/bcm2709.c\npatching file arch\/arm\/mach-bcm2709\/include\/mach\/entry-macro.S\n$ <strong>git  commit  -a  -m  \"xenomai-3-on-bcm2709 patch\"<\/strong><\/pre>\n<h1 style=\"text-align: justify;\">Compilations<\/h1>\n<h2>Kernel Linux et Xenomai<\/h2>\n<p style=\"text-align: justify;\">Nous pouvons configurer et compiler ce noyau&nbsp;:<\/p>\n<pre>$ <strong>make  ARCH=arm  bcm2709_defconfig<\/strong>\n  HOSTCC  scripts\/kconfig\/zconf.tab.o\n  HOSTLD  scripts\/kconfig\/conf\n#\n# configuration written to .config\n#\n$ <strong>make  ARCH=arm  menuconfig<\/strong><\/pre>\n<p>Deux messages \u00ab\u00a0WARNING\u00a0\u00bb nous indiquent que certains \u00e9l\u00e9ments de la configuration actuelle entrent en conflit avec Xenomai. Nous d\u00e9sactivons les entr\u00e9es suivantes&nbsp;:<\/p>\n<pre>CPU Power Management  ---&gt;\n    CPU Frequency scaling  ---&gt;\n        [ ] CPU Frequency scaling<\/pre>\n<p>et<\/p>\n<pre>Kernel Features  ---&gt;\n    [ ] Contiguous Memory Allocator<\/pre>\n<p>puis<\/p>\n<pre>Kernel Features  ---&gt;\n    [ ] Allow for memory compaction<\/pre>\n<p>et enfin<\/p>\n<pre>Kernel Hacking  ---&gt;\n    [ ] KGDB: kernel debugger ---&gt;<\/pre>\n<p>Une derni\u00e8re modification est n\u00e9cessaire&nbsp;; elle n&rsquo;a rien de sp\u00e9cifique \u00e0 Xenomai. Cela nous assure que le noyau disposera des bons arguments sur sa ligne de commande.<br \/>\nDans le menu<\/p>\n<pre>Boot options  ---&gt;<\/pre>\n<p>passer l&rsquo;option<\/p>\n<pre>    Kernel command line type (Use bootloader kernel arguments if available)  ---&gt;<\/pre>\n<p>\u00e0 la valeur<\/p>\n<pre>        (X) Extend bootloader kernel arguments<\/pre>\n<p style=\"text-align: justify;\">Nous pouvons lancer la compilation avec un&nbsp;:<\/p>\n<pre>$ <strong>make  ARCH=arm  CROSS_COMPILE=arm-linux-<\/strong><\/pre>\n<p style=\"text-align: justify;\">Bien entendu cela suppose que nous ayons configur\u00e9 dans notre variable <code>PATH<\/code> l&rsquo;acc\u00e8s \u00e0 une <em>toolchain<\/em> de <em>cross-compilation<\/em>, par exemple g\u00e9n\u00e9r\u00e9e avec Buildroot comme nous l&rsquo;avions fait dans l&rsquo;article \u00ab\u00a0<a href=\"http:\/\/www.blaess.fr\/christophe\/2015\/12\/08\/creation-dun-systeme-complet-avec-buildroot-2015-11\/\" target=\"_blank\" rel=\"noopener\">Cr\u00e9ation d&rsquo;un syst\u00e8me complet avec Buildroot 2015.11<\/a>\u00ab\u00a0.<\/p>\n<p style=\"text-align: justify;\">Au bout de quelques minutes notre noyau est pr\u00eat. Je vais l&rsquo;installer sur une carte micro-SD poss\u00e9dant deux partitions&nbsp;: <code>BOOT<\/code> (format\u00e9e en <em>vfat)<\/em> et <code>ROOT<\/code> (format\u00e9e en <em>ext2).<\/em> <strong>La partition BOOT comprend d\u00e9j\u00e0 le <em>bootloader<\/em> du Raspberry Pi<\/strong> obtenu lors de la compilation avec <strong>Buildroot 2016.02<\/strong> (de mani\u00e8re identique \u00e0 l&rsquo;article indiqu\u00e9 ci-dessus).<\/p>\n<pre>$ <strong>cp  arch\/arm\/boot\/zImage  \/media\/$USER\/BOOT\/<\/strong>\n$ <strong>cp  arch\/arm\/boot\/dts\/bcm2709-rpi-2-b.dtb  \/media\/$USER\/BOOT\/<\/strong><\/pre>\n<h2 style=\"text-align: justify;\">Xenomai en espace utilisateur<\/h2>\n<p style=\"text-align: justify;\">Nous allons maintenant compiler les biblioth\u00e8ques de Xenomai, qui permettent de faire fonctionner le code dans l&rsquo;espace utilisateur.<\/p>\n<pre>$ <strong>cd ..\/xenomai-3.0.2\/<\/strong>\n$ <strong>.\/scripts\/bootstrap<\/strong> \n  [...]\n$ <strong>.\/configure  --host=arm-linux  --enable-smp<\/strong>\n  [...]\n$ <strong>make<\/strong>\n  [...]<\/pre>\n<p style=\"text-align: justify;\">Les biblioth\u00e8ques et les utilitaires ainsi compil\u00e9s vont \u00eatre install\u00e9s sur la partition ROOT, qui contient un syst\u00e8me de fichiers minimal avec Busybox et quelques scripts g\u00e9n\u00e9r\u00e9s par Buildroot, comme dans l&rsquo;article mentionn\u00e9 ci-dessus.<\/p>\n<p style=\"text-align: justify;\">L&rsquo;acc\u00e8s \u00e0 cette partition <code>ROOT<\/code> n\u00e9cessitant les droits d&rsquo;administrateur, je pr\u00e9pare d&rsquo;abord une copie de l&rsquo;ensemble des fichiers \u00e0 installer que je transf\u00e8re ensuite avec le pr\u00e9fixe <code>sudo<\/code>.<\/p>\n<pre>$ <strong>make  DESTDIR=$(pwd)\/target  install<\/strong>\n  [...]\n$ <strong>sudo  cp  -a  target\/*  \/media\/$USER\/ROOT\/<\/strong>\n$ <strong>umount  \/media\/$USER\/*<\/strong><\/pre>\n<h1 style=\"text-align: justify;\">Tests<\/h1>\n<p style=\"text-align: justify;\">Le moment de v\u00e9rit\u00e9 est arriv\u00e9, on ins\u00e8re la carte micro-SD, on branche une console sur le port s\u00e9rie, et on d\u00e9marre un \u00e9mulateur de terminal comme Minicom. Voici le r\u00e9sultat&nbsp;:<\/p>\n<pre>Uncompressing Linux... done, booting the kernel.\n[    0.000000] Booting Linux on physical CPU 0xf00\n[    0.000000] Initializing cgroup subsys cpuset\n[    0.000000] Initializing cgroup subsys cpu\n[    0.000000] Initializing cgroup subsys cpuacct\n[    0.000000] Linux version 4.1.21-logilin+ (cpb@Logilin) (gcc version 4.9.3 (Buildroot 2016.02) ) #2 SMP Sun May 22 08:40:39 CEST 2016\n[    0.000000] CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c5387d\n[    0.000000] CPU: PIPT \/ VIPT nonaliasing data cache, VIPT aliasing instruction cache\n[    0.000000] Machine: BCM2709\n[    0.000000] Memory policy: Data cache writealloc\n  [...]\n[    0.000000] I-pipe, 19.200 MHz clocksource, wrap in 960767920505705 ms\n[    0.000000] clocksource ipipe_tsc: mask: 0xffffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns\n[    0.000000] clocksource arch_sys_counter: mask: 0xffffffffffffff max_cycles: 0x46d987e47, max_idle_ns: 440795202767 ns\n[    0.000000] sched_clock: 56 bits at 19MHz, resolution 52ns, wraps every 4398046511078ns\n[    0.000001] Switching to timer-based delay loop, resolution 52ns\n[    0.000917] Interrupt pipeline (release #4)\n\n  [...]\n[    0.948130] [Xenomai] scheduling class idle registered.\n[    0.953408] [Xenomai] scheduling class rt registered.\n[    0.958732] I-pipe: head domain Xenomai registered.\n[    0.967286] [Xenomai] Cobalt v3.0.2 (Exact Zero) \n  [...]\nWelcome to Buildroot\nbuildroot login:<\/pre>\n<p style=\"text-align: justify;\">Un oeil averti verra passer dans les traces du noyau quelques messages li\u00e9s \u00e0 Xenomai ou <em>ipipe. <\/em>Connectons-nous et examinons le syst\u00e8me&nbsp;:<\/p>\n<pre>buildroot login: <strong>root<\/strong>\nPassword: \n# <strong>uname -a<\/strong>\nLinux buildroot 4.1.21-logilin+ #2 SMP Sun May 22 08:40:39 CEST 2016 armv7l GNU\/Linux\n# <strong>cat \/proc\/xenomai\/version<\/strong>\n3.0.2\n# <strong>cat \/proc\/ipipe\/version<\/strong>\n4<\/pre>\n<p style=\"text-align: justify;\">Notre syst\u00e8me fonctionne bien avec Xenomai et <em>ipipe.<\/em> Le plus simple pour s&rsquo;assure de son bon fonctionnement est d&rsquo;utiliser l&rsquo;un des outils de test livr\u00e9s dans <code>\/usr\/xenomai\/bin<\/code>.<\/p>\n<pre># <strong>\/usr\/xenomai\/bin\/latency<\/strong>\n== Sampling period: 1000 us\n== Test mode: periodic user-mode task\n== All results in microseconds\nwarming up...\nRTT|  00:00:01  (periodic user-mode task, 1000 us period, priority 99)\nRTH|----lat min|----lat avg|----lat max|-overrun|---msw|---lat best|--lat worst\nRTD|      2.551|      2.795|      7.290|       0|     0|      2.551|      7.290\nRTD|      2.551|      2.809|      7.082|       0|     0|      2.551|      7.290\nRTD|      2.498|      2.825|      8.748|       0|     0|      2.498|      8.748\nRTD|      2.446|      2.787|      7.393|       0|     0|      2.446|      8.748\nRTD|      2.549|      2.784|      6.768|       0|     0|      2.446|      8.748\nRTD|      2.497|      2.784|      6.716|       0|     0|      2.446|      8.748\nRTD|      2.549|      2.781|      6.611|       0|     0|      2.446|      8.748<\/pre>\n<p style=\"text-align: justify;\">Cet outil montre les fluctuations (en micro-secondes) d&rsquo;un timer de fr\u00e9quence 1kHz. Ceci est assez r\u00e9v\u00e9lateur des variations du temps de latence des interruptions \u00e9galement. La colonne la plus int\u00e9ressante est la derni\u00e8re \u00e0 droite, puisqu&rsquo;elle montre le retard maximum atteint pendant l&rsquo;ex\u00e9cution. Au bout de quelques minutes, cette valeur se stabilise autour de 9 micro-secondes. En laissant l&rsquo;exp\u00e9rience pendant une heure et en r\u00e9cup\u00e9rant un histogramme des latences observ\u00e9es, on obtient les valeurs et graphique suivants&nbsp;:<\/p>\n<pre># ----lat min|----lat avg|----lat max|-overrun|---msw|\n#       2.563|      3.363|     11.283|       0|     0|<\/pre>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-no-load.png\" rel=\"attachment wp-att-4509\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4509 size-full\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-no-load.png\" alt=\"Xenomai 3 on Raspberry Pi 2\" width=\"800\" height=\"600\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-no-load.png 800w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-no-load-300x225.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-no-load-768x576.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Sur l&rsquo;axe des abscisses, les latences en micro-secondes. En ordonn\u00e9es le nombre de cas o\u00f9 chaque latence a \u00e9t\u00e9 observ\u00e9e. Cet axe est logarithmique. Nous voyons donc qu&rsquo;une \u00e9norme majorit\u00e9 des latences est de 3 ou 4 micro-secondes et que la pire latence est de 12 micro-secondes.<\/p>\n<p style=\"text-align: justify;\">N\u00e9anmoins pour des vraies mesures r\u00e9alistes, il faut stresser le syst\u00e8me intens\u00e9ment. Pour ce faire, il existe un script nomm\u00e9 <code>dohell<\/code>, livr\u00e9 avec Xenomai qui assure une charge tr\u00e8s forte en nombre de t\u00e2ches et op\u00e9rations d&rsquo;entr\u00e9es-sorties. J&rsquo;ai fait tourner ce script pendant une heure, avec en outre une charge importante en interruptions gr\u00e2ce \u00e0 un <code>ping<\/code> en mode <em>flood<\/em> qui se produisait r\u00e9guli\u00e8rement pendant une dizaine de secondes.<\/p>\n<pre># ----lat min|----lat avg|----lat max|-overrun|---msw|\n#       1.318|     23.331|     61.452|       0|     0|<\/pre>\n<p><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-heavy-load.png\" rel=\"attachment wp-att-4512\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4512 size-full\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-heavy-load.png\" alt=\"1h. charge \u00e9lev\u00e9e\" width=\"800\" height=\"600\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-heavy-load.png 800w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-heavy-load-300x225.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/1-hour-heavy-load-768x576.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Enfin, j&rsquo;ai r\u00e9alis\u00e9 une mesure pendant deux heures en alternant les p\u00e9riodes de faible charge et les p\u00e9riodes de charge tr\u00e8s intense. Je pense en effet que les pires latences se mesurent plut\u00f4t en r\u00e9gimes transitoires qu&rsquo;en r\u00e9gimes permanents. Il est donc important d&rsquo;alterner les conditions d&rsquo;ex\u00e9cution.<\/p>\n<pre># ----lat min|----lat avg|----lat max|-overrun|---msw|\n#      -0.346|     10.508|     62.491|       0|     0|<\/pre>\n<p style=\"text-align: justify;\"><a href=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/2-hours-mixed-load.png\" rel=\"attachment wp-att-4513\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4513 size-full\" src=\"http:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/2-hours-mixed-load.png\" alt=\"Xenomai 3 on Raspberry Pi 2\" width=\"800\" height=\"600\" srcset=\"https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/2-hours-mixed-load.png 800w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/2-hours-mixed-load-300x225.png 300w, https:\/\/www.blaess.fr\/christophe\/wp-content\/uploads\/2016\/05\/2-hours-mixed-load-768x576.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><br \/>\nNous pouvons remarquer que dans ce dernier cas, la latence minimale est de -0.346 micro-seconde. Ceci peut para\u00eetre surprenant mais est normal. Xenomai estime en effet la latence minimale et anticipe les d\u00e9clenchements des timers de la valeur (en nanosecondes) indiqu\u00e9e dans <code>\/proc\/xenomai\/latency<\/code>. Nous pourrions donc la corriger ainsi&nbsp;:<\/p>\n<pre># <strong>cat \/proc\/xenomai\/latency<\/strong>\n10520\n# <strong>echo $((10520 - 346 )) &gt; \/proc\/xenomai\/latency<\/strong>\n# <strong>cat \/proc\/xenomai\/latency<\/strong>\n10156\n#<\/pre>\n<h1>Conclusion<\/h1>\n<p style=\"text-align: justify;\">Nous voyons ainsi que le support de Xenomai sur Raspberry Pi 2 est assez simple \u00e0 configurer et installer. Bien s\u00fbr il faudrait faire des tests plus longs et plus complets pour avoir une bonne certitude de la latence maximale mais je pense que la valeur de 63 microsecondes que nous avons obtenue doit en \u00eatre une assez bonne approche.<\/p>\n<p style=\"text-align: justify;\">N&rsquo;h\u00e9sitez pas \u00e0 me faire part de vos essais et r\u00e9sultats.<\/p>\n<p style=\"text-align: justify;\">Je tiens \u00e0 remercier Nicolas Schurando qui m&rsquo;a aid\u00e9 lors d&rsquo;une s\u00e9ance de formation \u00e0 tester cette nouvelle version de Xenomai.<\/p>\n<p style=\"text-align: justify;\">","protected":false},"excerpt":{"rendered":"<p>Depuis plusieurs ann&eacute;es l&rsquo;installation de Xenomai sur un Raspberry Pi 1 se fait assez facilement, et les r&eacute;sultats en sont plut&ocirc;t satisfaisants. Malheureusement l&rsquo;installation sur un Raspberry Pi 2 ne fonctionnait pas. Le probl&egrave;me a &eacute;t&eacute; r&eacute;solu depuis quelques mois par un patch de Mathieu Rondonneau qui permet d&rsquo;utiliser la toute derni&egrave;re version de Xenomai [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,8,11,14],"tags":[],"class_list":["post-4488","post","type-post","status-publish","format-standard","hentry","category-embarque","category-linux-2","category-raspberry-pi","category-temps-reel"],"_links":{"self":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4488","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=4488"}],"version-history":[{"count":37,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4488\/revisions"}],"predecessor-version":[{"id":6422,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/posts\/4488\/revisions\/6422"}],"wp:attachment":[{"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/media?parent=4488"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/categories?post=4488"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.blaess.fr\/christophe\/wp-json\/wp\/v2\/tags?post=4488"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}