<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Electronique Innovante</title>
	<atom:link href="http://innovelectronique.fr/feed/" rel="self" type="application/rss+xml" />
	<link>http://innovelectronique.fr</link>
	<description>Apprendre l'électronique par l'exemple</description>
	<pubDate>Tue, 08 May 2012 20:55:56 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Arduino et LIFA (LabVIEW Interface For Arduino)</title>
		<link>http://innovelectronique.fr/2012/05/04/arduino-et-lifa-labview-interface-for-arduino/</link>
		<comments>http://innovelectronique.fr/2012/05/04/arduino-et-lifa-labview-interface-for-arduino/#comments</comments>
		<pubDate>Fri, 04 May 2012 11:19:52 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[Arduino]]></category>

		<category><![CDATA[LabVIEW]]></category>

		<category><![CDATA[lifa]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=891</guid>
		<description><![CDATA[LIFA signifie LabVIEW Interface For Arduino. C&#8217;est une extension de LabVIEW (compatible à partir de la version 2009) qui permet de piloter une carte compatible Arduino depuis LabVIEW. Dans cet article je vous propose d&#8217;installer et de découvrir LIFA car pour l&#8217;instant je n&#8217;ai pas trouvé beaucoup de ressources sur Internet à ce sujet. Attention [...]]]></description>
			<content:encoded><![CDATA[<p>LIFA signifie LabVIEW Interface For Arduino. C&#8217;est une extension de LabVIEW (compatible à partir de la version 2009) qui permet de piloter une carte compatible Arduino depuis LabVIEW. Dans cet article je vous propose d&#8217;installer et de découvrir LIFA car pour l&#8217;instant je n&#8217;ai pas trouvé beaucoup de ressources sur Internet à ce sujet. Attention cet article n&#8217;est pas une présentation de LabVIEW ou d&#8217;Arduino (vous avez plein de ressources pour cela sur le web) mais une utilisation conjointe de LabVIEW et Arduino. Cependant les VI (Virtual Instrument) de tests sont très simples et il n&#8217;y a <strong>PAS</strong> de programmation C/C++ du coté Arduino.<br />
Note : Il existe un lien d'impression intégré dans ce post, veuillez svp visiter ce post pour l'imprimer.<br />
<span id="more-891"></span></p>
<h1>Matériels et logiciels nécessaire</h1>
<p><em>Matériels :</em></p>
<ul>
<li>un ordinateur de 	type compatible PC avec Microsoft Windows7 ou WindowsXP (je n&#8217;ai pas testé sous GNU/Linux mais ça doit être fonctionnel)</li>
<li>une carte compatible 	Arduino : dans notre cas une carte <a href="http://arduino.cc/en/Main/ArduinoBoardUno" target="_blank">arduino UNO</a></li>
<li>un shield de	prototypage ou une plaquette d&#8217;essai sans soudure (<a href="http://www.lextronic.fr/P4130-kit-arduino-protoshield.html">http://www.lextronic.fr/P4130-kit-arduino-protoshield.html</a> à 15€ par exemple)</li>
<li>divers shields en fonction des utilisations avancées : ethershield, Xbee Shield, etc&#8230; (facultatif)</li>
<li>quelques composants de bases (résistance, dels, &#8230;) et des capteurs (température, humidité aussi bien en I2C qu&#8217;en analogique)</li>
</ul>
<p><em>Logiciels :</em></p>
<ul>
<li>L&#8217;environnement de développement d&#8217;arduino ( <a href="http://arduino.cc/en/Main/Software">http://arduino.cc/en/Main/Software</a> )</li>
<li>NI LabVIEW (version d&#8217;évaluation disponible sur <a href="http://www.ni.com/trylabview/" target="_blank">http://www.ni.com/trylabview/</a>) avec les pilotes VISA qui gèrent la voie série ( <a href="http://joule.ni.com/nidu/cds/view/p/id/2251/lang/en" target="_blank">http://joule.ni.com/nidu/cds/view/p/id/2251/lang/en</a> )</li>
<li>VI Packet Manager : logiciel qui gère l&#8217;installation des extensions de LabVIEW disponible sur le site d&#8217;un partenaire de National Instrument ( 	<a href="http://jki.net/vipm/download">http://jki.net/vipm/download )<br />
</a></li>
<li>Le paquet LIFA décrit sur <a href="https://decibel.ni.com/content/groups/labview-interface-for-arduino">https://decibel.ni.com/content/groups/labview-interface-for-arduino</a> et son installation sur <a href="https://decibel.ni.com/content/docs/DOC-15971">https://decibel.ni.com/content/docs/DOC-15971</a></li>
<li>Le logiciel Fritzing 	pour dessiner les schémas de câblage ( <a href="http://fritzing.org/welcome/">http://fritzing.org/welcome/</a> )</li>
</ul>
<p>Téléchargez le tout puis installez dans l&#8217;ordre ci-dessus. La plupart du temps ça se résume à &#8220;suivant&#8221;, &#8220;suivant&#8221;,&#8230;&#8221;terminer&#8221;. La version de LIFA utilisée ici est 2.XX.</p>
<h1>Installation du firmware LIFA sur la carte Arduino</h1>
<p>Le firmware LIFA est disponible après installation dans le répertoire &#8220;C:\Program Files\National Instruments\LabVIEW 2011\vi.lib\LabVIEW Interface for Arduino\Firmware\LVIFA_Base&#8221; (du moins sur mon installation). Vous trouverez alors plusieurs fichiers dont les trois principaux sont :</p>
<ul>
<li>le sketch &#8220;LVIFA_Base.ino&#8221; : c&#8217;est ce sketch que vous compilerez et transfèrerez dans la platine Arduino</li>
<li>le sketch &#8220;LabVIEWInterface.ino&#8221; : il contient l&#8217;implémentation de toutes les fonctions utilisées par LabVIEW pour dialoguer avec la carte Arduino</li>
<li>le fichier d&#8217;inclusion &#8220;LabVIEWInterface.h&#8221; : ce fichier d&#8217;en-tête est particulièrement intéressant puisque c&#8217;est lui qui contient les &#8220;define&#8221; que vous pouvez modifier pour adapter LIFA. Trois &#8220;define&#8221; en particulier seront à modifier suivant vos projets :
<ul>
<li>DEFAULTBAUDRATE : la vitesse de transmission de la voie série. En effet LabVIEW communique avec la carte Arduino par une voie série, par défaut la vitesse est de 115200 bauds/s mais si vous utilisez une liaison série sans fil (XBee ou Bluetooth), il faudra sans doute baisser la vitesse de transmission pour fiabiliser le dialogue</li>
<li>COMMANDLENGHT : le nombre d&#8217;octets transmis en une seule fois par une commande LabVIEW. Par défaut cette valeur est à 15. Si c&#8217;est insuffisant pour votre projet il faut le changer ici et sur le diagramme LabVIEW</li>
<li>STEPPER_SUPPORT : permet ou non d&#8217;intégrer le support des moteurs pas à pas dans le firmware, cela permet de diminuer la taille du fichier hex</li>
</ul>
</li>
<li>Les autres fichiers sont pour la gestion des moteurs pas à pas.</li>
</ul>
<p>Chargez donc &#8220;LVIFA_Base.ino&#8221; dans l&#8217;environnement Arduino, compilez-le puis programmez votre carte Arduino.</p>
<p>Vous disposez normalement maintenant d&#8217;une Arduino prête à fonctionner avec LabVIEW.</p>
<p><em>Remarque</em> : L&#8217;extension &#8220;ino&#8221; est la nouvelle extension pour les &#8220;sketches&#8221; arduino depuis la version 1.00, avant l&#8217;extension était &#8220;pde&#8221;.</p>
<h1>Premier exemple : Allumer une diode depuis LabVIEW et lire l&#8217;état d&#8217;une entrée</h1>
<p>On commence toujours par une del <img src='http://innovelectronique.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> donc on échappe pas à la tradition ! Le câblage sur la plaquette d&#8217;essai peut se présenter de la manière suivante (le dessin est réalisé avec le logiciel Fritzing) :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple1-del.png" rel="lightbox[891]"><img class="aligncenter size-thumbnail wp-image-899" title="Cablage Exemple1 DEL" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple1-del-150x150.png" alt="Cablage Exemple1 DEL" width="150" height="150" /></a></p>
<p>Lancez LabVIEW, puis réalisez la face avant suivante:</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/faceavant-exemple1-del.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-903" title="Face avant Exemple1 DEL" src="http://innovelectronique.fr/wp-content/uploads/2012/05/faceavant-exemple1-del.png" alt="Face avant Exemple1 DEL" width="104" height="268" /></a></p>
<p>Lorsque vous passez sur le diagramme, une nouvel palette dédié à Arduino doit apparaitre :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/palette-arduino-diagramme-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-902" title="Palette arduino diagramme labview" src="http://innovelectronique.fr/wp-content/uploads/2012/05/palette-arduino-diagramme-labview.png" alt="Palette arduino diagramme labview" width="241" height="67" /></a></p>
<p>Réalisons le diagramme suivant:</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/diagramme-exemple1-del.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-904" title="Diagramme Exemple1-DEL" src="http://innovelectronique.fr/wp-content/uploads/2012/05/diagramme-exemple1-del.png" alt="Diagramme Exemple1-DEL" width="664" height="236" /></a></p>
<p>Les applications LabVIEW utilisant LIFA sont toutes construites sur le même modèle:</p>
<ol>
<li><strong>Établir la connexion avec la platine Arduino à l&#8217;aide du sous VI &#8220;INIT&#8221;</strong>. Celui-ci dispose de nombreuses entrées pour le configurer. Je vous conseille de créer des constantes pour ces entrées afin d&#8217;observer les différents choix possibles. La création d&#8217;une constante se fait en cliquant avec le bouton droit sur une des entrées puis choisir &#8220;Créer&#8221;, &#8220;Constante&#8221;. Si vous souhaitez modifier ces paramètres sur la face avant créez des indicateurs. Tout d&#8217;abord choisir le port COM qui a été créé lors de la première connexion de l&#8217;arduino (ici COM19). Choisir la vitesse, elle doit correspondre avec celle défini dans &#8220;LabVIEWInterface.h&#8221; (ici 115200 qui est la valeur par défaut), ensuite le choix de la carte Arduino (par défaut UNO). Les deux derniers paramètres sont laissés tels quels. En sortie vous obtenez la &#8220;ressource&#8221; initialisée (trait épais rose) qui sera utilisée par tous les sous VI arduino et de quoi gérer les erreurs (trait épais jaune).</li>
<li><strong>Initialiser les E/S</strong>. Si vous utilisez des E/S numériques, utilisez le sous VI &#8220;Set Digital Pin Mode&#8221;. Il faut préciser alors la broche concernée ( ici 8 ) et son sens ( ici output : on pilote une del ).</li>
<li><strong>Boucle infinie de gestion des évènements</strong>. Comme sur micro-controlleur vous avez une boucle infinie qui gère les évènements (on ne considère pas ici les interruptions). Cette boucle infinie est ici représentée par une boucle &#8220;while&#8221; (flèche épaisse grise qui reboucle sur elle-même). Pour arrêter cette boucle, créez un indicateur sur le terminal de répétition de la boucle (ici point rouge). On doit allumer la DEL en fonction de l&#8217;état de l&#8217;interrupteur à levier de la face avant (Commande DEL). On transforme tout d&#8217;abord l&#8217;information booléenne (true, false) en nombre (0,1) puis on envoie cette information à l&#8217;entrée du sous VI &#8220;Digital Write Pin&#8221;. La broche de sortie est bien sur toujours la 8. Si vous regardez bien le diagramme, un petit point rouge à l&#8217;entrée du VI &#8220;Digital Write Pin&#8221; est présent. Ce qui indique que les formats utilisés ne sont pas totalement compatibles (ici la conversion booléenne se fait vers un entier signé codée sur 16 bits, or le VI attend une valeur non signé sur 8 bits).</li>
<li><strong>Fermeture de la connexion avec la carte Arduino à l&#8217;aide du sous VI &#8220;CLOSE&#8221;</strong>. On libère ainsi proprement la mémoire et le port COM. Éventuellement câblez un gestionnaire d&#8217;erreurs simple.</li>
</ol>
<p>Testez votre programme, lors de la manipulation de l&#8217;interrupteur de la face avant la diode doit réagir en conséquence. Vous savez donc piloter en tout ou rien des sorties. A titre d&#8217;exercice, modifiez le câblage, la face avant et le diagramme pour lire et afficher l&#8217;état d&#8217;un interrupteur&#8230;..</p>
<p>La correction est donnée ci-dessous :</p>
<p>Le câblage :<a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple1-del-inter.png" rel="lightbox[891]"><img class="aligncenter size-thumbnail wp-image-917" title="Exemple 1 : DEL et Interrupteur" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple1-del-inter-150x150.png" alt="Exemple 1 : DEL et Interrupteur" width="150" height="150" /></a>La face avant dans LabVIEW:<a href="http://innovelectronique.fr/wp-content/uploads/2012/05/faceavant-exemple1-del-inter.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-918" title="Face avant dans LabVIEW - Exemple 1 DEL et Inter" src="http://innovelectronique.fr/wp-content/uploads/2012/05/faceavant-exemple1-del-inter.png" alt="Face avant dans LabVIEW - Exemple 1 DEL et Inter" width="283" height="264" /></a>Le diagramme :<a href="http://innovelectronique.fr/wp-content/uploads/2012/05/diagramme-exemple1-del-inter.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-919" title="Diagramme LabVIEW - Exemple 1 : DEL et Inter" src="http://innovelectronique.fr/wp-content/uploads/2012/05/diagramme-exemple1-del-inter.png" alt="Diagramme LabVIEW - Exemple 1 : DEL et Inter" width="715" height="248" /></a></p>
<p><em>Remarque</em>: Le microcontrolleur Atmel présent sur la carte Arduino possède des résistance de pull-up interne activable individuellement. Vous pouvez donc vous passez de la résistance de 10K sur le schéma de câblage à condition de modifier le &#8220;sketch&#8221; de LIFA dans la fonction setup. Lire cet article : <a href="http://arduino.cc/fr/Main/ApprendreBrochesEntreeSortie" target="_blank">http://arduino.cc/fr/Main/ApprendreBrochesEntreeSortie</a></p>
<p><em>Remarque</em>: Si vous avez plusieurs broches à initialiser en entrée ou en sortie, le faire dans une boucle sous LabVIEW.</p>
<h1>Deuxième exemple : Lire une tension analogique</h1>
<p>Nous allons lire la tension issu d&#8217;un capteur de température analogique (LM35 : datasheet <a href="http://www.ti.com/product/lm35" target="_blank">ici</a>) et l&#8217;afficher sous LabVIEW. Ce capteur donne 0V à 0°C et à une pente de +10mV/°C. Ce qui fait par exemple à 25°C : 250mV. La variation de tension n&#8217;est pas importante et nous choisissons de ne pas amplifier cette tension pour garder un schéma de câblage simple. Le convertisseur analogique numérique de l&#8217;Atmel est un 10bits. La plage de numérisation est de base entre 0V et +Vcc = 5V. Le quantum fait donc 5/2^10 = 4,88mV. On réalise le câblage suivant:</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple2-temp.png" rel="lightbox[891]"><img class="aligncenter size-thumbnail wp-image-923" title="Exemple 2 - Capteur de température analogique" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple2-temp-150x150.png" alt="Exemple 2 - Capteur de température analogique" width="150" height="150" /></a>La face avant sous LabVIEW peut se présenter de la manière suivante:</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple2-temp-face-avant-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-925" title="Exemple 2 - Capteur de température analogique - Face avant LabVIEW" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple2-temp-face-avant-labview.png" alt="Exemple 2 - Capteur de température analogique - Face avant LabVIEW" width="594" height="298" /></a></p>
<p>Le diagramme se présente de la manière suivante :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple2-temp-diagramme-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-926" title="Exemple 2 - Capteur de température analogique - Diagramme LabVIEW" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple2-temp-diagramme-labview.png" alt="Exemple 2 - Capteur de température analogique - Diagramme LabVIEW" width="619" height="241" /></a><em>Remarque</em> : la sortie du sous VI &#8220;Analog Read Pin&#8221; donne une tension et pas un nombre compris entre 0 et 1023 !</p>
<h1>Troisième exemple : Moteur CC commandé en sens et en vitesse</h1>
<p>Nous allons utiliser un circuit intégré qui permet de piloter deux moteurs CC : le L293D (datasheet <a href="http://www.ti.com/lit/ds/symlink/l293d.pdf" target="_blank">ici</a>). Ce circuit est relativement facile à mettre en œuvre et comme nous allons piloter qu&#8217;un seul moteur cela simplifie encore l&#8217;ensemble. Notez qu&#8217;il existe des shields pour piloter des moteurs CC (par ex : <a href="http://www.lextronic.fr/P5073-platine-de-commande-de-moteurs-dc.html" target="_blank">http://www.lextronic.fr/P5073-platine-de-commande-de-moteurs-dc.html</a>). La broche 1 (EN1) permet d&#8217;activer le premier pont en H, si l&#8217;on connecte cette broche à une broche de l&#8217;arduino qui fourni un signal MLI alors on pourra faire varier la vitesse du moteur. Les broches 2 (IN1) et 7 (IN2) permettent de fixer le sens de rotation du moteur ou encore de le freiner. Les broches 3 (OUT1) et 6 (OUT2) sont les broches de sorties de puissance vers le moteur. La broche 16 (VSS) reçoit une alimentation 5V issu de la carte arduino. La broche 8 (VS) est connecté au +9V d&#8217;une pile pour assurer l&#8217;alimentation en puissance du moteur. Enfin les broches 4,5,12, 13 sont reliées aux masses (GND de l&#8217;arduino et pôle négatif de la pile). On obtient donc le schéma de câblage suivant :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur.png" rel="lightbox[891]"><img class="aligncenter size-thumbnail wp-image-931" title="Exemple 3 - Pilotage n MLI d'un moteur CC" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur-150x150.png" alt="Exemple 3 - Pilotage n MLI d'un moteur CC" width="150" height="150" /></a>Les broches 7 et 8 de l&#8217;arduino devront donc être en mode &#8220;digital&#8221; pour piloter le sens du moteur, la broche 11 en mode MLI (remarque: seul les broches avec une tilde peuvent être mises en mode MLI matériel : 6 broches en tout sur une arduino UNO). Le sens de rotation du moteur suit le tableau suivant:</p>
<p align="center">
<table style="text-align: center;" border="1" cellspacing="0" cellpadding="4">
<tbody>
<tr valign="top">
<td width="25%"><span style="color: black;"><strong>Enable 1 (EN1)<br />
</strong></span></td>
<td width="25%"><span style="color: black;"><strong>Input 1 (IN1)<br />
</strong></span></td>
<td width="25%"><span style="color: black;"><strong>Input 2 (IN 2)<br />
</strong></span></td>
<td width="25%"><span style="color: black;"><strong>Fonction</strong></span></td>
</tr>
<tr valign="top">
<td width="25%" bgcolor="#e6e6ff">High</td>
<td width="25%" bgcolor="#e6e6ff">Low</td>
<td width="25%" bgcolor="#e6e6ff">High</td>
<td width="25%" bgcolor="#e6e6ff">Tourne dans le sens horaire<strong></strong></td>
</tr>
<tr valign="top">
<td width="25%">High</td>
<td width="25%">High</td>
<td width="25%">Low</td>
<td width="25%">tourne dans le sens trigonométrique<strong></strong></td>
</tr>
<tr valign="top">
<td width="25%" bgcolor="#e6e6ff">High</td>
<td width="25%" bgcolor="#e6e6ff">Low</td>
<td width="25%" bgcolor="#e6e6ff">Low</td>
<td width="25%" bgcolor="#e6e6ff">Stop</td>
</tr>
<tr valign="top">
<td width="25%">High</td>
<td width="25%">High</td>
<td width="25%">High</td>
<td width="25%">Stop</td>
</tr>
<tr valign="top">
<td width="25%" bgcolor="#e6e6ff">Low</td>
<td width="25%" bgcolor="#e6e6ff">Non applicable</td>
<td width="25%" bgcolor="#e6e6ff">Non applicable</td>
<td width="25%" bgcolor="#e6e6ff">Stop</td>
</tr>
</tbody>
</table>
<p>La face avant de cette exemple sera très simple (un potentiomètre unique qui évolue de -100% à +100%, le signe permet de fixer le sens de rotation) :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur-face-avant-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-935" title="Exemple 3 - Commande Moteur CC - Face avant LabVIEW" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur-face-avant-labview.png" alt="Exemple 3 - Commande Moteur CC - Face avant LabVIEW" width="413" height="311" /></a>Le programme LabVIEW peut se présenter de la manière suivante (la seule partie qui varie d&#8217;une capture à l&#8217;autre, c&#8217;est l&#8217;intérieur de la boite de test : Vrai et Faux :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur-diagramme-labview-cas-vrai.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-936" title="Exemple 3 - Commande moteur CC - Diagramme LabVIEW - Cas vrai" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur-diagramme-labview-cas-vrai.png" alt="Exemple 3 - Commande moteur CC - Diagramme LabVIEW - Cas vrai" width="937" height="285" /></a><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur-diagramme-labview-cas-faux.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-938" title="Exemple 3 - Commande moteur CC - Diagramme LabVIEW - Cas faux" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple3-moteur-diagramme-labview-cas-faux.png" alt="Exemple 3 - Commande moteur CC - Diagramme LabVIEW - Cas faux" width="936" height="290" /></a>Câblez et testez : le moteur doit varier en vitesse et en sens. A l&#8217;oscilloscope la fréquence de la MLI est de 400Hz. Cette fréquence n&#8217;est pas réglable par l&#8217;intermédiaire d&#8217;un VI.</p>
<h1>Quatrième exemple : Capteur de température DS1621 sur bus I2C</h1>
<p>Le DS1621 est un capteur de température relativement répandu (datasheet <a href="http://datasheets.maxim-ic.com/en/ds/DS1621.pdf" target="_blank">ici</a>). Je ne vais pas détailler ici la documentation, on va juste préciser les commandes à envoyer au DS1621 pour l&#8217;initialiser et faire une lecture simple de température. La broche 1 est SDA, la 2 est SCL : signaux du bus I2C. La broche 3 (Tout) ne sera pas utilisée dans notre application. Les broches 7 (A0), 6 (A1) et 5 (A0) sont reliés à la masse pour fixer l&#8217;adresse I2C de ce capteur. La broche 4 est la masse et la broche 8 +Vcc (ici 5V).</p>
<p>La séquence d&#8217;initialisation est la suivante (broches A0, A1 et A2 reliées à la masse) :</p>
<ol>
<li>Condition de départ (start)</li>
<li>Écrire 0&#215;90 : on sélectionne le boitier à l&#8217;adresse A2A1A0 = 000 en écriture</li>
<li>Écrire 0xAC : on écrit dans le registre de configuration</li>
<li>Écrire 0&#215;00 : conversion de température en continu</li>
<li>Condition d&#8217;arrêt (stop)</li>
<li>Attendre 20ms : écriture en eeprom de la configuration précédente</li>
<li>Condition de départ (start)</li>
<li>Écrire 0&#215;90 : on sélectionne le boitier à l&#8217;adresse A2A1A0 = 000 en écriture</li>
<li>Écrire 0xEE : lancement de la conversion en continu de la température</li>
<li>Condition d&#8217;arrêt (stop)</li>
</ol>
<p>La séquence suivante permet la lecture de la température :</p>
<ol>
<li>Condition de départ (start)</li>
<li>Ecrire 0&#215;90 : on sélectionne le boitier à l&#8217;adresse A2A1A0 = 000 en écriture</li>
<li>Ecrire 0xAA : demande de lecture de la dernière température échantillonnée</li>
<li>Condition de départ (restart)</li>
<li>Ecrire 0&#215;91 : on sélectionne le boitier à l&#8217;adresse A2A1A0 = 000 en<strong> lecture</strong></li>
<li>Lire les 8 bits de poids fort de la température</li>
<li>Lire les 8 bits de poids faible de la température et faire un NACK !!</li>
<li>Condition d&#8217;arrêt (stop)</li>
</ol>
<p>Vous remarquez que ce n&#8217;est pas très simple mais on va essayer d&#8217;implémenter le tout en LabVIEW avec les fonctions Arduino. Suivant la version de la carte arduino UNO que vous possédez les broches SCL et SDA ne sont pas au même endroit (UNO Rev2 : A4=SDA, A5=SCL; UNO Rev3: deux broches dédiées sur un connecteur SCL et SDA). Au moment de rédiger ce tutoriel  je dispose d&#8217;une carte arduino UNO rev2, le schéma de câblage ci-dessous est donc adapté pour cette plate-forme :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple4-temp-i2c.png" rel="lightbox[891]"><img class="aligncenter size-thumbnail wp-image-946" title="Exemple 4 - Capteur de température DS1621 sur bus i2c" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple4-temp-i2c-150x150.png" alt="Exemple 4 - Capteur de température DS1621 sur bus i2c" width="150" height="150" /></a>La face avant sous LabVIEW se présente de la manière suivante :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple4-temp-i2c-face-avant-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-949" title="Exemple 4 - Capteur de température DS1621 sur bus I2C - Face avant LabVIEW" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple4-temp-i2c-face-avant-labview.png" alt="Exemple 4 - Capteur de température DS1621 sur bus I2C - Face avant LabVIEW" width="249" height="301" /></a><em>Remarque</em> : un indicateur permet de choisir l&#8217;adresse du capteur DS1621 sur le bus I2C. Sous l&#8217;intitulé &#8220;Données I2C&#8221; c&#8217;est en fait un indicateur sous forme de tableau, il permet de visualiser les données brutes lues sur le bus I2C.</p>
<p>Le diagramme peut se présenter de la manière suivante :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple4-temp-i2c-diagramme-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-950" title="Exemple 4 - Capteur de température DS1621 sur bus I2C - Diagramme LabVIEW" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple4-temp-i2c-diagramme-labview.png" alt="Exemple 4 - Capteur de température DS1621 sur bus I2C - Diagramme LabVIEW" width="931" height="288" /></a>Cela mérite quelques explications !!! Tout d&#8217;abord j&#8217;ai triché&#8230;pour comprendre comment fonctionne les sous VI I2C j&#8217;ai regardé les signaux I2C issu de l&#8217;arduino sur un oscilloscope et je dois dire que ça m&#8217;a bien aidé ! Lecture du diagramme de gauche à droite:</p>
<ol>
<li>Initialisation du bus I2C (TWI dans la terminologie arduino)</li>
<li>Initialisation du DS1621. Tout d&#8217;abord l&#8217;adresse du composant. L&#8217;adresse est sur 7 bits (bit de poids fort en premier), les 4 premiers sont fixes (1001 voir documentation), les 3 derniers sont fixés avec les broches A2A1A0. Dans notre cas A2A1A0=000 donc l&#8217;adresse du composant est 0b1001000 en binaire ou 0&#215;48 en hexadécimal ou 72 en décimal. Vous avez donc l&#8217;explication de la valeur 72 sur la face avant. Ensuite il faut écrire les valeurs 0xAC (172) et 0&#215;00 (0) : c&#8217;est le rôle du premier sous VI  &#8220;I2C Write&#8221;.</li>
<li>Suite de l&#8217;initialisation. Normalement il faut attendre une dizaine de ms mais comme la transmission des 15 octets de LabVIEW vers l&#8217;arduino prend du temps, on peut considérer que la temporisation est réalisée. On écrit alors la valeur 0xEE (238). A ce point le DS1621 est correctement initialisé.</li>
<li>On rentre alors dans une boucle infinie. La température sera demandée toutes les 500ms. Pour faire la demande de la dernière température, il faut écrire la valeur 0xAA (170).</li>
<li>On lit alors le résultat : ici le DS1621 doit nous renvoyer 2 octets d’où la valeur 2 sur le sous VI &#8220;I2C Read&#8221;. Ce sous VI se charge aussi de faire le NACK final (vérifié à l&#8217;oscilloscope). On obtient alors un tableau 1D à deux cases contenant des entiers non signés codés sur 8 bits. Ces données sont affichées de manière brute dans un l&#8217;indicateur de la face avant &#8220;Données I2C&#8221;.</li>
<li>Il faut traiter les deux valeurs fourni par le DS1621. On commence par extraire les données du tableau avec le sous VI &#8220;Indexer un tableau&#8221;. L&#8217;indice  &#8216;0&#8242; : 8 bit de poids fort du résultat de la température en entier signé et l&#8217;indice &#8216;1&#8242; : 8 bit de poids faible de la conversion : dans notre cas cet octet prendra deux valeurs : soit 128 pour indiquer qu&#8217;il faut rajouter 0,5°C, soit 0.</li>
<li>On reconstruit alors la température réelle et on l&#8217;affiche sur le thermomètre.</li>
</ol>
<p>Cela fonctionne, notez cependant que l&#8217;on ne gère pas les températures négatives&#8230;c&#8217;est à faire en guise d&#8217;exercice <img src='http://innovelectronique.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h1>Cinquième exemple : Afficheur LCD alphanumérique</h1>
<p>Pour ce test il existe un shield (par exemple <a href="http://www.zartronic.fr/shield-lcd-pour-arduino-p-125.html" target="_blank">http://www.zartronic.fr/shield-lcd-pour-arduino-p-125.html</a>) ou on peut le fabriquer à partir des fichiers Isis et Ares disponible sur <a href="http://www.ac-limoges.fr/sti_ge/spip.php?article38" target="_blank">http://www.ac-limoges.fr/sti_ge/spip.php?article38</a>. L&#8217;afficheur LCD sera utilisé en mode 4 bits et la ligne RW sera reliée à la masse pour diminuer le nombre de fils. On peut avoir le câblage suivant qui n&#8217;est <strong>PAS DU TOUT</strong> le câblage par défaut proposé sous LabVIEW :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple5-aff-lcd1.png" rel="lightbox[891]"><img class="aligncenter size-thumbnail wp-image-958" title="Exemple 5 - Afficheur LCD Alphanumerique" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple5-aff-lcd1-150x150.png" alt="Exemple 5 - Afficheur LCD Alphanumerique" width="150" height="150" /></a></p>
<p>Pour être plus explicite on a le câblage suivant (j&#8217;exclue les alimentations et le réglage de contraste avec le potentiomètre).</p>
<ul>
<li>broche 4 de l&#8217;arduino vers broche 4 (RS) de l&#8217;afficheur</li>
<li>broche 5 (RW) de l&#8217;afficheur reliée à la masse : l&#8217;afficheur est toujours en mode écriture</li>
<li>broche 6 de l&#8217;arduino vers broche 6 (E) de l&#8217;afficheur</li>
<li>broches 10,11,12,13 de l&#8217;arduino respectivement sur 11,12,13,14 (DB4,DB5,DB6,DB7) les 4 bits de poids fort du bus de données de l&#8217;afficheur</li>
</ul>
<p><em>Remarque</em> : suivant votre afficheur, vous pouvez tenter de mettre la broche 3 (Vcontrast) directement à la masse. Si les caractères sont encore visibles cela simplifie encore le câblage.</p>
<p>On va afficher la date et l&#8217;heure courante du PC sur l&#8217;afficheur LCD. On vérifiera que la longueur de la chaine à afficher est compatible avec le nombre de colonne de l&#8217;afficheur sinon on affichera le mot &#8220;Erreur !!&#8221; et on positionnera un témoin lumineux à rouge. La face avant peut être celle-ci :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple5-aff-lcd-face-avant-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-959" title="Exemple 5 - Afficheur LCD alphanumerique - Face avant LabVIEW" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple5-aff-lcd-face-avant-labview.png" alt="Exemple 5 - Afficheur LCD alphanumerique - Face avant LabVIEW" width="273" height="158" /></a>Compte tenu du cahier des charges précédent, on peut obtenir le diagramme LabVIEW suivant :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple5-aff-lcd-diagramme-labview.png" rel="lightbox[891]"><img class="aligncenter size-full wp-image-961" title="Exemple 5 - Afficheur LCD alphanumerique - Diagramme LabVIEW" src="http://innovelectronique.fr/wp-content/uploads/2012/05/exemple5-aff-lcd-diagramme-labview.png" alt="Exemple 5 - Afficheur LCD alphanumerique - Diagramme LabVIEW" width="966" height="367" /></a></p>
<p>Quelques commentaires sur ce diagramme:</p>
<ul>
<li>le sous VI &#8220;LCD configure 4-bit&#8221; permet d&#8217;affecter les broches de l&#8217;afficheur LCD aux broches de l&#8217;arduino. Le nom des broches est rappelé sur le diagramme. La valeur 255 pour la ligne R/W indique que cette ligne n&#8217;est pas cablé du coté de l&#8217;arduino. La broche &#8220;LCD&#8221; précise quel ligne sur l&#8217;arduino sera utilisée pour piloter le rétroéclairage de l&#8217;afficheur s&#8217;il en possède un. Ne connectez pas directement la broche de l&#8217;arduino à la broche d&#8217;alimentation du rétro-éclairage (vu sur les exemples de chez NI) mais utilisez plutôt un petit transistor MOS type BS170 (datasheet <a href="http://www.fairchildsemi.com/ds/BS/BS170.pdf" target="_blank">ici</a>) pour piloter l&#8217;alimentation du rétro-éclairage.</li>
<li>Le sous VI &#8220;LCD Init&#8221; permet de préciser le nombre de colonnes (ici 16) et le nombre de ligne (ici 2) de l&#8217;afficheur LCD.</li>
<li>Tout ce qui est dans la partie supérieure de la boucle while concerne la récupération de la date et de l&#8217;heure du PC (avec un format précis) et du test pour savoir si la longueur de la chaine générée est compatible avec le nombre de colonnes de l&#8217;afficheur</li>
<li>Le sous VI &#8220;LCD Set Cursor Position&#8221; permet de fixer la position de départ de la chaine à afficher. Notez bien que les coordonnées x,y de l&#8217;afficheur commence à 0,0 et pas 1,1 !</li>
<li>Le sous VI &#8220;LCD print&#8221; permet d&#8217;afficher la chaine que l&#8217;on a généré auparavant</li>
</ul>
<p><em>Remarque</em> : le VI précédent a été testé sur un afficheur LCD 16&#215;2 et un afficheur LCD 20&#215;4 en changeant les paramètres d&#8217;initialisation et la position d&#8217;affichage. Tout a bien fonctionné <img src='http://innovelectronique.fr/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<h1>Conclusion&#8230;</h1>
<p>Pour explorer plus avant les possibilités de LIFA, il suffit d&#8217;ouvrir les VI exemples fournis. Ceux-ci se trouvent dans &#8220;C:\Program Files\National Instruments\LabVIEW 2011\vi.lib\LabVIEW Interface for Arduino\Palette Examples&#8221;. J&#8217;espère aussi que les quelques exemples précédents vous ont ouvert l&#8217;appétit ! Je trouve le &#8220;mariage&#8221; open-source, open-harware de l&#8217;arduino et le très propriétaire NI LabVIEW assez intéressant car il permet de développer rapidement de petites applications ou projets. De ce point de vue LIFA correspond bien à une philosophie d&#8217;apprentissage par projet !</p>
<p>Je compte, si j&#8217;ai assez de temps faire un second article, sur une utilisation plus avancé de LIFA. Un des thèmes abordés pourrait être la manette nunchuck de la wii car elle embarque un accéléromètre 3 axes, un joystick analogique et deux boutons poussoirs, le tout interrogeable par un bus I2C pour un prix de 20€&#8230;</p>
<p>Vous trouverez ci-dessous une archive zip contenant les captures d&#8217;écrans, les fichiers pour fritzing, les VI des exemples (réalisés avec la version 2011 de LabVIEW). N&#8217;hésitez pas à commenter cet article et à apporter votre pierre à l&#8217;édifice de l&#8217;open source - open hardware.</p>
<div class="attachments"><dl class="attachments attachments-large"><dt class="icon"><a title="Exemples LIFA" href="?aid=968&pid=891&sa=0"><img src="http://innovelectronique.fr/wp-content/plugins/eg-attachments/images/zip.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="Exemples LIFA" href="?aid=968&pid=891&sa=0">Exemples LIFA</a><br /><strong>L&eacute;gende: </strong>VI, fichiers Fritzing, captures d'écran pour LIFA<br /><strong>Fichier: </strong>exemples-lifa.zip<br /><strong>Taille: </strong>1 Mo</dd></dl></div>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2012/05/04/arduino-et-lifa-labview-interface-for-arduino/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Installation et utilisation de QTExtSerialPort sous Debian/GNU Linux 6.0</title>
		<link>http://innovelectronique.fr/2012/03/13/installation-et-utilisation-de-qtextserialport-sous-debiangnu-linux-60/</link>
		<comments>http://innovelectronique.fr/2012/03/13/installation-et-utilisation-de-qtextserialport-sous-debiangnu-linux-60/#comments</comments>
		<pubDate>Tue, 13 Mar 2012 08:04:19 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[GNU/Linux]]></category>

		<category><![CDATA[Linux Embarqué]]></category>

		<category><![CDATA[port série]]></category>

		<category><![CDATA[QT]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=828</guid>
		<description><![CDATA[Pour un projet industriel, les étudiants doivent utiliser QT4 et dialoguer avec différents appareils par le port série. QT4 ne délivrant pas nativement de classe gérant le port série, il faut se tourner vers des développements extérieurs. Pour l&#8217;instant j&#8217;en connais deux:

QTExtSerialPort : http://code.google.com/p/qextserialport/
QTSerialDevice : http://gitorious.org/qserialdevice

Mon environnement de développement sera une debian Squeeze. QTCreator est [...]]]></description>
			<content:encoded><![CDATA[<p>Pour un projet industriel, les étudiants doivent utiliser QT4 et dialoguer avec différents appareils par le port série. QT4 ne délivrant pas nativement de classe gérant le port série, il faut se tourner vers des développements extérieurs. Pour l&#8217;instant j&#8217;en connais deux:</p>
<ul>
<li>QTExtSerialPort : <a href="http://code.google.com/p/qextserialport/" target="_blank">http://code.google.com/p/qextserialport/</a></li>
<li>QTSerialDevice : <a href="http://gitorious.org/qserialdevice" target="_blank">http://gitorious.org/qserialdevice</a></li>
</ul>
<p>Mon environnement de développement sera une debian Squeeze. QTCreator est installé depuis les paquets standards (en version 1.3.1 basé sur les librairies QT 4.6.3).<span id="more-828"></span></p>
<h1>Test avec QExtSerialPort</h1>
<p>Il faut se rendre àl&#8217;adresse indiquée plus haut. On va faire une copie du projet en utilisant Mercurial. Il faut d&#8217;abord installer celui-ci puis se déplacer dans un endroit adéquate puis enfin rapatrier le projet:</p>
<pre>olivier@portable-od:~$ sudo aptitude install mercurial
olivier@portable-od:~$ cd Documents/BTS_IRIS/LangageC-C++/Qt
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt$ hg clone https://code.google.com/p/qextserialport/
destination directory: qextserialport
requesting all changes
adding changesets
adding manifests
adding file changes
added 106 changesets with 726 changes to 124 files (+2 heads)
updating to branch default
95 files updated, 0 files merged, 0 files removed, 0 files unresolved
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt$ ls
basiclayouts   imageviewer         qextserialport
collidingmice  localfortuneclient  Test_crosscompilateur</pre>
<p>On rentre dans le répertoire &#8220;qextserialport&#8221;. On remarque un &#8220;qextserialport.pro&#8221; (un projet Qt4). On va donc essayer de compiler ce projet avec une simple commande &#8220;make&#8221;. En analysant les messages de compilation, on remarque que l&#8217;on a obtenu:</p>
<ul>
<li>une librairie partagée :  libqextserialport.so.1.2.0 dans le répertoire &#8220;src/build&#8221; et les liens symboliques</li>
<li>des exemples : enumerator,  event (le projet QEPSTA nécessite une compilation dans QTCreator)</li>
</ul>
<p>On teste donc les exemples fournis&#8230;le problème est que la librairie partagée n&#8217;est pas reconnue. Je copie donc celle-ci dans &#8220;/lib&#8221; et je fais les liens symboliques associés. Enfin on remet à jour la liste des librairies avec ldconfig:</p>
<pre>olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport$ cd src/build/
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/src/build$ ls
libqextserialport.so  libqextserialport.so.1  libqextserialport.so.1.2  libqextserialport.so.1.2.0
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/src/build$ sudo cp libqextserialport.so.1.2.0 /lib
[sudo] password for olivier:
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/src/build$ cd /lib
olivier@portable-od:/lib$ sudo ln -s libqextserialport.so.1.2.0 libqextserialport.so.1.2
olivier@portable-od:/lib$ sudo ln -s libqextserialport.so.1.2.0 libqextserialport.so.1
olivier@portable-od:/lib$ sudo ln -s libqextserialport.so.1.2.0 libqextserialport.so
olivier@portable-od:/lib$ sudo ldconfig
olivier@portable-od:/lib$ cd /home/olivier/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/enumerator/
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/enumerator$</pre>
<ul>
<li>enumerator : on lance l&#8217;éxecution du programme &#8220;enumerator&#8221; et l&#8217;on obtient la liste des &#8220;ports séries&#8221; disponible sur la machine.</li>
</ul>
<pre>olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/enumerator$ ./enumerator
List of ports:
port name: "ttyS0"
friendly name: "Serial port 0"
physical name: "/dev/ttyS0"
enumerator name: "/dev"
vendor ID: "ffffffffa3e49cf8"
product ID: "7fff"
===================================
port name: "ttyS1"
friendly name: "Serial port 1"
physical name: "/dev/ttyS1"
enumerator name: "/dev"
vendor ID: "ffffffffa3e49cf8"
product ID: "7fff"
===================================
port name: "ttyS2"
friendly name: "Serial port 2"
physical name: "/dev/ttyS2"
enumerator name: "/dev"
vendor ID: "ffffffffa3e49cf8"
product ID: "7fff"
===================================
port name: "ttyS3"
friendly name: "Serial port 3"
physical name: "/dev/ttyS3"
enumerator name: "/dev"
vendor ID: "ffffffffa3e49cf8"
product ID: "7fff"
===================================
port name: "ttyUSB0"
friendly name: "USB-serial adapter 0"
physical name: "/dev/ttyUSB0"
enumerator name: "/dev"
vendor ID: "ffffffffa3e49cf8"
product ID: "7fff"
===================================</pre>
<p>En fait le seul port série que j&#8217;ai sur ma machine est le &#8220;/dev/ttyUSB0&#8243; : c&#8217;est un adaptateur USB-Serie basé sur le circuit FT232 de FTDI.</p>
<ul>
<li>event : si on exécute ce programme, le message d&#8217;erreur suivant apparaît :</li>
</ul>
<pre>olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/event$ ./event
hi there
trying to open file "COM1"
could not open file: Aucun fichier ou dossier de ce type
device failed to open: "The COM1 file doesn't exists"
^C</pre>
<p>Visiblement le nom du port est codé &#8220;en dur&#8221;. Donc on modifie le fichier source (remplacement de COM0 par /dev/ttyUSB0) et on recompile (make dans le répertoire) puis on exécute :</p>
<pre>olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/event$ nano main.cpp
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/event$ ls
event  event.pro  main.cpp  Makefile  PortListener.cpp  PortListener.h  tmp
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/event$ make
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I../../src -Itmp -o tmp/main.o main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:15: warning: unused variable ‘listener’
g++ -Wl,-O1 -o event tmp/main.o tmp/PortListener.o tmp/moc_PortListener.o    -L../../src/build -L/usr/lib -lqextserialport -lQtGui -lQtCore -lpthread
olivier@portable-od:~/Documents/BTS_IRIS/LangageC-C++/Qt/qextserialport/examples/event$ ./event
hi there
trying to open file "/dev/ttyUSB0"
file opened succesfully
warning: device is not turned on
listening for data on "/dev/ttyUSB0"
bytes read: 2
bytes: "f "
bytes read: 2
bytes: "f "
bytes read: 2
bytes: "x "</pre>
<p>Visiblement le programme fonctionne et reçoit les données de la voie série. Nous avons donc deux codes sources à examiner.</p>
<p>J&#8217;ouvre enfin le programme QEPSTA dans QTCreator (ouvrir le projet QEPSTA.pro) et je lance la compilation et l&#8217;exécution. A la compilation une erreur apparaît, je modifie la ligne d&#8217;include concernée en #include &#8220;../../src/qextserialport.h&#8221;. Je relance la compilation est j&#8217;obtiens deux erreurs sur fprintf et stderr. Je choisis la solution radicale de commenter les lignes concernées. Il y a d&#8217;autres erreurs du mêmes types. Cependant à la fin le programme ne pouvait être lié avec la bibliothèque qextserialportd (voir le fichier qespta.pro, d pour debug). J&#8217;ai donc changé en qextserialport et c&#8217;est OK. Le programme graphique s&#8217;exécute.</p>
<p>J&#8217;ai depuis développé une petite application de test basé sur trois &#8220;scrool bar&#8221; R,G,B pour commander le microcontrolleur. Le tout est fonctionnel. Le code sera mis plus tard avec les classes associées.</p>
<p>Comme nous avons des doutes sur la compilation de cette librairie sous la dernière version de QT (4.8 à l&#8217;instant d&#8217;écriture de ces lignes) j&#8217;installe dans une machine virtuelle VirtualBox une ubuntu 11.10. QTCreator sera alors installé ensuite pour voir quel version est utilisé dans cette environnement. Suivant la version, j&#8217;installerai le dernier SDK directement depuis le site de QT.</p>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2012/03/13/installation-et-utilisation-de-qtextserialport-sous-debiangnu-linux-60/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Carte E/S sur relais 230V pilotable par le protocole MODBUS</title>
		<link>http://innovelectronique.fr/2012/02/27/carte-es-sur-relais-230v-pilotable-par-le-protocole-modbus/</link>
		<comments>http://innovelectronique.fr/2012/02/27/carte-es-sur-relais-230v-pilotable-par-le-protocole-modbus/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 21:34:58 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[µC PIC]]></category>

		<category><![CDATA[ModBUS]]></category>

		<category><![CDATA[PIC18F]]></category>

		<category><![CDATA[RS485]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=842</guid>
		<description><![CDATA[Dans le cadre d&#8217;un projet industriel, les étudiant doivent piloter en tout ou rien sous 230V un signal lumineux (ampoule), un signal sonore (sirène), un moteur pour l&#8217;aspiration de fumées, un régulateur de vitesse pour un convoyeur (altivar) et des régulateurs PID (eurotherm), le tout sur bus physique RS485 avec le protocole ModBUS.  Malheureusement l&#8217;altivar [...]]]></description>
			<content:encoded><![CDATA[<p>Dans le cadre d&#8217;un projet industriel, les étudiant doivent piloter en tout ou rien sous 230V un signal lumineux (ampoule), un signal sonore (sirène), un moteur pour l&#8217;aspiration de fumées, un régulateur de vitesse pour un convoyeur (altivar) et des régulateurs PID (eurotherm), le tout sur bus physique RS485 avec le protocole ModBUS.  Malheureusement l&#8217;altivar n&#8217;est plus produit et la carte de commande sur bus RS485 n&#8217;est donc plus produite non plus. L&#8217;entrepreneur ne souhaite pas changer son altivar. Il reste donc l&#8217;entrée 0-10V pour donner la consigne de vitesse. Il faut donc générer une tension continue variable et pilotable par bus RS485 et compatible ModBUS. Plutôt que de faire un assemblage de &#8220;différents morceaux&#8221;, j&#8217;ai réalisé une carte électronique qui suit ce cahier des charges.<span id="more-842"></span></p>
<h1>Réalisation de la carte électronique</h1>
<p>Cette carte électronique doit donc répondre au cahier des charges suivant:</p>
<ul>
<li>piloter en tout ou rien trois sorties 230V (voyant lumineux, alarme sonore, aspirateur à fumées)</li>
<li>générer une tension continue variable comprise entre 0V et 10V pour la consigne de vitesse de l&#8217;altivar</li>
<li>être compatible avec les régulateurs de températures qui fonctionnent sur bus RS485 avec le protocole ModBUS en mode RTU</li>
<li>permettre de piloter la consigne de l&#8217;altivar de manière manuel (avec un potentiomètre multitours) ou automatique (par la tension générer sur la carte)</li>
<li>fonctionner à partir d&#8217;une tension unique régulée de 5V</li>
</ul>
<p>Ce qui m&#8217;a conduit à adopter les solutions suivantes pour un prototype en fonction de ce que j&#8217;avais comme composants disponibles :</p>
<ul>
<li>la réception de la trame ModBUS, son décodage et enfin le pilotage de l&#8217;ensemble sera réalisé par un microcontrolleur Microchip PIC18F2520</li>
<li>pour piloter en tout ou rien du 230V, j&#8217;ai utilisé des relais classiques 12V/230V 1A</li>
<li>le bus RS485 deux fils sera piloté avec un CI du type DS75176</li>
<li>le 12V de commande des relais sera réalisé à partir du 5V à l&#8217;aide un convertisseur de type &#8220;boost&#8221; piloté par le PIC</li>
<li>la consigne 0-10V sera réalisé par filtrage d&#8217;un signal MLI généré par le PIC puis amplifié (x2) par un montage à amplificateur opérationnel. Cet amplificateur utilisant le 12V comme tension d&#8217;alimentation</li>
<li>l&#8217;aiguillage de la tension continue générée par le PIC (mode automatique) ou celle issu du potentiomètre (mode manuel) sera réalisé par un relai</li>
</ul>
<p>Ce qui nous mène au schéma électrique suivant (le fichier original au format Proteus Isis 7.4 est disponible en fin d&#8217;article) :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/02/cartees_modbus.png" rel="lightbox[842]"><img class="aligncenter size-medium wp-image-853" title="Carte ES ModBUS" src="http://innovelectronique.fr/wp-content/uploads/2012/02/cartees_modbus-300x200.png" alt="Carte ES ModBUS" width="300" height="200" /></a></p>
<p>Quelques explications sur ce schéma :</p>
<ul>
<li>la carte est alimentée par une alimentation extérieure industrielle régulée 5V. La diode D1 protège le montage contre les inversions de polarité. Cependant elle introduit un problème : en effet la chute de tension dans cette diode est proportionnelle au courant qui la traverse. Lorsque les relais sont alimentés, le &#8220;5V&#8221; varie ! Or le CAN du PIC utilise comme référence cette tension de 5V ainsi que la génération du signal 0-10V. Je pense donc qu&#8217;à terme il faudra soit supprimer cette diode, soit alimenter la carte en 24V continu et générer les tensions continues de 5V et 12V (ce qui supprimera le convertisseur boost). C3 et C4 sont des condensateurs de filtrage.</li>
<li>la conversion du signal RS485 en signal RS232 TTL est assuré par un ci du type SN75176. Comme on utilise un bus RS485 sur 2 fils, cela sous entend que l&#8217;on fonctionne en mode half-duplex. Il faut donc gérer ce mode en pilotant les lignes DE et RE. En mode réception, il faut mettre un état bas sur les lignes 2 et 3. En mode émission il faut mettre un état haut. Cette gestion est assurée de manière automatique dans le code C du PIC. R6 et R7 protège les entrées du SN75176. R8 et J2 permettent de &#8220;fermer&#8221; le bus RS485 sur une impédance de 120 Ohms pour éviter les réflexions en bout de ligne. R9 et J3 permettent de réaliser un &#8220;pull-up&#8221; de la ligne A du bus RS485. R10 et J4 assurent le &#8220;pull-down&#8221; de la ligne B du bus RS485.</li>
<li>Les composants autour des relais RL1, RL2 et RL3 permettent de piloter en tout ou rien ces relais. Les DELs permettent de visualiser que les relais sont en position &#8220;travail&#8221;. En effet si la carte ne fonctionne pas ou en absence d&#8217;alimentation les relais sont sur leur position repos (donc pas de voyant lumineux allumé, pas de sirène mais pas d&#8217;aspirateur à fumées non plus). Comme les contacts &#8220;travail&#8221; et &#8220;repos&#8221; sont sortis sur des borniers, c&#8217;est l&#8217;utilisateur qui choisira sa configuration.</li>
<li>le convertisseur &#8220;boost&#8221; est réalisé autour des composants Q5, D7, BOB et C1. Le transistor mosfet utilisé ici est surdimensionné mais c&#8217;est celui que j&#8217;avais de disponible. Attention à prendre une diode rapide pour D7 (et pas une 1N4007 comme indiqué sur le schéma). R22 protège la grille du transistor et R23 bloque le transistor en l’absence de commande. Le pont diviseur R20/R21 permet de renvoyer vers le PIC une image de la tension de sortie. Le système fonctionne alors en boucle fermée et l&#8217;asservissement est réalisé par le PIC. En effet, en gros, il faut piloter le rapport cyclique du signal MLI PWM_12V pour obtenir un 12V continu quelque soit le courant demandé par les relais. Cette partie disparaitra si je choisi d&#8217;alimenter la carte en 24V. Cette partie était surtout là pour me faire plaisir et tester un montage que je n&#8217;avais pas encore utilisé <img src='http://innovelectronique.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> mais du coup comme le système est pleinement fonctionnel je l&#8217;utiliserais dans d&#8217;autres montages.</li>
<li>l&#8217;amplificateur U3 sera du type &#8220;rail to rail&#8221; (pas de tensions de déchets) pour gérer les tensions basses en particulier. Les tensions hautes prés du 10V posant moins de problèmes car l&#8217;amplificateur est alimenté en 12V. R14 et C6 filtrent le signal MLI issu du PIC pour obtenir une tension continue comprise entre 0V et 5V. U3, monté en amplificateur non inverseur, multiplie cette tension par deux (gain fixé par R11, R12) pour obtenir la gamme 0-10V. D5 protège l&#8217;entrée de l&#8217;altivar contre les tensions supérieures à 10V. R13 et C7 filtrent l&#8217;alimentation de U3.</li>
<li>le relais RL4 permet de commuter entre la tension fournie par un potentiomètre extérieur (P1) et la tension issu de U3 pour réaliser la tension de consigne de l&#8217;altivar. Ce relai assure donc la commutation entre le mode automatique et le mode manuel.</li>
<li>enfin le microcontroleur U1 assure la gestion de l&#8217;ensemble. J1 est le connecteur de programmation. J7 permet de choisir la vitesse du bus rs485 (9600 ou 19200). J5 et J6 permettent de choisir l&#8217;adresse de la carte sur le bus RS485 (adresse 16, 32, 64 ou 128). Un tableau récapitulatif de ces cavaliers sera présenté plus loin dans cet article.</li>
</ul>
<p>On passe à la phase de routage sur une carte au format &#8220;europe&#8221;, on câble et on obtient la carte suivante:</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/02/cartees_modbus_typon.png" rel="lightbox[842]"><img class="aligncenter size-medium wp-image-855" title="CarteES ModBUS Typon" src="http://innovelectronique.fr/wp-content/uploads/2012/02/cartees_modbus_typon-300x187.png" alt="CarteES ModBUS Typon" width="300" height="187" /></a></p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/02/cartees_implantation.png" rel="lightbox[842]"><img class="aligncenter size-full wp-image-858" title="Carte ES : découpe fonctionnel" src="http://innovelectronique.fr/wp-content/uploads/2012/02/cartees_implantation.png" alt="Carte ES : découpe fonctionnel" width="414" height="287" /></a></p>
<h1>Étude du protocole ModBUS sur liaison physique RS485 en mode RTU</h1>
<p>Le protocole ModBUS est décrit sur différents sites : <a href="http://fr.wikipedia.org/wiki/Modbus" target="_blank">wikipédia</a>, <a href="sitelec.org/cours/abati/modbus.htm" target="_blank">stielec</a><br />
La liaison physique RS485 est décrite sur : <a href="http://fr.wikipedia.org/wiki/EIA-485" target="_blank">wikipédia</a>, <a href="http://www.technologuepro.com/cours-systemes-embarques/cours-systemes-embarques-Bus-RS485-MODBUS-Prifibus.htm" target="_blank">technologuepro</a><br />
Mais je me suis principalement appuyé sur le document officiel : <a href="http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf" target="_blank">Modbus Serial Line Protocol and Implementation Guide</a></p>
<p>La liaison physique RS485 permet des liaisons multipoints, on peut donc connecter plusieurs esclaves et un maitre sur le même bus. Dans notre cas, le maitre sera un système embarqué sous GNU/Linux avec un adaptateur RS232/RS485 et les esclaves seront les régulateurs de températures eurotherm et la carte d&#8217;E/S. Chaque esclave doit avoir une adresse unique sur le bus (1 à 247). L&#8217;adresse 0 étant une adresse de diffusion (ou broadcast), les adresses supérieures à 247  sont réservés.</p>
<p>Il existe deux mode de transmission du protocole ModBUS sur voie série : le mode ASCII et le mode RTU (Remote Terminal Unit). Les régulateurs de température fonctionnant en mode RTU, on choisit donc d&#8217;implémenter ce mode pour la carte E/S. Le format de transmission en mode RTU pour chaque octet est le suivant :</p>
<ul>
<li>un bit de start (front descendant)</li>
<li>8 bits de données : poids faible en premier</li>
<li>1 bit de parité (la norme recommande une parité paire mais nous n&#8217;utiliserons pas de parité car les régulateurs sont configurés de cette manière)</li>
<li>1 bit de stop s&#8217;il y a un bit de parité sinon 2 bits de stop (dans notre montage : pas de bit de parité et un bit de stop)</li>
</ul>
<p>Le format d&#8217;une trame ModBUS RTU est le suivant:</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/02/modbus1.png" rel="lightbox[842]"><img class="aligncenter size-full wp-image-867" title="Trame ModBUS RTU" src="http://innovelectronique.fr/wp-content/uploads/2012/02/modbus1.png" alt="Trame ModBUS RTU" width="548" height="38" /></a></p>
<ul>
<li>Adresse de l&#8217;esclave sur un octet compris entre 1 et 247.</li>
<li>Le code fonction correspond à une opération demandée par le maitre auquel l&#8217;esclave doit répondre sauf dans le cas ou le maitre envoie une trame de broadcast (à l&#8217;adresse 0).</li>
<li>Les données que ce soit pour une demande de la part du maitre ou une réponse de l&#8217;esclave sont groupés sous forme de mots (2 octets) dont le MSB est en premier.</li>
<li>Le CRC est un code de vérification de la trame généré par le maitre ou l&#8217;esclave. Ce CRC suit la norme CRC16 : l&#8217;algorithme est décrit dans le document officiel de la norme. Une application en ligne pour calculer les CRC est disponible <a href="http://www.lammertbies.nl/comm/info/crc-calculation.html" target="_blank">ici</a> ou<a href="http://sitelec.org/cours/abati/flash/crc16.swf" target="_blank"> là</a>.</li>
</ul>
<p>Chaque trame ModBUS RTU doit être précédé et suivi d&#8217;un temps de repos de 3,5 fois la durée d&#8217;un caractère (d&#8217;un octet). Ce qui donne au niveau temps : à 9600 bauds/s : 4ms et à 19200 bauds/s : 2ms pour des trames 8E1. La détection de fin de trame sur le PIC se fera en détectant ce temps après la réception du dernier caractère.</p>
<p>Le ModBUS propose un ensemble de fonctions (Code Fonction). Toutes ces fonctions lisent ou écrivent dans une zone mémoire spéciale de l&#8217;esclave pour commander les différents organes de la carte. Dans notre cas le découpage mémoire des registres internes est le suivant:</p>
<ol>
<li>Registre 0 sur 16 bits : pilote le relais 1. Écrire un &#8216;0&#8242; dans ce registre met le relai en position repos, écrire un chiffre supérieur à 0 met le relai en position travail (dans notre exemple : alarme visuelle)</li>
<li>Registre 1 sur 16 bits : pilote le relais 2. Écrire un &#8216;0&#8242; dans ce registre met le relai en  position repos, écrire un chiffre supérieur à 0 met le relai en position  travail (dans notre exemple : alarme sonore)</li>
<li>Registre 2 sur 16 bits : pilote le relais 3. Écrire un &#8216;0&#8242; dans ce registre met le relai en  position repos, écrire un chiffre supérieur à 0 met le relai en position  travail (dans notre exemple : pilote l&#8217;aspirateur des fumées)</li>
<li>Registre 3 sur 16 bits : pilote le relais 4. Écrire un &#8216;0&#8242; dans ce registre met le relai en  position repos, écrire un chiffre supérieur à 0 met le relai en position  travail (dans notre exemple : permet de basculer du mode manuel (position repos) au mode automatique (position travail))</li>
<li>Registre 4 sur 16 bits : génère une tension continue comprise entre 0V et 10V. Écrire un &#8216;0&#8242; dans ce registre génère du 0V en sortie, écrire &#8216;1023&#8242; génère du +10V (dans notre exemple, cette tension sert au pilotage du régulateur de vitesse Altivar)</li>
</ol>
<p>Dans notre cas, la carte d&#8217;E/S ne répondra qu&#8217;à trois commandes:</p>
<ul>
<li><strong>Code fonction 0&#215;03</strong> : Read Holding Registers : Lire les registres internes. Cette commande permet d&#8217;obtenir l&#8217;état des différents organes de la carte. Cette commande permet de lire n registres 16 bits à partir du registre x codé sur 16 bits.<br />
<a href="http://innovelectronique.fr/wp-content/uploads/2012/02/modbus_trame_type033.png" rel="lightbox[842]"><img class="aligncenter size-full wp-image-886" title="modbus_trame_type033" src="http://innovelectronique.fr/wp-content/uploads/2012/02/modbus_trame_type033.png" alt="modbus_trame_type033" width="718" height="133" /></a><br />
<a href="http://innovelectronique.fr/wp-content/uploads/2012/02/modbus_trame_type031.png" rel="lightbox[842]"></a>*: le nombre d&#8217;octets renvoyés est égale au Nb de registre à lire x 2<br />
Par exemple la trame ModBUS suivante <strong>sans CRC</strong> permet de lire l&#8217;état des trois premiers relais en une seule lecture (l&#8217;esclave est à l&#8217;adresse 16 ou 0&#215;10) : 0&#215;10 0&#215;03 0&#215;00 0&#215;00 0&#215;00 0&#215;03. Si vous désirez obtenir la valeur de la tension actuelle qui pilote l&#8217;altivar : 0&#215;10 0&#215;03 0&#215;00 0&#215;04 0&#215;00 0&#215;01</li>
<li><strong>Code fonction 0&#215;06</strong> : Write Single Register : Ecrire dans un registre. Cette commande permet d&#8217;écrire une valeur codée sur 16bits dans le registre indiqué.<br />
<a href="http://innovelectronique.fr/wp-content/uploads/2012/02/modbus_trame_type06.png" rel="lightbox[842]"><img class="aligncenter size-full wp-image-864" title="Requete/Reponse ModBUS type 0x06" src="http://innovelectronique.fr/wp-content/uploads/2012/02/modbus_trame_type06.png" alt="Requete/Reponse ModBUS type 0x06" width="643" height="138" /></a>Vous remarquez que si tout c&#8217;est passé correctement la réponse est identique à la requête. Par exemple la trame ModBUS sans CRC qui suit permet de passer le relais2 en mode travail : 0&#215;10 0&#215;06 0&#215;00 0&#215;01 0&#215;00 0&#215;01.</li>
<li><strong>Code fonction 0&#215;08</strong> : Diagnostics : Diagnostique. Seule la sous fonction 0&#215;0000 est implémenté. Cette sous fonction est &#8220;echo&#8221;. La réponse est identique à la requête. Par exemple, si vous envoyez la trame suivante sans CRC : 0&#215;10 0&#215;08 0&#215;00 0&#215;00 0&#215;12 0&#215;34, vous devriez obtenir exactement la même chose en retour.</li>
</ul>
<h1>Code source en Langage C pour le PIC18F2520</h1>
<p>Le code source suivant permet de réaliser le cahier des charges précédent. Il est commenté, cependant si quelque chose n&#8217;était pas assez clair, n&#8217;hésitez pas à me contacter&#8230;</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p842code2'); return false;">View Code</a> C</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p8422"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
</pre></td><td class="code" id="p842code2"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// Carte gestion des alarmes, de l'aspirateur de fumées, et de l'altivar</span>
<span style="color: #666666; font-style: italic;">// avec le protocole MODBUS sur voie série (ModBUS RTU) RS485</span>
<span style="color: #666666; font-style: italic;">// Projet Four - InnovDecor</span>
<span style="color: #666666; font-style: italic;">// O. Dartois - le 19/02/2012</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Remarque: Je me suis basé pour implémenter le protocole ModBUS sur la doc</span>
<span style="color: #666666; font-style: italic;">// des régulateurs 2208e de la société EuroTherm. Dans la présentation des trames</span>
<span style="color: #666666; font-style: italic;">// il y a une erreur sur l'ordre des octets du CRC. Dans la documentation il est</span>
<span style="color: #666666; font-style: italic;">// indiqué MSB puis LSB or aprés lecture du protocole officiel:</span>
<span style="color: #666666; font-style: italic;">// http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf p44</span>
<span style="color: #666666; font-style: italic;">// il s'avère que l'on doit transmettre dans l'ordre LSB puis MSB !!!</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Seulement 3 fonctions du protocole MODBUS sont implémentées dans ce code</span>
<span style="color: #666666; font-style: italic;">// et pour les besoins du projet. Un mot = 16 bits</span>
<span style="color: #666666; font-style: italic;">// Fonction 06 : Ecriture d'un mot</span>
<span style="color: #666666; font-style: italic;">// Fonction 03 : Lecture de N mots</span>
<span style="color: #666666; font-style: italic;">// Fonction 08 : Bouclage (ou loopback)</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//#include &amp;lt;16F886.h&amp;gt;</span>
<span style="color: #339933;">#include &amp;lt;18F2520.h&amp;gt;</span>
&nbsp;
<span style="color: #339933;">#device *=16</span>
<span style="color: #339933;">#device adc=10                   // CAN en mode 10bits</span>
&nbsp;
<span style="color: #339933;">#FUSES NOWDT                     //No Watch Dog Timer</span>
<span style="color: #339933;">#FUSES INTRC_IO                  //Oscillateur interne si utilisé</span>
<span style="color: #666666; font-style: italic;">//#FUSES HS                       //Utilisation d'un quartz externe &amp;gt;= à 4MHz</span>
<span style="color: #339933;">#FUSES PUT                       //Power Up Timer</span>
<span style="color: #339933;">#FUSES MCLR                      //Master Clear pin enabled</span>
<span style="color: #339933;">#FUSES NOPROTECT                 //Code not protected from reading</span>
<span style="color: #339933;">#FUSES NOCPD                     //No EE protection</span>
<span style="color: #339933;">#FUSES NOBROWNOUT                //No brownout reset</span>
<span style="color: #339933;">#FUSES NOIESO                    //Internal External Switch Over mode enabled</span>
<span style="color: #339933;">#FUSES NOFCMEN                   //Fail-safe clock monitor enabled</span>
<span style="color: #339933;">#FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O</span>
<span style="color: #339933;">#FUSES NODEBUG                   //No Debug mode for ICD</span>
<span style="color: #339933;">#FUSES NOWRT                     //Program memory not write protected</span>
<span style="color: #666666; font-style: italic;">//#FUSES BORV21                  //Brownout reset at 2.1V</span>
<span style="color: #339933;">#FUSES CCP2B3                    // Sortie de la PWM2 sur la broche B3</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Horloge interne a 8MHz</span>
<span style="color: #666666; font-style: italic;">//#use delay(internal=4M, clock=16M)</span>
<span style="color: #339933;">#use delay(internal=8M)</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Activation du SCI à 9600 bauds/s en 8N1, gestion du half duplex avec la broche C5</span>
<span style="color: #339933;">#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ENABLE=PIN_C5)</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Gestion par le programmeur des ports d'E/S</span>
<span style="color: #339933;">#use fast_io(A)</span>
<span style="color: #339933;">#use fast_io(B)</span>
<span style="color: #339933;">#use fast_io(C)</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Define pour faciliter la lecture du programme</span>
<span style="color: #339933;">#define AL1             PIN_A1</span>
<span style="color: #339933;">#define AL2             PIN_A2</span>
<span style="color: #339933;">#define AL3             PIN_A3</span>
<span style="color: #339933;">#define MAUTO           PIN_A4</span>
<span style="color: #339933;">#define GEST_HALF       PIN_C5</span>
<span style="color: #339933;">#define AL1_ON          output_high(AL1)</span>
<span style="color: #339933;">#define AL1_OFF         output_low(AL1)</span>
<span style="color: #339933;">#define AL2_ON          output_high(AL2)</span>
<span style="color: #339933;">#define AL2_OFF         output_low(AL2)</span>
<span style="color: #339933;">#define AL3_ON          output_high(AL3)</span>
<span style="color: #339933;">#define AL3_OFF         output_low(AL3)</span>
<span style="color: #339933;">#define MAUTO_ON        output_high(MAUTO)</span>
<span style="color: #339933;">#define MAUTO_OFF       output_low(MAUTO)</span>
<span style="color: #339933;">#define CHOIX_VITESSE   input(PIN_B2)</span>
&nbsp;
<span style="color: #339933;">#define MODBUS_LECTURE  0x03</span>
<span style="color: #339933;">#define MODBUS_ECRITURE 0x06</span>
<span style="color: #339933;">#define MODBUS_BOUCLAGE 0x08</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Les deux lignes suivantes ne sont plus nécessaires car c'est gérer par le #use RS232</span>
<span style="color: #666666; font-style: italic;">//#define EMISSION  output_high(GEST_HALF)</span>
<span style="color: #666666; font-style: italic;">//#define RECEPTION output_low(GEST_HALF)</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Variables globales du programme</span>
<span style="color: #993333;">const</span> <span style="color: #993333;">float</span> consigne<span style="color: #339933;">=</span><span style="color:#800080;">12.0</span><span style="color: #339933;">;</span>
int8 addr_carte <span style="color: #339933;">=</span> <span style="color: #0000dd;">16</span><span style="color: #339933;">;</span>
<span style="color: #993333;">volatile</span> int8 req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">16</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> cpt_req_modbus<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #993333;">volatile</span> int1 recep_trame_modbus <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Cette structure permet d'avoir l'état des differentes E/S de la carte</span>
<span style="color: #666666; font-style: italic;">// toutes les variables sont en int16 pour être conforme avec le MODBus</span>
<span style="color: #993333;">struct</span> registres_interne <span style="color: #009900;">&#123;</span>
   int16 relai0<span style="color: #339933;">;</span>
   int16 relai1<span style="color: #339933;">;</span>
   int16 relai2<span style="color: #339933;">;</span>
   int16 relai_ma<span style="color: #339933;">;</span>
   int16 val_cons10V<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> registres_carte<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Routines d'interruptions</span>
<span style="color: #666666; font-style: italic;">// Interruption réception voie serie</span>
<span style="color: #339933;">#int_RDA</span>
<span style="color: #993333;">void</span> RDA_isr<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #666666; font-style: italic;">// On stocke le caractère recu dans le tableau d'octets req_modus puis</span>
   <span style="color: #666666; font-style: italic;">// on incremente le compteur de réception</span>
   req_modbus<span style="color: #009900;">&#91;</span>cpt_req_modbus<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> getchar<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   cpt_req_modbus<span style="color: #339933;">++;</span>
   <span style="color: #666666; font-style: italic;">// Le timer0 gère le timeout, à chaque réception de caractères on repart à 0</span>
   <span style="color: #666666; font-style: italic;">// On met le compteur du timer0 à 0</span>
   set_timer0<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;">// On efface le drapeaux d'interruption car il a été fixé par ailleurs</span>
   clear_interrupt<span style="color: #009900;">&#40;</span>INT_TIMER0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #666666; font-style: italic;">// On active l'interruption</span>
   enable_interrupts<span style="color: #009900;">&#40;</span>INT_TIMER0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Si on recoit rien au bout de 1,5 fois la durée d'un octet on considère que</span>
<span style="color: #666666; font-style: italic;">// la trame modbus est complète</span>
<span style="color: #339933;">#INT_TIMER0</span>
<span style="color: #993333;">void</span> timer0_isr<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   disable_interrupts<span style="color: #009900;">&#40;</span>INT_TIMER0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   recep_trame_modbus <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Fonction d'initialisation pour parametrer tous les modules du PIC</span>
<span style="color: #993333;">void</span> initialisation<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   int8 choix_adresse<span style="color: #339933;">;</span>                       <span style="color: #666666; font-style: italic;">// Variable temporaire pour le choix de l'adresse de la carte</span>
&nbsp;
   setup_adc_ports<span style="color: #009900;">&#40;</span>AN0<span style="color: #339933;">|</span>VSS_VDD<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>             <span style="color: #666666; font-style: italic;">// Activation de l'entree analogique AN0</span>
   setup_adc<span style="color: #009900;">&#40;</span>ADC_CLOCK_INTERNAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>            <span style="color: #666666; font-style: italic;">// Utilisation de l'horloge interne du CAN</span>
   set_tris_a<span style="color: #009900;">&#40;</span><span style="color: #208080;">0b11100001</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                   <span style="color: #666666; font-style: italic;">// On fixe les E/S sur les ports</span>
   set_tris_b<span style="color: #009900;">&#40;</span><span style="color: #208080;">0b11110111</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                   <span style="color: #666666; font-style: italic;">// 0 : Output = sortie</span>
   set_tris_c<span style="color: #009900;">&#40;</span><span style="color: #208080;">0b10011011</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                   <span style="color: #666666; font-style: italic;">// 1 : Input = entree</span>
   port_b_pullups<span style="color: #009900;">&#40;</span><span style="color: #208080;">0b00000111</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>               <span style="color: #666666; font-style: italic;">// Activation des résistances de rappel individuellement</span>
   setup_spi<span style="color: #009900;">&#40;</span>SPI_SS_DISABLED<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>               <span style="color: #666666; font-style: italic;">// Desactivation du SPI</span>
   setup_timer_0<span style="color: #009900;">&#40;</span>T0_INTERNAL<span style="color: #339933;">|</span>T0_DIV_32<span style="color: #339933;">|</span>T0_8_BIT<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// Reglage du timer 0</span>
   setup_timer_1<span style="color: #009900;">&#40;</span>T1_DISABLED<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>               <span style="color: #666666; font-style: italic;">// Desactivation timer 1</span>
   setup_ccp1<span style="color: #009900;">&#40;</span>CCP_PWM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                      <span style="color: #666666; font-style: italic;">// Activation de la premiere PWM : generation 12V</span>
   setup_ccp2<span style="color: #009900;">&#40;</span>CCP_PWM<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                      <span style="color: #666666; font-style: italic;">// Activation de la deuxieme PWM : generation 10V</span>
   setup_timer_2<span style="color: #009900;">&#40;</span>T2_DIV_BY_1<span style="color: #339933;">,</span><span style="color: #0000dd;">255</span><span style="color: #339933;">,</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>         <span style="color: #666666; font-style: italic;">// Activation des PWM avec le timer2</span>
   setup_comparator<span style="color: #009900;">&#40;</span>NC_NC_NC_NC<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>            <span style="color: #666666; font-style: italic;">// Desactivation des modules de comparaison</span>
   set_adc_channel<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                       <span style="color: #666666; font-style: italic;">// Choix du canal 0 pour le CAN</span>
   output_a<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                              <span style="color: #666666; font-style: italic;">// Sorties du port A a 0 : relais en position repos</span>
   memset<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>registres_carte<span style="color: #339933;">,</span><span style="color: #0000dd;">0</span><span style="color: #339933;">,</span><span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span>registres_carte<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Initialisation des registres de la carte à 0</span>
   set_pwm1_duty<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                         <span style="color: #666666; font-style: italic;">// MLI generation 12V arrêté</span>
   set_pwm2_duty<span style="color: #009900;">&#40;</span>registres_carte.<span style="color: #202020;">val_cons10V</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// MLI generation 10V arreté</span>
   disable_interrupts<span style="color: #009900;">&#40;</span>INT_TIMER0<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// Interruption tts les 1/(8MHz/4) * 32 * 256 = 4,096ms</span>
   enable_interrupts<span style="color: #009900;">&#40;</span>INT_RDA<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>               <span style="color: #666666; font-style: italic;">// Activation interruption voie serie</span>
   enable_interrupts<span style="color: #009900;">&#40;</span>GLOBAL<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                <span style="color: #666666; font-style: italic;">// Activation des interruptions (globalement)</span>
   <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>CHOIX_VITESSE<span style="color: #009900;">&#41;</span> setup_uart<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">19200</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>    <span style="color: #666666; font-style: italic;">// Si un cavalier est présent sur J7 on change la vitesse</span>
                                             <span style="color: #666666; font-style: italic;">// de l'USART à 19200 bauds/s au lieu de 9600 bauds/s</span>
   choix_adresse <span style="color: #339933;">=</span> input_b<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span><span style="color: #208080;">0x03</span><span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// On récupère l'état des cavaliers J5 et J6</span>
                                             <span style="color: #666666; font-style: italic;">// Si un cavalier =&amp;gt;0, si pas de cavalier =&amp;gt;1 car résistances de rappel interne</span>
   <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>choix_adresse<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">3</span> <span style="color: #339933;">:</span> addr_carte <span style="color: #339933;">=</span> <span style="color: #208080;">0x10</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>     <span style="color: #666666; font-style: italic;">// Pas de cavalier : adresse de la carte : 0x10 ou 16</span>
      <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">:</span> addr_carte <span style="color: #339933;">=</span> <span style="color: #208080;">0x20</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>     <span style="color: #666666; font-style: italic;">// Pas de cavalier sur J6, cavalier sur J5 : adresse de la carte : 0x20 ou 32</span>
      <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">:</span> addr_carte <span style="color: #339933;">=</span> <span style="color: #208080;">0x40</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>     <span style="color: #666666; font-style: italic;">// Pas de cavalier sur J5, cavalier sur J6 : adresse de la carte : 0x40 ou 64</span>
      <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">0</span> <span style="color: #339933;">:</span> addr_carte <span style="color: #339933;">=</span> <span style="color: #208080;">0x80</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>     <span style="color: #666666; font-style: italic;">// Cavalier sur J5 et J6 : : adresse de la carte : 0x80 ou 128</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Code trouvé sur un forum, une version optimisé existe chez CCS</span>
int16 calc_crc16<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   int16 crc <span style="color: #339933;">=</span> <span style="color: #208080;">0xFFFF</span><span style="color: #339933;">;</span>
   int8 i<span style="color: #339933;">,</span> done <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
   int8 todo<span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
         todo <span style="color: #339933;">=</span> req_modbus<span style="color: #009900;">&#91;</span>done<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
         crc <span style="color: #339933;">^=</span> todo<span style="color: #339933;">;</span>
         <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #0000dd;">8</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>crc <span style="color: #339933;">%</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">!=</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
               crc <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>crc <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">^</span> <span style="color: #208080;">0xA001</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
               crc <span style="color: #339933;">=</span> crc <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
         <span style="color: #009900;">&#125;</span>
         done<span style="color: #339933;">++;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>done <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #009900;">&#40;</span>cpt_req_modbus<span style="color: #339933;">-</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #b1b100;">return</span> crc<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #993333;">float</span> val_tension<span style="color: #339933;">;</span>
   int16 val_pwm<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
   int16 CRC16<span style="color: #339933;">,</span> registre<span style="color: #339933;">,</span> donnee<span style="color: #339933;">;</span>
   int8 i<span style="color: #339933;">,</span>j<span style="color: #339933;">;</span>
&nbsp;
   initialisation<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>recep_trame_modbus<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// On vérifie que l'adresse de l'esclave est la notre et que l'on a recu</span>
         <span style="color: #666666; font-style: italic;">// plus que 3 octets (taille minimum d'un requete MODBUS : 4 octets)</span>
         <span style="color: #666666; font-style: italic;">// Ex: Addr Esclave + Fonction Bouclage + CRC (2 octets) = 4 octets</span>
         <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> addr_carte <span style="color: #339933;">||</span> cpt_req_modbus<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> fin<span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">// calcul du CRC16 et comparaison avec celui transmis dans la trame</span>
         CRC16 <span style="color: #339933;">=</span> make16<span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span>cpt_req_modbus<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> req_modbus<span style="color: #009900;">&#91;</span>cpt_req_modbus<span style="color: #339933;">-</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">// on sort si le CRC n'est pas correct</span>
         <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>CRC16 <span style="color: #339933;">!=</span> calc_crc16<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> fin<span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">// On teste si on gère la fonction demandée</span>
         <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> MODBUS_BOUCLAGE<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span>
             <span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> MODBUS_ECRITURE<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span>
             <span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> MODBUS_LECTURE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> fin<span style="color: #339933;">;</span>
         <span style="color: #666666; font-style: italic;">// on aiguille suivant la fonction choisie</span>
         <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #b1b100;">case</span> MODBUS_ECRITURE <span style="color: #339933;">:</span>
               <span style="color: #666666; font-style: italic;">// On analyse si le registre existe sinon on sort</span>
               registre <span style="color: #339933;">=</span> make16<span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>registre <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> fin<span style="color: #339933;">;</span>
               donnee <span style="color: #339933;">=</span> make16<span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span>registre<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                  <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">0</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>donnee<span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>AL1_ON<span style="color: #339933;">:</span>AL1_OFF<span style="color: #339933;">;</span> registres_carte.<span style="color: #202020;">relai0</span><span style="color: #339933;">=</span>donnee<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                  <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">1</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>donnee<span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>AL2_ON<span style="color: #339933;">:</span>AL2_OFF<span style="color: #339933;">;</span> registres_carte.<span style="color: #202020;">relai1</span><span style="color: #339933;">=</span>donnee<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                  <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>donnee<span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>AL3_ON<span style="color: #339933;">:</span>AL3_OFF<span style="color: #339933;">;</span> registres_carte.<span style="color: #202020;">relai2</span><span style="color: #339933;">=</span>donnee<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                  <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">3</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>donnee<span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span>MAUTO_ON<span style="color: #339933;">:</span>MAUTO_OFF<span style="color: #339933;">;</span> registres_carte.<span style="color: #202020;">relai_ma</span><span style="color: #339933;">=</span>donnee<span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
                  <span style="color: #b1b100;">case</span> <span style="color: #0000dd;">4</span> <span style="color: #339933;">:</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>donnee <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;=</span> <span style="color: #0000dd;">1023</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> set_pwm2_duty<span style="color: #009900;">&#40;</span>donnee<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> registres_carte.<span style="color: #202020;">val_cons10V</span><span style="color: #339933;">=</span>donnee<span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #009900;">&#125;</span>
               <span style="color: #666666; font-style: italic;">// Notez l'absence du break ici pour renvoyer la réponse</span>
           <span style="color: #b1b100;">case</span> MODBUS_BOUCLAGE <span style="color: #339933;">:</span>
               <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>cpt_req_modbus<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> putc<span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
           <span style="color: #b1b100;">case</span> MODBUS_LECTURE <span style="color: #339933;">:</span>
               registre <span style="color: #339933;">=</span> make16<span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>registre <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #0000dd;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> fin<span style="color: #339933;">;</span>
               donnee <span style="color: #339933;">=</span> make16<span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>donnee <span style="color: #339933;">==</span> <span style="color: #0000dd;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>donnee <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> fin<span style="color: #339933;">;</span>
               <span style="color: #666666; font-style: italic;">// on teste si on ne demande pas des registres en dehors de la plage autorisée</span>
               <span style="color: #666666; font-style: italic;">// on a 5 registres accésibles à partir de 0</span>
               <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>registre<span style="color: #339933;">+</span>donnee<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">goto</span> fin<span style="color: #339933;">;</span>
               req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> donnee <span style="color: #339933;">*</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>
               <span style="color: #666666; font-style: italic;">// Les deux boucles 'for' pour remplir le tableau de la requete modbus à partir de la structure</span>
               <span style="color: #666666; font-style: italic;">// qui représente la mémoire de registre. Deux boucles pour gérer le passage LSB,MSB de la structure</span>
               <span style="color: #666666; font-style: italic;">// vers le format modbus qui réclame MSB,LSB</span>
               <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span>registre<span style="color: #339933;">*</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>j<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>j<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>donnee<span style="color: #339933;">*</span><span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>i<span style="color: #339933;">+=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>j<span style="color: #339933;">+=</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span> req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #339933;">+</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">=*</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>int8 <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>registres_carte <span style="color: #339933;">+</span> i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span>registre<span style="color: #339933;">*</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>j<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>j<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>donnee<span style="color: #339933;">*</span><span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>i<span style="color: #339933;">+=</span><span style="color: #0000dd;">2</span><span style="color: #339933;">,</span>j<span style="color: #339933;">+=</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#41;</span> req_modbus<span style="color: #009900;">&#91;</span><span style="color: #0000dd;">3</span><span style="color: #339933;">+</span>j<span style="color: #009900;">&#93;</span><span style="color: #339933;">=*</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>int8 <span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span>registres_carte <span style="color: #339933;">+</span> i <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               cpt_req_modbus <span style="color: #339933;">=</span> <span style="color: #0000dd;">3</span> <span style="color: #339933;">+</span> donnee <span style="color: #339933;">*</span> <span style="color: #0000dd;">2</span> <span style="color: #339933;">+</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">;</span>
               CRC16 <span style="color: #339933;">=</span> calc_crc16<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               req_modbus<span style="color: #009900;">&#91;</span>cpt_req_modbus<span style="color: #339933;">-</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> CRC16<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;&amp;</span>gt<span style="color: #339933;">;</span><span style="color: #0000dd;">8</span><span style="color: #339933;">;</span>
               req_modbus<span style="color: #009900;">&#91;</span>cpt_req_modbus<span style="color: #339933;">-</span><span style="color: #0000dd;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> CRC16<span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;</span><span style="color: #208080;">0x00FF</span><span style="color: #339933;">;</span>
               <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span><span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>cpt_req_modbus<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> putc<span style="color: #009900;">&#40;</span>req_modbus<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
               <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #009900;">&#125;</span>
&nbsp;
         fin<span style="color: #339933;">:</span>
         recep_trame_modbus <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">false</span><span style="color: #339933;">;</span>
         cpt_req_modbus <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Boucle d'asservissement de la tension 12V</span>
      <span style="color: #666666; font-style: italic;">// Pont diviseur : R20=68K, R21=33K donc VCAN_12V = (33K/(33K+68K)*(VCC/2^10)</span>
      val_tension <span style="color: #339933;">=</span> read_adc<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color:#800080;">0.0145</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>abs<span style="color: #009900;">&#40;</span>consigne<span style="color: #339933;">-</span>val_tension<span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color:#800080;">0.05</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>val_tension<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span>consigne <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> val_pwm<span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span><span style="color: #0000dd;">1000</span><span style="color: #009900;">&#41;</span> val_pwm<span style="color: #339933;">++;</span>
         <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>val_tension<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span>consigne <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> val_pwm<span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span><span style="color: #0000dd;">5</span><span style="color: #009900;">&#41;</span> val_pwm<span style="color: #339933;">--;</span>
         set_pwm1_duty<span style="color: #009900;">&#40;</span>val_pwm<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
      delay_us<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">500</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong>Remarque</strong> : lorsqu&#8217;une trame n&#8217;est pas valide ou qu&#8217;elle contient une requête non conforme, le code se contente de l&#8217;ignorer. Donc si vous ne recevez rien en retour d&#8217;une requête c&#8217;est que très certainement celle-ci est incorrecte ou que votre liaison physique est défectueuse. Rappelez-vous aussi qu&#8217;en l’absence de cavalier sur J5,J6 et J7 la carte a comme adresse 0&#215;10 ou 16 en décimal et qu&#8217;elle fonctionne en 8N1 à 9600 bauds/s !</p>
<h1>Programmation de la carte en langage C++ et réalisation de classes</h1>
<p>Cette carte sera pilotée sous au moins deux environnements : un avec du GNU/Linux (emDebian sur plateforme TQ6410 avec QT comme framework), l&#8217;autre avec un PC industriel sous Microsoft Windows. Pour faciliter le pilotage de cette carte et des régulateurs, il a été décidé de créer des classes C++. Ces classes C++ se baseront sur la librairie open source libmodbus disponible sur<a href="http://libmodbus.org/" target="_blank"> libmodbus.org</a>. Je ne peux pour l&#8217;instant pas donner les codes sources de ces classes, ni les tests unitaires réalisés avec celles-ci tant que les étudiants n&#8217;ont pas fini leur projet. La seule chose que je peux affirmer pour l&#8217;instant, c&#8217;est que les classes fonctionnent dans le cadre que l&#8217;on s&#8217;est fixé. Les codes sources seront disponibles lorsque les étudiants auront finalisé le projet&#8230;</p>
<p>L&#8217;interface graphique de test suivante a été réalisé sous GNU/Linux Debian avec Qt4.7 et les classes développées pour la carte :</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2012/02/capture-test-carte-es-modbus-sur-rs4851.png" rel="lightbox[842]"><img class="aligncenter size-full wp-image-883" title="capture-test-carte-es-modbus-sur-rs4851" src="http://innovelectronique.fr/wp-content/uploads/2012/02/capture-test-carte-es-modbus-sur-rs4851.png" alt="capture-test-carte-es-modbus-sur-rs4851" width="451" height="493" /></a></p>
<h1>Conclusion temporaire</h1>
<p>Je pense que la mise en place chez l&#8217;industriel concerné va amener des modifications au niveau de la carte d&#8217;E/S. Lorsque le projet sera totalement finalisé, je mettrais à disposition les sources et le nouveau typon. En attendant vous avez largement de quoi débuter avec cette carte&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2012/02/27/carte-es-sur-relais-230v-pilotable-par-le-protocole-modbus/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Utilisation de Qt sur la carte TQ6410</title>
		<link>http://innovelectronique.fr/2011/08/31/utilisation-de-qt-sur-la-carte-tq6410/</link>
		<comments>http://innovelectronique.fr/2011/08/31/utilisation-de-qt-sur-la-carte-tq6410/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 20:53:07 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[Linux Embarqué]]></category>

		<category><![CDATA[emdebian]]></category>

		<category><![CDATA[QT]]></category>

		<category><![CDATA[TQ6410]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=798</guid>
		<description><![CDATA[Cette carte a été acheté dans le but de développer une application graphique de commande d&#8217;un processus industriel. Le choix du kit graphique est pour l&#8217;instant Qt. Pour construire cette application, nous allons la développer sur notre machine de bureau puis la &#8220;cross-compiler&#8221; pour ensuite la faire fonctionner sur le système embarqué. Il existe sur [...]]]></description>
			<content:encoded><![CDATA[<p>Cette carte a été acheté dans le but de développer une application graphique de commande d&#8217;un processus industriel. Le choix du kit graphique est pour l&#8217;instant Qt. Pour construire cette application, nous allons la développer sur notre machine de bureau puis la &#8220;cross-compiler&#8221; pour ensuite la faire fonctionner sur le système embarqué. Il existe sur internet de nombreux sites qui présente cette méthode. Je me base sur les sites suivants :<a href="http://cor-net.org/2009/03/qt-45-on-mini2440/"> http://cor-net.org/2009/03/qt-45-on-mini2440/</a> , sur le <a href="http://billforums.station51.net/viewtopic.php?f=8&amp;t=15" target="_blank">bill&#8217;s blog</a> et sur le site de Pobot (<a href="http://www.pobot.org/Qt4-6-embedded-sur-la-mini2440.html" target="_blank">article1</a> et <a href="http://www.pobot.org/Qt-embedded-on-avance.html" target="_blank">article2</a>).</p>
<p><span id="more-798"></span>Je travaille avec une debian Sqeeze Grip (6.0). Les &#8220;pseudos&#8221; systèmes de fichiers /proc et /sys sont bien montés au démarrage. Le framebuffer est bien géré par le noyau. Le &#8220;touchscreen&#8221; est détecté dans /devices/virtual/input/input0. Un petit tour dans /dev que udev a peuplé pour trouver &#8220;fb0&#8243; et &#8220;input/event0&#8243;. La gestion du touchscreen sera assuré par la librairie tslib. Celle-ci a été installé avec les paquets standards de debian (voir les autres articles). La base <em>semble</em> correct&#8230;En fait lors des premières compilations de Qt j&#8217;ai eu des soucis avec la librairies tslib qu&#8217;il ne trouvait pas même en ayant installé les paquets de développement. J&#8217;ai donc choisi de recompiler complètement la librairie et les utilitaires qui l&#8217;accompagne. La procédure est décrite ci-dessous.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code14'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79814"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p798code14"><pre class="text" style="font-family:monospace;">root@casimir:~/qt-everywhere/# git clone http://github.com/kergoth/tslib.git
root@casimir:~/qt-everywhere/# cd tslib/
root@casimir:~/qt-everywhere/tslib# aptitude install dh-autoreconf
root@casimir:~/qt-everywhere/tslib# ./autogen.sh
root@casimir:~/qt-everywhere/tslib# ./configure --host=arm-linux-gnueabi --prefix=/usr/local/tslib --enable-static --enable-shared
root@casimir:~/qt-everywhere/tslib# make -j2
root@casimir:~/qt-everywhere/tslib# make install</pre></td></tr></table></div>

<p>La librairie tslib nécessite autoconf, d’où l&#8217;installation de autoreconf. Ensuite on compile en dynamique et en statique et enfin on installe dans /usr/local/tslib. Ce répertoire est ensuite copié intégralement sur la SDCard qui contient le &#8216;rootfs&#8217; pour la carte TQ6410. On monte la carte et on copie le tout :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code15'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79815"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p798code15"><pre class="text" style="font-family:monospace;">root@casimir:~/qt-everywhere/tslib# mount -t auto /dev/sdd1 /mnt
root@casimir:~/qt-everywhere/tslib# copy -R /usr/local/tslib /mnt/usr/local
root@casimir:~/qt-everywhere/tslib# sync; umount /mnt</pre></td></tr></table></div>

<p>On passe maintenant à la compilation de Qt. Sur notre machine de développement, on créée un nouveau répertoire puis on télécharge à l&#8217;aide de wget la dernière archive en date (qt-4.7.3 : 204Mo) de qt-everywhere enfin on désarchive le tout:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code16'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79816"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p798code16"><pre class="text" style="font-family:monospace;">root@casimir:~# mkdir qt-everywhere
root@casimir:~# cd qt-everywhere
root@casimir:~/qt-everywhere# wget http://get.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.7.3.tar.gz
root@casimir:~/qt-everywhere# tar xzvf qt-everywhere-opensource-src-4.7.3.tar.gz</pre></td></tr></table></div>

<p>On rentre dans le répertoire puis on modifie le mkspec pour un arm v6 (arm11 sur le S3C36410):</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code17'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79817"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code" id="p798code17"><pre class="text" style="font-family:monospace;">root@casimir:~/qt-everywhere# cd qt-everywhere-opensource-src-4.7.3
root@casimir:~/qt-everywhere/qt-everywhere-opensource-src-4.7.3# vi mkspecs/qws/linux-armv6-g++/qmake.conf 
&nbsp;
## qmake configuration for building for ARMv6 devices with arm-linux-g++#
&nbsp;
include(../../common/g++.conf)
include(../../common/linux.conf)
include(../../common/qws.conf)
&nbsp;
# modifications to g++.conf
QMAKE_CC                = arm-linux-gnueabi-gcc
QMAKE_CXX               = arm-linux-gnueabi-g++
QMAKE_LINK              = arm-linux-gnueabi-g++
QMAKE_LINK_SHLIB        = arm-linux-gnueabi-g++
QMAKE_CFLAGS           += -march=armv6
QMAKE_CXXFLAGS         += -march=armv6
&nbsp;
# modifications to linux.conf
QMAKE_AR                = arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY           = arm-linux-gnueabi-objcopy
QMAKE_STRIP             = arm-linux-gnueabi-strip
&nbsp;
QMAKE_INCDIR += /usr/local/tslib/include/
QMAKE_LIBDIR += /usr/local/tslib/lib/
QMAKE_LFLAGS += -Wl,-rpath-link=/usr/local/tslib/lib
&nbsp;
load(qt_config)</pre></td></tr></table></div>

<p>On adapte l&#8217;existant pour faire pointer vers notre chaine de cross-compilation (ici arm-linux-gnueabi-xxxx), on rajoute les lignes QMAKE_INCDIR, QMAKE_LIBDIR pour qu&#8217;il utilise les includes et librairies de la TSLIB. La ligne QMAKE_LFLAGS permet d&#8217;éviter une erreur à l&#8217;édition de lien (voir ce <a href="http://developer.qt.nokia.com/forums/viewthread/3203" target="_blank">lien</a>). On lance ensuite la création des &#8216;makefiles&#8217; puis la compilation et l&#8217;installation avec les commandes suivantes:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code18'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79818"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p798code18"><pre class="text" style="font-family:monospace;">root@casimir:~/qt-everywhere/qt-everywhere-opensource-src-4.7.3# ./configure -embedded arm -xplatform qws/linux-armv6-g++ -prefix /usr/local/Qt -qt-mouse-tslib -little-endian
root@casimir:~/qt-everywhere/qt-everywhere-opensource-src-4.7.3# make -j2
root@casimir:~/qt-everywhere/qt-everywhere-opensource-src-4.7.3# make install</pre></td></tr></table></div>

<p>Dans la ligne &#8216;configure&#8217; on génère tous les exemples, démos, docs, librairies, etc&#8230;Je l&#8217;ai laissé pour être sur de tout avoir correctement cependant la durée de compilation sur ma machine est énorme (plus de 6H : attention c&#8217;est un athlon et un disque ide de 40Go). Si une erreur apparaît en disant qu&#8217;il ne trouve pas la tslib, passez l&#8217;argument &#8216;-v&#8217; à la commande configure puis regarder les logs. Dans la plupart des cas c&#8217;est qu&#8217;il ne trouve pas le compilateur : mettre dans le qmake.conf le nom et le chemin complet du cross-compilateur. Le &#8216;make install&#8217; n&#8217;est pas strictement nécessaire car il va copier dans /usr/local/Qt l&#8217;ensemble des fichiers. Ca fait un peu doublon mais ensuite je vais transférer ce répertoire directement sur la carte SD qui contient ma debian lenny Grip (procédure identique à la copie de la tslib, ici le répertoire source est /usr/local/Qt).</p>
<p>Du coté de la carte TQ6410, je désinstalle les paquets que j&#8217;avais installé auparavant et qui risque de gêner quand je vais installer Qt: nodm, matchbox et libts:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code19'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79819"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p798code19"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# aptitude remove --purge matchbox
root@TQ6410-Iris:~# aptitude remove --purge nodm
root@TQ6410-Iris:~# aptitude remove --purge libts-0.0-0</pre></td></tr></table></div>

<p>On installe ensuite la tslib que l&#8217;on a compilé auparavant sur notre machine de développement et on informe que l&#8217;on a de nouvelles librairies en créant un fichier /etc/ld.so.conf/tslib.conf qui contient le chemin vers les nouvelles librairies. Dans mon cas ce sera: /usr/local/tslib/lib. On met à jour la configuration en lançant ldconfig. Ensuite éditez le fichier /usr/local/tslib/etc/ts.conf pour décommenter la ligne qui contient &#8216;module raw&#8217;. Faire ensuite tous les exports de la tslib en faisant bien attention aux chemins et en laissant TSLIB_CALIBFILE= vide.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code20'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79820"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p798code20"><pre class="text" style="font-family:monospace;">export TSLIB_TSEVENTTYPE=INPUT
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=
export TSLIB_CONFFILE=/usr/local/tslib/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/local/tslib/lib/ts
export QWS_MOUSE_PROTO=tslib:/dev/input/event0</pre></td></tr></table></div>

<p>On lance ensuite la calibration de l&#8217;écran avec:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code21'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79821"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p798code21"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~#/usr/local/bin/ts_calibrate /usr/local/tslib/etc/ts.calib</pre></td></tr></table></div>

<p>Vous appuyez sur les croix qui apparaissent&#8230;vous obtenez alors un fichier de calibration de l&#8217;écran. Vous pouvez alors faire l&#8217;export de TSLIB_CALIBFILE correctement:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code22'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79822"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p798code22"><pre class="text" style="font-family:monospace;">export TSLIB_CALIBFILE=/usr/local/tslib/etc/ts.calib</pre></td></tr></table></div>

<p>Pour tester lancez : /usr/local/tslib/bin/ts_test. Si c&#8217;est bon vous pouvez tester les applications Qt que vous avez compilé précédemment. Elles sont disponibles dans /usr/local/Qt/examples et demos. Quand vous lancez une application, il faut faire:</p>
<p>./nom_appli -qws pour la lancer en mode embarqué. Si les caractères sont illisibles à l&#8217;écran, il faut rajouter deux variables aux précédentes:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code23'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79823"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p798code23"><pre class="text" style="font-family:monospace;">export QWS_SIZE=800x600
export QWS_DISPLAY=&quot;LinuxFb:mmWidth=160:mmHeight=100&quot;</pre></td></tr></table></div>

<p>Ces variables correspondent bien sur à mon écran (ici un 7&#8221;). J&#8217;ai ensuite récupéré une démonstration de &#8216;widget&#8217; pour l&#8217;embarqué pour les compiler. J&#8217;ai suivi la procédure de <a href="http://www.pobot.org/Qt-embedded-on-avance.html" target="_blank">pobot</a> mais j&#8217;ai désarchivé dans /usr/local/Qt. J&#8217;ai donc un nouveau répertoire du nom de &#8216;embedded-widgets-1.1.0&#8242;. Pour compiler ces nouveaux exemples, j&#8217;ai tapé ces lignes dans le répertoire précédemment cité:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p798code24'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p79824"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p798code24"><pre class="text" style="font-family:monospace;">export PATH=/usr/local/Qt/bin:$PATH
/usr/local/Qt/bin/qmake -spec qws/linux-armv6-g++
make</pre></td></tr></table></div>

<p>J&#8217;ai ensuite transféré ce répertoire sur ma carte SD et testé sur la carte TQ6410. Cela fonctionne très bien et les widgets sont réellement impressionnants.</p>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2011/08/31/utilisation-de-qt-sur-la-carte-tq6410/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Optimisation du temps de &#8216;Boot&#8217; et choix du système de fichiers parmi ext3, jffs2, yaffs2 et ubifs pour le &#8216;rootfs&#8217; de la carte TQ6410</title>
		<link>http://innovelectronique.fr/2011/08/09/optimisation-du-temps-de-boot-et-choix-du-systeme-de-fichiers-parmi-ext3-jffs2-yaffs2-et-ubifs-pour-le-rootfs-de-la-carte-tq6410/</link>
		<comments>http://innovelectronique.fr/2011/08/09/optimisation-du-temps-de-boot-et-choix-du-systeme-de-fichiers-parmi-ext3-jffs2-yaffs2-et-ubifs-pour-le-rootfs-de-la-carte-tq6410/#comments</comments>
		<pubDate>Tue, 09 Aug 2011 11:52:45 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[Linux Embarqué]]></category>

		<category><![CDATA[emdebian]]></category>

		<category><![CDATA[JFFS2]]></category>

		<category><![CDATA[QT]]></category>

		<category><![CDATA[TQ6410]]></category>

		<category><![CDATA[UBIFS]]></category>

		<category><![CDATA[YAFFS2]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=758</guid>
		<description><![CDATA[Maintenant que la plateforme de test générique est fonctionnelle, nous allons faire quelques tests pour optimiser l&#8217;ensemble. Nous allons nous consacrer à réduire le temps de chargement du noyau jusqu&#8217;au passage au système de fichiers racine. Puis dans un second temps nous choisirons le système de fichiers du rootfs. Une grande partie des optimisations mises [...]]]></description>
			<content:encoded><![CDATA[<p>Maintenant que la plateforme de test générique est fonctionnelle, nous allons faire quelques tests pour optimiser l&#8217;ensemble. Nous allons nous consacrer à réduire le temps de chargement du noyau jusqu&#8217;au passage au système de fichiers racine. Puis dans un second temps nous choisirons le système de fichiers du rootfs. Une grande partie des optimisations mises en place viennent de remarque de ce site : <a href="http://elinux.org/Boot_Time" target="_blank">eLinux</a>.</p>
<p><span id="more-758"></span>Le démarrage de la carte à froid (cold boot) se déroule dans cet ordre :</p>
<ol>
<li>Lancement du chargeur intégré à la puce SoC (chez TI : X-Loader, chez Samsung ?) qui charge U-Boot depuis la flash NAND</li>
<li>Démarrage de U-Boot qui s&#8217;occupe du chargement de l&#8217;image noyau depuis la flash NAND en RAM</li>
<li>Décompression du noyau et démarrage de celui-ci</li>
<li>Montage du système de fichiers racine puis passage à INIT</li>
<li>Fin de l&#8217;initialisation : &#8220;UserLand&#8221; : vos applications</li>
</ol>
<p>Le chargeur de la puce ne m&#8217;est pas accessible donc pas d&#8217;optimisation la dessus ! Nous allons donc commencer par U-Boot. Mais pour optimiser le temps de chargement, il faut pouvoir mesurer le temps de chaque étape. J&#8217;ai choisi d&#8217;utiliser GrabSerial (présentation et installation <a href="http://elinux.org/Grabserial" target="_blank">ici</a>) pour faire les mesures de temps car il n&#8217;apporte pas de surcharge du coté système embarqué. GrabSerial utilise Python et necessite un module python à installer avec la commande suivante:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code49'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75849"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p758code49"><pre class="text" style="font-family:monospace;">root@casimir:~# aptitude install python-serial</pre></td></tr></table></div>

<p>Il faut ensuite télécharger le script python GrabSerial, le rendre exécutable (chmod +x) et enfin le lancer avec une commande du style:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code50'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75850"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p758code50"><pre class="text" style="font-family:monospace;">root@casimir:~# ./grabserial.py -v -t -m &quot;Starting kernel.*&quot;</pre></td></tr></table></div>

<p>qui va permettre d&#8217;intercepter les caractères arrivant sur la voie série ttyS0 et qui remet à 0 le compteur de temps lorsque &#8220;Starting kernel&#8221; apparaitra&#8230; Vous avez un exemple d&#8217;une trace issu de GrabSerial en fin d&#8217;article sur la <a href="http://innovelectronique.fr/2011/08/01/personnalisation-de-la-carte-tq6410-noyau-linux-et-systeme-de-fichiers-racine-emdebian-squeeze/" target="_blank">personnalisation de la carte TQ6410</a>.</p>
<h1>Optimisation de U-Boot</h1>
<p>Nous allons commencer par les optimisations simples (sous entendu sans recompilation du code) :</p>
<ol>
<li>Le &#8216;u-Boot&#8217; fourni avec la carte attend pendant 3s que vous tapiez sur une touche pour arrêter le chargement. On peut réduire ce temps à &#8216;0s&#8217; et ainsi gagner 3s mais vous n&#8217;aurez plus accès au menu de U-Boot. Il faudra alors reflasher le U-Boot d&#8217;origine depuis la flash NOR. Pour fixer ce temps à &#8216;0&#8242;, quitter le menu de U-Boot pour passer à l’interpréteur de commande : Quit to shell (lettre &#8216;q&#8217;) puis tapez &#8217;set bootdelay 0&#8242;. Si vous souhaitez conserver cette option, tapez &#8217;saveenv&#8217;.</li>
<li>Vérifiez que la vitesse de transmission du port série est à 115200. Toujours depuis le shell de U-Boot, tapez &#8216;printenv&#8217; puis vérifiez que la variable &#8216;baudrate&#8217; est à 115200 sinon la fixer avec &#8217;set baudrate 115200&#8242;.</li>
<li>U-Boot effectue une somme de contrôle sur le noyau qu&#8217;il charge. On peut désactiver cette option en tapant &#8217;set verify no&#8217;.</li>
<li>Toutes les sorties vers la voie série ralentissent énormément U-Boot. Pour désactiver les sorties il faut que le code soit compiler avec &#8216;#define CONFIG_SILENT_CONSOLE&#8217; et mettre à 1 la variable silent: &#8217;set silent 1&#8242;. J&#8217;ai essayé de recompiler le code fourni avec la carte avec l&#8217;option ci-dessus mais cela n&#8217;a rien changé sur le fait qu&#8217;il m&#8217;affiche les messages de lecture de la flash NAND lors du chargement du noyau. Il faut donc que je trouve dans le code ou est ce &#8220;printf&#8221; qui ralentit énormément la lecture en flash NAND&#8230;</li>
<li>Par défaut si on ne touche pas au menu de U-Boot, au bout de 3s, la commande &#8216;bootcmd&#8217; est exécutée. Or cette commande lit  0&#215;500000 octets soit 5 242 880 octets avec le U-Boot fourni par le vendeur de la carte. Ceci même si votre noyau fait 1,2Mo. Il faut donc modifier cette commande pour ne lire que ce qui est nécessaire en flash NAND pour démarrer le noyau. Par exemple, un des noyaux (uImage) que j&#8217;ai compilé pour cette plateforme fait 1 246 156 octets qu&#8217;il faut aligner sur la flash NAND (padder en anglais) sur des secteurs de 2 048 octets donc on fait 1 246 156/2 048 = 608,47. On prend 609+1=610 et on remultiplie par 2048, on obtient 1 249 280 octets soit 0&#215;13 100 en hexadécimal. On tapera donc la commande suivante pour fixer &#8216;bootcmd&#8217; : set bootcmd &#8216;nand read.i c0008000 80000 13100; bootm c0008000&#8242;. On charge en RAM (0xc000800) à partir de l&#8217;adresse 0&#215;80000 de la flash NAND (adresse ou l&#8217;on télécharge  le noyau en flash avec la lettre &#8216;k&#8217; du menu) 0&#215;131000 octets. On gagne ainsi un temps précieux. Remarquez que si vous tapez la lettre &#8216;b&#8217; du menu, c&#8217;est toujours 5Mo qui seront lu depuis la flash car la commande est codé en &#8220;dur&#8221; dans le code.</li>
</ol>
<p>On obtient la trace suivante:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code51'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75851"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code" id="p758code51"><pre class="text" style="font-family:monospace;">[    0.000003]
[    0.289005]
[    0.289216] U-Boot 1.1.6 (Aug  5 2011 - 11:50:17) for TQ6410
[    0.293653]
[    0.293860]
[    0.294013] CPU:     S3C6410@532MHz
[    0.296218]          Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
[    0.303626] Board:   TQ6410
[    0.305115] DRAM:    128 MB
[    0.306488] Flash:   0 kB
[    0.307700] NAND:    256 MB
[    0.399982] In:      serial
[    0.401473] Out:     serial
[    0.402932] Err:     serial
[    0.483943] MAC: 08:90:90:90:90:90
[    0.486062] Hit any key to stop autoboot:  3  2  1  0
[    3.468708]
[    3.468897] NAND read: device 0 offset 0x80000, size 0x131000
[    3.473340]
[    3.473511] Reading data from 0x80000 --   0% complete.Reading data from 0x83000 --   1% complete.Reading data from 0x86000 --   2% complete.Reading data from 0x89000 --   3% complete.Reading data from 0x8c000 --   4% complete.Reading data from 0x8f000 --   5% complete.Reading data from 0x92000 --   6% complete.Reading data from 0x95000 --   7% complete.Reading data from 0x98000 --   8% complete.Reading data from 0x9b000 --   9% complete.Reading data from 0x9e000 --  10% complete.Reading data from 0xa1800 --  11% complete.Reading data from 0xa4800 --  12% complete.Reading data from 0xa7800 --  13% complete.Reading data from 0xaa800 --  14% complete.Reading data from 0xad800 --  15% complete.Reading data from 0xb0800 --  16% complete.Reading data from 0xb3800 --  17% complete.Reading data from 0xb6800 --  18% complete.Reading data from 0xb9800 --  19% complete.Reading data from 0xbc800 --  20% complete.Reading data from 0xc0000 --  21% complete.Reading data from 0xc3000 --  22% complete.Reading data from 0xc6000 --  23% complete.Reading data from 0xc9000 --  24% complete.Reading data from 0xcc000 --  25% complete.Reading data from 0xcf000 --  26% complete.Reading data from 0xd2000 --  27% complete.Reading data from 0xd5000 --  28% complete.Reading data from 0xd8000 --  29% complete.Reading data from 0xdb000 --  30% complete.Reading data from 0xde800 --  31% complete.Reading data from 0xe1800 --  32% complete.Reading data from 0xe4800 --  33% complete.Reading data from 0xe7800 --  34% complete.Reading data from 0xea800 --  35% complete.Reading data from 0xed800 --  36% complete.Reading data from 0xf0800 --  37% complete.Reading data from 0xf3800 --  38% complete.Reading data from 0xf6800 --  39% complete.Reading data from 0xf9800 --  40% complete.Reading data from 0xfd000 --  41% complete.Reading data from 0x100000 --  42% complete.Reading data from 0x103000 --  43% complete.Reading data from 0x106000 --  44% complete.Reading data from 0x109000 --  45% complete.Reading data from 0x10c000 --  46% complete.Reading data from 0x10f000 --  47% complete.Reading data from 0x112000 --  48% complete.Reading data from 0x115000 --  49% complete.Reading data from 0x118000 --  50% complete.Reading data from 0x11b800 --  51% complete.Reading data from 0x11e800 --  52% complete.Reading data from 0x121800 --  53% complete.Reading data from 0x124800 --  54% complete.Reading data from 0x127800 --  55% complete.Reading data from 0x12a800 --  56% complete.Reading data from 0x12d800 --  57% complete.Reading data from 0x130800 --  58% complete.Reading data from 0x133800 --  59% complete.Reading data from 0x136800 --  60% complete.Reading data from 0x13a000 --  61% complete.Reading data from 0x13d000 --  62% complete.Reading data from 0x140000 --  63% complete.Reading data from 0x143000 --  64% complete.Reading data from 0x146000 --  65% complete.Reading data from 0x149000 --  66% complete.Reading data from 0x14c000 --  67% complete.Reading data from 0x14f000 --  68% complete.Reading data from 0x152000 --  69% complete.Reading data from 0x155000 --  70% complete.Reading data from 0x158800 --  71% complete.Reading data from 0x15b800 --  72% complete.Reading data from 0x15e800 --  73% complete.Reading data from 0x161800 --  74% complete.Reading data from 0x164800 --  75% complete.Reading data from 0x167800 --  76% complete.Reading data from 0x16a800 --  77% complete.Reading data from 0x16d800 --  78% complete.Reading data from 0x170800 --  79% complete.Reading data from 0x173800 --  80% complete.Reading data from 0x177000 --  81% complete.Reading data from 0x17a000 --  82% complete.Reading data from 0x17d000 --  83% complete.Reading data from 0x180000 --  84% complete.Reading data from 0x183000 --  85% complete.Reading data from 0x186000 --  86% complete.Reading data from 0x189000 --  87% complete.Reading data from 0x18c000 --  88% complete.Reading data from 0x18f000 --  89% complete.Reading data from 0x192000 --  90% complete.Reading data from 0x195800 --  91% complete.Reading data from 0x198800 --  92% complete.Reading data from 0x19b800 --  93% complete.Reading data from 0x19e800 --  94% complete.Reading data from 0x1a1800 --  95% complete.Reading data from 0x1a4800 --  96% complete.Reading data from 0x1a7800 --  97% complete.Reading data from 0x1aa800 --  98% complete.Reading data from 0x1ad800 --  99% complete.Reading data from 0x1b0800 -- 100% complete.
[    4.672055]  1249280 bytes read: OK
[    4.678741] ## Booting image at c0008000 ...
[    4.679811]    Image Name:   Linux-2.6.28.6-IRIS-Turgot-O.Dar
[    4.684310]    Image Type:   ARM Linux Kernel Image (uncompressed)
[    4.686018]    Data Size:    1246092 Bytes =  1.2 MB
[    4.688032]    Load Address: 50008000
[    4.692227]    Entry Point:  50008000
[    4.999951] OK
[    5.000117]
[    5.000197] Starting kernel ...</pre></td></tr></table></div>

<p>J&#8217;ai laissé volontairement la &#8216;longuuuuue&#8217; chaine qui indique la progression de la lecture en flash. Je pense que cette sortie vers la voie série ralentit énormément le boot. Je recherche donc dans les codes sources comment supprimer cette sortie&#8230; Je viens de trouver ! C&#8217;est dans le fichiers drivers/nand/nand_util.c&#8230;faire une recherche avec &#8220;Reading&#8221; et commenter la ligne : printf(&#8221;\rReading data from&#8230;percent);.  Je recompile le tout et je fais un test avec et sans cette sortie avec GrabSerial:</p>
<ul>
<li>avec la sortie &#8220;Reading&#8230;&#8221; : 1,204s pour charger le noyau (1,2Mo) depuis la flash NAND</li>
<li>sans la sortie &#8220;Reading&#8230;.&#8221; : 0,832s pour charger le noyau (1,2Mo) depuis la flash NAND</li>
</ul>
<p><em>Conclusion</em> : prêt de 30% de temps de gagner ! Dans la plupart des cas limiter les sorties vers l&#8217;écran ou la voie série permet de gagner du temps (voir plus loin pour le noyau avec le &#8216;printk&#8217; et l&#8217;option &#8216;quiet&#8217;). J&#8217;obtiens un temps de 1,6s depuis le démarrage à froid jusqu&#8217;au message &#8216;Starting kernel&#8217; et 14,4s jusqu&#8217;à l&#8217;affichage du login avec un rootfs en ext3 sur carte SD.</p>
<h1>Optimisation du noyau Linux</h1>
<p>J&#8217;ai modifié la configuration de base fourni par le vendeur pour qu&#8217;elle corresponde à nos besoins. En clair moins vous mettez de &#8216;choses&#8217; dans votre noyau, plus celui-ci est petit et plus il charge vite. Actuellement j&#8217;ai gardé le nécessaire pour faire tourner la carte correctement, cependant comme je n&#8217;ai pas encore choisi le système de fichiers du &#8216;rootfs&#8217; j&#8217;ai gardé le support du ext3, de yaffs, de jffs2 avec tous les systèmes de compression et ubifs. Une fois que j&#8217;aurais décidé lequel je garde j&#8217;éliminerai les autres et je gagnerai du temps au boot. De plus afin d&#8217;avoir des indication de temps par le noyau j&#8217;ai compilé celui-ci avec le support du &#8220;printk&#8221;, on pourra l&#8217;éliminer par la suite.</p>
<p>Pour l&#8217;instant on peut appliquer des modifications à la ligne de commande du noyau Linux. Comme précédemment, limiter les sorties vers l&#8217;écran ou la voie série permet de gagner du temps. Donc la première chose à changer et de rajouter le paramètre &#8216;quiet&#8217;. Un petit test avec GrabSerial et on obtient :</p>
<ul>
<li>messages du noyau affichés : de &#8220;Starting kernel&#8221; au lancement de INIT : 2,255s</li>
<li>messages du noyau cachés :  de &#8220;Starting kernel&#8221; au lancement de INIT : 1,707s</li>
</ul>
<p><em>Conclusion</em>: on gagne 548ms rien qu&#8217;avec ce paramètre !</p>
<p>A chaque démarrage, on recalibre la durée d&#8217;une boucle appelée &#8216;loop_per_jiffy&#8217; ou LPJ associée au BogoMips. Or le noyau nous donne la valeur de la calibration pendant le boot. Il suffit donc de passer ce paramètre au noyau pour éviter cette calibration. Dans mon cas, la ligne qui nous interesse est la suivante:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code52'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75852"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p758code52"><pre class="text" style="font-family:monospace;">Calibrating delay loop... 353.89 BogoMIPS (lpj=884736)</pre></td></tr></table></div>

<p>A priori cette opération dure 110ms mais la sortie &#8216;printk&#8217; du noyau n&#8217;est sans doute pas assez précise. Faisons un test avec GrabSerial. J&#8217;obtiens:</p>
<ul>
<li>avec boucle de calibrage: de &#8220;Starting kernel&#8221; au lancement de INIT : 1,707s</li>
<li>sans boucle de calibrage: de &#8220;Starting kernel&#8221; au lancement de INIT : 1,599s</li>
</ul>
<p><em>Conclusion</em>: environ 110ms de gagner ! Dans les messages noyau on obtient:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code53'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75853"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p758code53"><pre class="text" style="font-family:monospace;">Calibrating delay loop (skipped) preset value.. 353.89 BogoMIPS</pre></td></tr></table></div>

<p>On obtient actuellement un temps de 13,184s pour l&#8217;arrivée jusqu&#8217;au login mais surtout on met 3,228s jusqu&#8217;à INIT.</p>
<p>La décompression du noyau au départ prend 560ms, ce qui est loin d&#8217;être négligeable. J&#8217;ai testé avec un noyau non compressé mais c&#8217;est plus défavorable donc il faudrait que la décompression soit plus rapide. Dans la version de mon noyau  (2.6.38), l&#8217;image est compressé avec ZLIB et je n&#8217;ai pas d&#8217;autres choix. Apparemment si vous pouvez choisir votre système de décompression, il faut prendre LZO !</p>
<h1>Choix du système de fichiers racine parmi ext3, JFFS2, YAFFS2 et UBIFS</h1>
<p>Pour continuer à optimiser le temps de boot, je me suis dit que l&#8217;on pouvait certainement gagner sur le temps de montage du rootfs. Pendant tous les tests précédents on monte le rootfs depuis une carte SD formatée en ext3. Le paramètre &#8216;rootwait&#8217; du noyau permet d&#8217;attendre le système de fichiers. Cette attente est donnée dans les messages du noyau, ici elle vaut (du message &#8216;Waiting for root device /dev/mmcblk0p1&#8230;&#8217; à &#8216;VFS: Mounted root (ext3 filesystem)&#8217;) 435ms.</p>
<p>Au boot 3 &#8220;pseudos&#8221; partitions sont créées aux adresses indiquées ci-dessous dans la flash NAND, on le voit avec les messages du noyau suivant:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code54'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75854"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p758code54"><pre class="text" style="font-family:monospace;">S3C NAND Driver, (c) 2008 Samsung Electronics
S3C NAND Driver is using hardware ECC.
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Creating 3 MTD partitions on &quot;NAND 256MiB 3,3V 8-bit&quot;:
0x00000000-0x00080000 : &quot;Bootloader&quot;
0x00080000-0x00580000 : &quot;Kernel&quot;
0x00580000-0x10000000 : &quot;File System&quot;</pre></td></tr></table></div>

<p>On va donc s&#8217;interresser à la troisième partition &#8220;File System&#8221; qui va contenir le système de fichiers racine. Comme on démarre actuellement sur la carte SD, on peut effacer sans problème cette &#8220;partition&#8221;. Pour cela vous devez disposer des outils de manipulation des Flashs NOR et NAND. Ceux-ci s&#8217;installent avec la commande suivante depuis le système embarqué et nous allons tester quelques commandes :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code55'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75855"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p758code55"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# aptitude install mtd-utils
root@TQ6410-Iris:~# mtdinfo /dev/mtd2
mtd2
Name:                           File System
Type:                           nand
Eraseblock size:                131072 bytes, 128.0 KiB
Amount of eraseblocks:          2004 (262668288 bytes, 250.5 MiB)
Minimum input/output unit size: 2048 bytes
Sub-page size:                  unknown
Bad blocks are allowed:         true
Device is writable:             true</pre></td></tr></table></div>

<p>On remarque bien que la flash NAND s&#8217;efface par blocs de 128Ko et que l&#8217;unité de base est de 2048octets.</p>
<h2>Système de fichiers JFFS2 sur flash NAND</h2>
<p>On va commencer par tester le système de fichiers JFFS2. Pour mémoire dans la configuration du noyau, j&#8217;ai activé toutes les méthodes de compression avec une préférence pour LZO (compression plus faible que ZLIB ou BZip2 mais vitesse de décompression trés rapide). On va donc initialiser cette partition pour qu&#8217;elle acceuille un système de fichiers JFFS2:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code56'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75856"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p758code56"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# flash_eraseall -j /dev/mtd2
Erasing 128 Kibyte @ 62c0000 -- 39 % complete. Cleanmarker written at 62c0000.
Skipping bad block at 0x062e0000
Erasing 128 Kibyte @ 8e60000 -- 56 % complete. Cleanmarker written at 8e60000.
Skipping bad block at 0x08e80000
Erasing 128 Kibyte @ 95e0000 -- 59 % complete. Cleanmarker written at 95e0000.
Skipping bad block at 0x09600000
Erasing 128 Kibyte @ fa80000 -- 100 % complete.Cleanmarker written at fa60000.</pre></td></tr></table></div>

<p>On remarque que la flash NAND a des erreurs. Le système de fichiers en tiendra compte ! On monte notre &#8220;pseudo&#8221; partition dans /mnt:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code57'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75857"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p758code57"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# mount -t jffs2 /dev/mtdblock2 /mnt
root@TQ6410-Iris:~# mount
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
rootfs on / type rootfs (rw)
/dev/mtdblock2 on /mnt type jffs2 (rw)
root@TQ6410-Iris:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
rootfs                1.9G  477M  1.4G  26% /
/dev/mtdblock2        251M  5.9M  245M   3% /mnt</pre></td></tr></table></div>

<p>Nous disposons donc d&#8217;un espace conséquent pour le stockage de notre système de fichiers racine (prés de 245Mo avant compression). Pour installer le système de fichiers racine dans cette espace, j&#8217;ai créé auparavant une archive tar.bz2 de mon système qui tourne actuellement sur la carte SD. Comment faire ? Trés simple, sur votre système de développement montez cette carte SD avec une commande du style : <em>mount -t auto /dev/sdd1 /mnt</em> puis créez l&#8217;archive avec <em>tar jcf rootfs-debian-squeeze-grip-for-TQ6410.tar.bz2 /mnt/*</em>. Vous obtenez alors une archive de votre système de fichiers racine (chez moi cette archive fait 22Mo) que vous allez copier sur la carte SD avec <em>cp rootfs-debian-squeeze-grip-for-TQ6410.tar.bz2 /mnt</em> pour ensuite le désarchiver vers la NAND Flash. Démontez votre carte SD avec umount /mnt. On admet que l&#8217;on reprend la suite des commandes ci-dessus et que vous disposez de l&#8217;archive à la racine de la carte SD <img src='http://innovelectronique.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> Au fait si vous n&#8217;arrivez pas à désarchivez l&#8217;archive c&#8217;est que vous n&#8217;avez probablement pas bzip2 d&#8217;installé&#8230;un petit <em>aptitude install bzip2</em> réglera l&#8217;affaire !</p>
<p>On désarchive donc notre système de fichiers racine vers /mnt qui représente le mtd2 de la flash NAND (attention soyez patient) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code58'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75858"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code" id="p758code58"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# cd /mnt
root@TQ6410-Iris:/mnt# tar jxf /debian-squeeze-grip-OD.tar.bz2 .
root@TQ6410-Iris:/mnt# ls /mnt
bin   dev  home  lost+found  mnt  proc  sbin     srv  tmp  var
boot  etc  lib   media       opt  root  selinux  sys  usr
root@TQ6410-Iris:/mnt# df -h
Filesystem            Size  Used Avail Use% Mounted on
rootfs                1.9G  477M  1.4G  26% /
/dev/mtdblock2        251M   42M  210M  17% /mnt
root@TQ6410-Iris:/mnt# du -h --max-depth=1 /mnt
3.9M    /mnt/bin
512     /mnt/dev
361K    /mnt/etc
7.3M    /mnt/lib
0       /mnt/mnt
0       /mnt/opt
0       /mnt/srv
0       /mnt/tmp
0       /mnt/sys
8.3M    /mnt/var
40M     /mnt/usr
0       /mnt/boot
0       /mnt/home
0       /mnt/proc
3.3M    /mnt/sbin
14K     /mnt/root
0       /mnt/media
0       /mnt/selinux
0       /mnt/lost+found
63M     /mnt</pre></td></tr></table></div>

<p>On vérifie le contenu de la flash NAND avec un &#8216;ls&#8217;. On regarde combien on a mangé de place (ici 42Mo) et combien on occupe effectivement de place (ici 63Mo). On travaille donc bien sur un système de fichiers compressé mais adapté au mémoire flash (c&#8217;est à dire que l&#8217;on réparti les écritures pour moyenner l&#8217;usure (<a href="http://fr.wikipedia.org/wiki/Wear_levelling" target="_blank">wear-levelling</a>)) et relativement résistant au coupure électrique brusque puisque journalisé ! Reste à savoir le temps de montage au boot. Redémarrez puis arrêtez U-Boot car il nous faut modifier la ligne de passage d&#8217;arguments au noyau (lettre &#8217;s&#8217;) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code59'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75859"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p758code59"><pre class="text" style="font-family:monospace;">console=ttySAC0,115200 root=/dev/mtdblock2 rootfstype=jffs2 init=/sbin/init quiet noswap lpj=884736</pre></td></tr></table></div>

<p>Je retire la carte SD puis on fait donc le test du temps de boot avec GrabSerial. J&#8217;obtiens un temps de 18,383s depuis la mise sous tension jusqu&#8217;a l&#8217;obtention du login. Mais ce n&#8217;est pas vraiment ce qui m&#8217;interesse. Il faut fouiller les messages du noyau pour tenter de repérer le temps de montage :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code60'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75860"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p758code60"><pre class="text" style="font-family:monospace;">[21474536.705000] TCP cubic registered
[21474536.705000] NET: Registered protocol family 17
[21474536.705000] VFP support v0.3: implementor 41 architecture 1 part 20 varia5
[21474536.710000] s3c2410-rtc s3c2410-rtc: setting system clock to 2011-08-08 2)
[21474539.275000] s3c64xx_clk_doutmpll_get_rate: parent is 532000000
[21474539.560000] VFS: Mounted root (jffs2 filesystem).
[21474539.560000] Freeing init memory: 96K</pre></td></tr></table></div>

<p>On passe de 36.71s à 39.275s or ce n&#8217;est pas la synchronisation de l&#8217;horloge système avec la RTC qui prend aussi longtemps. J&#8217;estime donc que le temps de montage est 39.56 - 36.71 = 2,85s pour monter les 250Mo de cette partition. Si vous cherchez un peu sur Internet vous verrez que le reproche fait à JFFS2 est son temps de montage or ici il est loin d&#8217;être catastrophique&#8230;bon j&#8217;ai triché un peu :-). Il existe un paramètre pour le système de fichiers JFFS2 qui permet de monter beaucoup plus vite le système de fichiers dans le noyau :  [*] JFFS2 summary support. J&#8217;ai fait le test sans ce paramètre et le temps de montage sur la même partition est alors de 14s ! Bon on s&#8217;éloigne de notre but : démarrez plus vite mais on s&#8217;est rapproché de coté &#8216;clair&#8217; de la force : on a un système rootfs sur une flash NAND et pas sur une SD.</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-jffs2.png" rel="lightbox[758]"><img class="aligncenter size-full wp-image-772" title="Paramètres noyau pour JFFS2" src="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-jffs2.png" alt="Paramètres noyau pour JFFS2" width="430" height="380" /></a></p>
<p><em>Conclusion</em>: globalement on va moins vite mais on s&#8217;est rapproché d&#8217;un &#8216;vrai&#8217; système embarqué&#8230;de plus la compression, la jounalisation et le wear-levelling sont interessants.</p>
<h2>Système de fichiers YAFFS2 sur flash NAND</h2>
<p>On va recommencer un peu la même chose que précédemment avec un système de fichiers YAFFS2. Cette fois-ci je commence par la capture d&#8217;écran des paramètres noyau pour le système de fichiers YAFFS2:</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-yaffs2.png" rel="lightbox[758]"><img class="aligncenter size-full wp-image-775" title="Paramètres noyau pour le système de fichier YAFFS2" src="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-yaffs2.png" alt="Paramètres noyau pour le système de fichier YAFFS2" width="520" height="243" /></a>Donc on redémarre sur notre carte SD pour pouvoir manipuler sans problème la flash NAND. On enchaine donc les commandes suivantes:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code61'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75861"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
</pre></td><td class="code" id="p758code61"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# flash_eraseall /dev/mtd2
Erasing 128 Kibyte @ 62c0000 -- 39 % complete.
Skipping bad block at 0x062e0000
Erasing 128 Kibyte @ 8e60000 -- 56 % complete.
Skipping bad block at 0x08e80000
Erasing 128 Kibyte @ 95e0000 -- 59 % complete.
Skipping bad block at 0x09600000
Erasing 128 Kibyte @ fa80000 -- 100 % complete.
root@TQ6410-Iris:~# mount -t yaffs2 /dev/mtdblock2 /mnt
[21474611.890000] yaffs: dev is 32505858 name is &quot;mtdblock2&quot;
[21474611.890000] yaffs: passed flags &quot;&quot;
[21474611.895000] yaffs: Attempting MTD mount on 31.2, &quot;mtdblock2&quot;
[21474612.095000] yaffs_read_super: isCheckpointed 0
root@TQ6410-Iris:~# mount
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
rootfs on / type rootfs (rw)
/dev/mtdblock2 on /mnt type yaffs2 (rw)
root@TQ6410-Iris:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
rootfs                1.9G  477M  1.4G  26% /
/dev/mtdblock2        251M  1.5M  249M   1% /mnt
root@TQ6410-Iris:~# cd /mnt
root@TQ6410-Iris:/mnt# tar jxf /debian-squeeze-grip-OD.tar.bz2 .
root@TQ6410-Iris:/mnt# ls /mnt
bin   dev  home  lost+found  mnt  proc  sbin     srv  tmp  var
boot  etc  lib   media       opt  root  selinux  sys  usr
root@TQ6410-Iris:/mnt# df -h
Filesystem            Size  Used Avail Use% Mounted on
rootfs                1.9G  477M  1.4G  26% /
/dev/mtdblock2        251M   81M  170M  33% /mnt
root@TQ6410-Iris:/mnt# du -h --max-depth=1 /mnt
532K    /mnt/etc
2.0K    /mnt/boot
18K     /mnt/root
2.0K    /mnt/home
2.0K    /mnt/mnt
2.0K    /mnt/srv
41M     /mnt/usr
3.3M    /mnt/sbin
2.0K    /mnt/tmp
2.0K    /mnt/opt
2.0K    /mnt/selinux
2.0K    /mnt/media
3.9M    /mnt/bin
8.4M    /mnt/var
2.0K    /mnt/proc
92K     /mnt/dev
2.0K    /mnt/sys
7.3M    /mnt/lib
2.0K    /mnt/lost+found
64M     /mnt</pre></td></tr></table></div>

<p>Quelques remarques sur ce qui précède : on efface d&#8217;abord la flash NAND, puis on monte cette partition en YAFFS2, on voit que trés peu de place est occupé au montage (à peine 1,5Mo). On désarchive le &#8216;rootfs&#8217;. Puis on regarde la place occupée sur le support : prés de 80Mo !! sur 64Mo effectif&#8230;on perd donc beaucoup de bloc mémoire. Le système de fichiers n&#8217;est pas compressé. On redémarre sur ce système de fichier avec les paramètres suivants:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code62'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75862"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p758code62"><pre class="text" style="font-family:monospace;">console=ttySAC0,115200 root=/dev/mtdblock2 rootfstype=yaffs2 init=/sbin/init quiet noswap lpj=884736</pre></td></tr></table></div>

<p>A nouveau on regarde ce que ça donne au point de vue temps de boot avec GrabSerial.  J&#8217;obtiens un temps de 13,215s depuis la mise sous tension jusqu’à  l&#8217;obtention du login. Ce n&#8217;est pas mal du tout puisque l&#8217;on est au même niveau que le boot sur la SD en ext3. Fouillons les messages du noyau pour tenter de repérer le temps de  montage :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code63'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75863"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p758code63"><pre class="text" style="font-family:monospace;">[21474536.710000] yaffs: dev is 32505858 name is &quot;mtdblock2&quot;
[21474536.710000] yaffs: passed flags &quot;&quot;
[21474536.710000] yaffs: Attempting MTD mount on 31.2, &quot;mtdblock2&quot;
[21474536.960000] yaffs: restored from checkpoint
[21474536.960000] yaffs_read_super: isCheckpointed 1
[21474536.960000] VFS: Mounted root (yaffs2 filesystem).</pre></td></tr></table></div>

<p>On obtient un temps de 36.96 - 36.71 = 250ms ce qui est assez remarquable&#8230;à moins que je me sois trompé quelque part mais là je vois pas où car j&#8217;ai suivi la même procédure que pour le JFFS2.</p>
<p><em>Conclusion</em>: on est au même niveau que la carte SD en ext3 mais avec un système de fichier pour flash NAND journalisé. On est aussi plus &#8217;système embarqué&#8217;. Le seul souci c&#8217;est qu&#8217;il ne compresse pas à la volée. Je n&#8217;ai pas cherché si cela est possible&#8230;En tout cas cela semble être un bon choix comme futur système de fichiers pour notre système.</p>
<h2>Système de fichiers UBIFS sur flash NAND</h2>
<p>C&#8217;est sans doute le système de fichiers le plus compliqué à mettre en place avec une méthode identique aux précédents. Les paramètres du noyau sont les suivants:</p>
<p style="text-align: center;"><a href="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-ubi.png" rel="lightbox[758]"><img class="alignnone size-full wp-image-785" title="Paramètres Noyau pour UBI" src="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-ubi.png" alt="Paramètres Noyau pour UBI" width="564" height="148" /></a></p>
<p style="text-align: center;"><a href="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-ubifs.png" rel="lightbox[758]"><img class="alignnone size-full wp-image-786" title="Paramètres Noyau pour UBIFS" src="http://innovelectronique.fr/wp-content/uploads/2011/08/capture-decran-ubifs.png" alt="Paramètres Noyau pour UBIFS" width="295" height="150" /></a></p>
<p>Pour mémoire on travaille sur la MTD2 qui doit contenir le rootfs.On va donc commencer par effacer la flash NAND puis formater le MTD avec ubiformat:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code64'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75864"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code" id="p758code64"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# flash_eraseall /dev/mtd2
Erasing 128 Kibyte @ 62c0000 -- 39 % complete.
Skipping bad block at 0x062e0000
Erasing 128 Kibyte @ 8e60000 -- 56 % complete.
Skipping bad block at 0x08e80000
Erasing 128 Kibyte @ 95e0000 -- 59 % complete.
Skipping bad block at 0x09600000
Erasing 128 Kibyte @ fa80000 -- 100 % complete.
root@TQ6410-Iris:~# ubiformat /dev/mtd2
ubiformat: warning!: your MTD system is old and it is impossible to detect sub-page size. Use -s to get rid of this warning
ubiformat: assume sub-page to be 2048
ubiformat: mtd2 (nand), size 262668288 bytes (250.5 MiB), 2004 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 2003 -- 100 % complete
ubiformat: 2001 eraseblocks have valid erase counter, mean value is 0
ubiformat: bad eraseblocks: 791, 1140, 1200
ubiformat: formatting eraseblock 2003 -- 100 % complete</pre></td></tr></table></div>

<p>J&#8217;essaye alors &#8220;d&#8217;attacher&#8221; ce mtd au système (paramètres -m 2 ci-dessous) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code65'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75865"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p758code65"><pre class="text" style="font-family:monospace;">oot@TQ6410-Iris:~# ubiattach /dev/ubi_ctrl -m 2
[  748.290000] UBI: attaching mtd2 to ubi0
[  748.290000] UBI: physical eraseblock size:   131072 bytes (128 KiB)
[  748.295000] UBI: logical eraseblock size:    129024 bytes
[  748.300000] UBI: smallest flash I/O unit:    2048
[  748.305000] UBI: sub-page size:              512
[  748.310000] UBI: VID header offset:          512 (aligned 512)
[  748.315000] UBI: data offset:                2048
[  748.330000] UBI error: validate_ec_hdr: bad VID header offset 2048, expected 512
[  748.330000] UBI error: validate_ec_hdr: bad EC header
[  748.335000] UBI error: ubi_io_read_ec_hdr: validation failed for PEB 0
ubiattach: error!: cannot attach mtd2
           error 22 (Invalid argument)</pre></td></tr></table></div>

<p>Bon il y a un soucis&#8230;Aprés une petite recherche sur internet, je trouve la réponse sur ce site : <a href="http://www.linux-mtd.infradead.org/faq/ubifs.html#L_mount_ubifs">http://www.linux-mtd.infradead.org/faq/ubifs.html#L_mount_ubifs</a>. Il faut reformatter la MTD en précisant la taille des &#8220;sous-pages&#8221; puis on retente d&#8217;attacher :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code66'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75866"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code" id="p758code66"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# ubiformat /dev/mtd2 -s 512
ubiformat: mtd2 (nand), size 262668288 bytes (250.5 MiB), 2004 eraseblocks of 131072 bytes (128.0 KiB), min. I/O size 2048 bytes
libscan: scanning eraseblock 2003 -- 100 % complete
ubiformat: 2001 eraseblocks have valid erase counter, mean value is 1
ubiformat: bad eraseblocks: 791, 1140, 1200
ubiformat: warning!: VID header and data offsets on flash are 2048 and 4096, which is different to requested offsets 512 and 2048
ubiformat: use new offsets 512 and 2048? (yes/no)  yes
ubiformat: use offsets 512 and 2048
ubiformat: formatting eraseblock 2003 -- 100 % complete
root@TQ6410-Iris:~# ubiattach /dev/ubi_ctrl -m 2
[ 1443.140000] UBI: attaching mtd2 to ubi0
[ 1443.140000] UBI: physical eraseblock size:   131072 bytes (128 KiB)
[ 1443.145000] UBI: logical eraseblock size:    129024 bytes
[ 1443.150000] UBI: smallest flash I/O unit:    2048
[ 1443.155000] UBI: sub-page size:              512
[ 1443.160000] UBI: VID header offset:          512 (aligned 512)
[ 1443.165000] UBI: data offset:                2048
[ 1444.270000] UBI: attached mtd2 to ubi0
[ 1444.270000] UBI: MTD device name:            &quot;File System&quot;
[ 1444.275000] UBI: MTD device size:            250 MiB
[ 1444.280000] UBI: number of good PEBs:        2001
[ 1444.285000] UBI: number of bad PEBs:         3
[ 1444.290000] UBI: max. allowed volumes:       128
[ 1444.295000] UBI: wear-leveling threshold:    4096
[ 1444.300000] UBI: number of internal volumes: 1
[ 1444.305000] UBI: number of user volumes:     0
[ 1444.305000] UBI: available PEBs:             1977
[ 1444.310000] UBI: total number of reserved PEBs: 24
[ 1444.315000] UBI: number of PEBs reserved for bad PEB handling: 20
[ 1444.320000] UBI: max/mean erase counter: 2/2
[ 1444.345000] UBI: background thread &quot;ubi_bgt0d&quot; started, PID 1727
UBI device number 0, total 2001 LEBs (258177024 bytes, 246.2 MiB), available 1977 LEBs (255080448 bytes, 243.3 MiB), LEB size 129024 bytes (126.0 KiB)</pre></td></tr></table></div>

<p>On vient d&#8217;attacher un périphérique &#8216;ubi0&#8242; à notre système, il faut maintenant créer un volume sur celui-ci (le paramètre &#8216;-m&#8217; permet d&#8217;utiliser la totalité de l&#8217;espace disponible dans &#8216;ubi0&#8242; et -N spécifie le nom : ici &#8216;rootfs&#8217; qui sera utilisé plus tard):</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code67'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75867"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code" id="p758code67"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# ubimkvol -h
ubimkvol version 1.0 - a tool to create UBI volumes.
&nbsp;
Usage: ubimkvol &lt;UBI device node file name&gt; [-h] [-a &lt;alignment&gt;] [-n &lt;volume ID&gt;] [-N &amp;lt;name&amp;gt;]
                        [-s &amp;lt;bytes&amp;gt;] [-S &amp;lt;LEBs&amp;gt;] [-t &amp;lt;static|dynamic&amp;gt;] [-V] [-m]
                        [--alignment=&amp;lt;alignment&amp;gt;][--vol_id=&amp;lt;volume ID&amp;gt;] [--name=&amp;lt;name&amp;gt;]
                        [--size=&amp;lt;bytes&amp;gt;] [--lebs=&amp;lt;LEBs&amp;gt;] [--type=&amp;lt;static|dynamic&amp;gt;] [--help]
                        [--version] [--maxavsize]
&nbsp;
Example: ubimkvol /dev/ubi0 -s 20MiB -N config_data - create a 20 Megabytes volume
         named &quot;config_data&quot; on UBI device /dev/ubi0.
&nbsp;
-a, --alignment=&amp;lt;alignment&amp;gt;   volume alignment (default is 1)
-n, --vol_id=&amp;lt;volume ID&amp;gt;      UBI volume ID, if not specified, the volume ID
                              will be assigned automatically
-N, --name=&amp;lt;name&amp;gt;             volume name
-s, --size=&amp;lt;bytes&amp;gt;            volume size volume size in bytes, kilobytes (KiB)
                              or megabytes (MiB)
-S, --lebs=&amp;lt;LEBs count&amp;gt;       alternative way to give volume size in logical
                              eraseblocks
-m, --maxavsize               set volume size to maximum available size
-t, --type=&amp;lt;static|dynamic&amp;gt;   volume type (dynamic, static), default is dynamic
-h, -?, --help                print help message
-V, --version                 print program version
&nbsp;
The following is a compatibility option which is deprecated, do not use it
-d, --devn=&amp;lt;devn&amp;gt;             UBI device number - may be used instead of the UBI
                              device node name in which case the utility assumes
                              that the device node is &quot;/dev/ubi&amp;lt;devn&amp;gt;&quot;
root@TQ6410-Iris:~# ubimkvol /dev/ubi0 -N rootfs -m
Set volume size to 255080448
Volume ID 0, size 1977 LEBs (255080448 bytes, 243.3 MiB), LEB size 129024 bytes (126.0 KiB), dynamic, name &quot;rootfs&quot;, alignment 1</pre></td></tr></table></div>

<p>On regarde si &#8216;udev&#8217; a créé les périphériques concernés dans /dev:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code68'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75868"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p758code68"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# ls /dev/ubi*
/dev/ubi0  /dev/ubi0_0  /dev/ubi_ctrl</pre></td></tr></table></div>

<p>On est prêt à monter ce périphérique dans notre système et prendre quelques renseignements dessus:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code69'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75869"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code" id="p758code69"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# mount -t ubifs ubi0:rootfs /mnt
[ 2589.845000] UBIFS: default file-system created
[ 2589.950000] UBIFS: mounted UBI device 0, volume 0, name &quot;rootfs&quot;
[ 2589.950000] UBIFS: file system size:   253532160 bytes (247590 KiB, 241 MiB, 1965 LEBs)
[ 2589.955000] UBIFS: journal size:       12644352 bytes (12348 KiB, 12 MiB, 98 LEBs)
[ 2589.960000] UBIFS: media format:       4 (latest is 4)
[ 2589.965000] UBIFS: default compressor: LZO
[ 2589.970000] UBIFS: reserved for root:  5182151 bytes (5060 KiB)
root@TQ6410-Iris:~# mount
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
rootfs on / type rootfs (rw)
ubi0:rootfs on /mnt type ubifs (rw)
root@TQ6410-Iris:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
rootfs                1.9G  477M  1.4G  26% /
ubi0:rootfs           227M     0  223M   0% /mnt</pre></td></tr></table></div>

<p>On continue donc comme les autres systèmes de fichiers. On désarchive le rootfs dans /mnt et on regarde la place occupé.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code70'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75870"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code" id="p758code70"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# cd /mnt
root@TQ6410-Iris:/mnt# tar jxf /debian-squeeze-grip-OD.tar.bz2 .
root@TQ6410-Iris:/mnt# df -h
Filesystem            Size  Used Avail Use% Mounted on
rootfs                1.9G  477M  1.4G  26% /
ubi0:rootfs           227M   47M  176M  21% /mnt
root@TQ6410-Iris:/mnt# du -h --max-depth=1 /mnt
4.0M    /mnt/bin
4.0K    /mnt/dev
896K    /mnt/etc
8.0M    /mnt/lib
0       /mnt/mnt
0       /mnt/opt
0       /mnt/srv
0       /mnt/tmp
0       /mnt/sys
11M     /mnt/var
48M     /mnt/usr
0       /mnt/boot
0       /mnt/home
0       /mnt/proc
3.5M    /mnt/sbin
24K     /mnt/root
0       /mnt/media
0       /mnt/lost+found
0       /mnt/selinux
75M     /mnt</pre></td></tr></table></div>

<p>La compression utilisée ici est LZO. On peut la changer en le spécifiant sur la commande mount. On a bien affaire à un système de fichiers compressés 47Mo utilisé sur 227Mo disponible et 75Mo de fichiers réels. Notez au passage que c&#8217;est un peu moins bien que JFFS2. On va pouvoir tester le démarrage sur ce système de fichier. Il faut encore une fois modifié la ligne d&#8217;arguments passé au noyau par U-Boot:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code71'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75871"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p758code71"><pre class="text" style="font-family:monospace;">console=ttySAC0,115200 ubi.mtd=2 root=ubi0:rootfs rootfstype=ubifs init=/sbin/init quiet noswap lpj=884736</pre></td></tr></table></div>

<p>A nouveau on regarde ce que ça donne au point de vue temps de boot avec  GrabSerial.  Fouillons les messages du  noyau pour tenter de repérer le temps de  montage :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p758code72'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p75872"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code" id="p758code72"><pre class="text" style="font-family:monospace;">[21474536.690000] UBI: attaching mtd2 to ubi0
[21474536.690000] UBI: physical eraseblock size:   131072 bytes (128 KiB)
[21474536.690000] UBI: logical eraseblock size:    129024 bytes
[21474536.690000] UBI: smallest flash I/O unit:    2048
[21474536.690000] UBI: sub-page size:              512
[21474536.690000] UBI: VID header offset:          512 (aligned 512)
[21474536.690000] UBI: data offset:                2048
[21474537.760000] UBI: attached mtd2 to ubi0
[21474537.760000] UBI: MTD device name:            &quot;File System&quot;
[21474537.760000] UBI: MTD device size:            250 MiB
[21474537.760000] UBI: number of good PEBs:        2001
[21474537.760000] UBI: number of bad PEBs:         3
[21474537.760000] UBI: max. allowed volumes:       128
[21474537.760000] UBI: wear-leveling threshold:    4096
[21474537.760000] UBI: number of internal volumes: 1
[21474537.760000] UBI: number of user volumes:     1
[21474537.760000] UBI: available PEBs:             0
[21474537.760000] UBI: total number of reserved PEBs: 2001
[21474537.760000] UBI: number of PEBs reserved for bad PEB handling: 20
[21474537.760000] UBI: max/mean erase counter: 3/2
...
[21474537.915000] UBIFS: mounted UBI device 0, volume 0, name &quot;rootfs&quot;
[21474537.915000] UBIFS: file system size:   253532160 bytes (247590 KiB, 241 Mi
B, 1965 LEBs)
[21474537.915000] UBIFS: journal size:       12644352 bytes (12348 KiB, 12 MiB,
98 LEBs)
[21474537.915000] UBIFS: media format:       4 (latest is 4)
[21474537.915000] UBIFS: default compressor: LZO
[21474537.915000] UBIFS: reserved for root:  5182151 bytes (5060 KiB)
[21474537.920000] VFS: Mounted root (ubifs filesystem).</pre></td></tr></table></div>

<p>On remarque qu&#8217;il y a deux parties distinctes dans les message du noyau: la partie association du MTD avec le système UBI qui prend 37.76-36.69=1,07s et le montage du système de fichiers UBIFS qui prend 0,005s. Pour comparer aux autres systèmes de fichiers, le temps de démarrage global est de 16,8s. C&#8217;est donc un peu plus lent que YAFFS2 et du même niveau que JFFS2. Cependant UBI et UBIFS semble être promis à un bel avenir comme on peut le voir sur ces<a href="http://elinux.org/Flash_Filesystem_Benchmarks_2.6.38"> tests</a>.</p>
<p><em>Conclusion</em>: c&#8217;est un bon compromis entre yaffs2 et jffs2. De plus il semble que ce système se développe dans les noyaux récents. De plus il a de trés bonne performance en lecture/écriture par rapport à YAFFS2. La mise en oeuvre est juste un peu plus délicate&#8230;.</p>
<h2>Conclusion sur les systèmes de fichiers</h2>
<p>Pendant la phase de développement, je dirais que le plus simple est de travailler avec une carte SD : c&#8217;est pas cher, vous avez des capacités énormes mais &#8220;ca fait pas embarqué&#8221; comme dirais Denis Bodor dans ces articles. Au niveau du choix du système de fichiers sur la flash NAND il faudra tester à l&#8217;utilisation YAFFS2 et UBIFS. YAFFS2 a pour lui l&#8217;ancienneté et une trés bonne stabilité, UBI quand à lui est plus récent et évolue encore assez fortement.</p>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2011/08/09/optimisation-du-temps-de-boot-et-choix-du-systeme-de-fichiers-parmi-ext3-jffs2-yaffs2-et-ubifs-pour-le-rootfs-de-la-carte-tq6410/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Personnalisation de la carte TQ6410 (noyau Linux et système de fichiers racine emDebian Squeeze)</title>
		<link>http://innovelectronique.fr/2011/08/01/personnalisation-de-la-carte-tq6410-noyau-linux-et-systeme-de-fichiers-racine-emdebian-squeeze/</link>
		<comments>http://innovelectronique.fr/2011/08/01/personnalisation-de-la-carte-tq6410-noyau-linux-et-systeme-de-fichiers-racine-emdebian-squeeze/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 11:22:33 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[Linux Embarqué]]></category>

		<category><![CDATA[emdebian]]></category>

		<category><![CDATA[QT]]></category>

		<category><![CDATA[TQ6410]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=706</guid>
		<description><![CDATA[Après la découverte de cette carte, nous allons passer à l&#8217;étape de personnalisation. Nous souhaitons faire de cette carte une plateforme de développement générique pour développer des applications en C/C++ et QT. Dans un proche avenir cela peut être complètement autre chose (Python et GTK+ par exemple). Aussi pour avoir une base solide et facilement [...]]]></description>
			<content:encoded><![CDATA[<p>Après la découverte de cette carte, nous allons passer à l&#8217;étape de personnalisation. Nous souhaitons faire de cette carte une plateforme de développement générique pour développer des applications en C/C++ et QT. Dans un proche avenir cela peut être complètement autre chose (Python et GTK+ par exemple). Aussi pour avoir une base solide et facilement maintenable, nous allons installer la version embarqué de la distribution Debian : emDebian. Par la même occasion, nous allons recompiler le noyau pour l&#8217;adapter à nos besoins (pas de multimédia par exemple). Ces différentes étapes sont décrites dans la suite de l&#8217;article&#8230;<span id="more-706"></span></p>
<h1>Lectures enrichissantes voire obligatoires !!</h1>
<p>Non vous n&#8217;êtes pas seul, des dizaines de personnes sur Internet ont déjà rédigé des tutoriaux sur la mise en place d&#8217;un noyau personnalisé ou la réalisation d&#8217;un &#8216;rootfs&#8217;. Pour ma part je livre les liens qui m&#8217;ont réellement permis d&#8217;avancer sur cette carte :</p>
<ul>
<li>Le <a href="http://www.esky-sh.com/bbs/index.php" target="_blank">forum du vendeur de la carte</a> et en particulier les sections S3C6410, S3C2440 et Linux,</li>
<li>Les <a href="http://www.friendlyarm.net/forum/0" target="_blank">forums du site FriendlyARM</a>,</li>
<li>Le blog de Bill (<a href="http://bill.station51.net/" target="_blank">Bill&#8217;s Blog</a>) : très bon &#8216;HowTo&#8217; et un excellent forum. Bill se définit lui même comme un &#8216;installeur&#8217; et pas comme un &#8216;programmeur&#8217;,</li>
<li>Le site de la distribution <a href="http://www.emdebian.org/" target="_blank">Emdebian</a> : Debian facilite énormément la création d&#8217;un &#8216;rootfs&#8217; pour l&#8217;embarqué !,</li>
<li>Un bon tutoriel sur la mise en place d&#8217;<a href="http://code.google.com/p/mini6410-debian/wiki/Tutorial#Tutorial_Mini6410_Debian/Emdebian" target="_blank">emdebian sur une mini6410</a> ainsi que le site voisin pour une <a href="http://code.google.com/p/mini2440/wiki/Emdebian" target="_blank">mini2440</a>,</li>
<li>Le site <a href="http://boundarydevices.com/blogs/debian-in-more-depth-adding-touch-support" target="_blank">BoundaryDevice</a> qui m&#8217;a permis de régler une bonne fois pour toute mes problèmes de calibration du touchscreen sous Xorg !</li>
<li>Et enfin je réserve la place d&#8217;honneur pour l&#8217;article en FRANÇAIS qui m&#8217;a donné envie de travailler avec cette carte : l&#8217;article de <a href="http://www.lefinnois.net" target="_blank">Denis Bodor</a> dans le magazine <a href="http://www.ed-diamond.com/feuille_os1/index.html" target="_blank">OpenSilicium N°1</a> : Plateforme FriendlyARM Mini2440</li>
</ul>
<h1>Les étapes de la personnalisation de la carte TQ6410</h1>
<ol>
<li>Installation d&#8217;une chaine de cross-compilation sur une station de développement fonctionnant de préférence sous GNU/Linux Debian Squeeze,</li>
<li>Compilation et installation d&#8217;un &#8216;bootloader&#8217; : dans notre cas U-Boot,</li>
<li>Compilation et installation d&#8217;un noyau linux personnalisé,</li>
<li>Génération, installation et configuration d&#8217;un système de fichiers racine (rootfs en anglais). Dans notre cas, ce rootfs sera basé sur emdebian squeeze Grip,</li>
<li>Développement d&#8217;applications sur la plateforme&#8230;</li>
</ol>
<h2>1. Installation d&#8217;une chaine de cross-compilation</h2>
<p>Avant de poursuivre, on considère que votre machine de développement est fonctionnelle et que vous avez un minimum de connaissance d&#8217;un système GNU/Linux. La distribution choisie est, comme indiqué ci-dessus, une debian 6.0 (Squeeze). La carte est équipée d&#8217;un <a href="http://fr.wikipedia.org/wiki/System_on_Chip" target="_blank">SoC</a> <a href="http://www.samsung.com/global/business/semiconductor/productInfo.do?fmly_id=835&amp;partnum=S3C6410" target="_blank">Samsung S3C6410</a>. C&#8217;est donc un cœur ARM11 qui équipe cette puce. La chaine de compilation sera donc une chaine <a href="http://en.wikipedia.org/wiki/EABI#EABI" target="_blank">arm-linux-gnueabi</a>. Pour installer cette chaine de cross compilation, il faut tout d&#8217;abord importer les clés des archives emdebian :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code98'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p70698"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p706code98"><pre class="text" style="font-family:monospace;">root@casimir:~# aptitude install emdebian-archive-keyring</pre></td></tr></table></div>

<p>il faut ensuite rajouter le dépôt suivant et mettre à jour la base des paquets:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code99'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p70699"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p706code99"><pre class="text" style="font-family:monospace;">root@casimir:~# echo &quot;deb http://www.emdebian.org/debian/ squeeze main&quot; &gt;&gt; /etc/apt/sources.list
root@casimir:~# aptitude update</pre></td></tr></table></div>

<p>on installe alors les paquets suivants:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code100'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706100"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p706code100"><pre class="text" style="font-family:monospace;">root@casimir:~# aptitude install linux-libc-dev-armel-cross libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi gcc-4.4-arm-linux-gnueabi g++-4.4-arm-linux-gnueabi
Les NOUVEAUX paquets suivants vont être installés :
  binutils{a} binutils-arm-linux-gnueabi cpp-4.4-arm-linux-gnueabi{a}
  g++-4.4-arm-linux-gnueabi gcc-4.4-arm-linux-gnueabi
  gcc-4.4-arm-linux-gnueabi-base{a} gcc-4.4-base-armel-cross{a}
  libc-bin-armel-cross{a} libc-dev-bin-armel-cross{a} libc6-armel-cross
  libc6-dev-armel-cross libgcc1-armel-cross{a} libgomp1-armel-cross{a}
  libstdc++6-4.4-dev-armel-cross{a} libstdc++6-armel-cross{a}
  linux-libc-dev-armel-cross
0 paquets mis à jour, 16 nouvellement installés, 0 à enlever et 2 non mis à jour.
Il est nécessaire de télécharger 23,8 Mo d'archives. Après dépaquetage, 56,5 Mo seront utilisés.
Voulez-vous continuer ? [Y/n/?]  y</pre></td></tr></table></div>

<p>Après l&#8217;installation des différents paquets vous disposez alors d&#8217;une chaine de compilation croisée pour processeur ARM. Une petite vérification pour la route:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code101'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706101"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code" id="p706code101"><pre class="text" style="font-family:monospace;">root@casimir:~# arm-linux-gnueabi-
arm-linux-gnueabi-addr2line  arm-linux-gnueabi-gcov-4.4
arm-linux-gnueabi-ar         arm-linux-gnueabi-gprof
arm-linux-gnueabi-as         arm-linux-gnueabi-ld
arm-linux-gnueabi-c++filt    arm-linux-gnueabi-nm
arm-linux-gnueabi-cpp        arm-linux-gnueabi-objcopy
arm-linux-gnueabi-cpp-4.4    arm-linux-gnueabi-objdump
arm-linux-gnueabi-g++        arm-linux-gnueabi-ranlib
arm-linux-gnueabi-g++-4.4    arm-linux-gnueabi-readelf
arm-linux-gnueabi-gcc        arm-linux-gnueabi-size
arm-linux-gnueabi-gcc-4.4    arm-linux-gnueabi-strings
arm-linux-gnueabi-gcov       arm-linux-gnueabi-strip
root@casimir:~# arm-linux-gnueabi-gcc -v
Using built-in specs.
Target: arm-linux-gnueabi
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/arm-linux-gnueabi/include/c++/4.4.5 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --disable-sjlj-exceptions --enable-checking=release --program-prefix=arm-linux-gnueabi- --includedir=/usr/arm-linux-gnueabi/include --build=i486-linux-gnu --host=i486-linux-gnu --target=arm-linux-gnueabi --with-headers=/usr/arm-linux-gnueabi/include --with-libs=/usr/arm-linux-gnueabi/lib
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)</pre></td></tr></table></div>

<p>Cela semble correct ! La première étape est complétée&#8230; Nous allons pouvoir compiler pour notre carte TQ6410.</p>
<h2>2. Compilation du chargeur U-Boot et installation sur la carte TQ6410</h2>
<p>Pour mémoire la carte dispose de deux types de mémoire : Flash NOR et Flash NAND. Ces deux mémoires contiennent à l&#8217;achat le chargeur U-Boot. En particulier, si pour une raison ou une autre, le chargeur de la flash NAND est défectueux, vous pouvez le réinstaller en démarrant sur la flash NOR. Donc normalement vous ne pouvez pas bloquer la carte (la &#8216;bricker&#8217;). Dans tous les cas, on peut réinstaller le chargeur U-Boot avec un programmateur type <a href="http://openocd.berlios.de/web/" target="_blank">OpenOCD</a> par le port <a href="http://fr.wikipedia.org/wiki/JTAG" target="_blank">JTAG</a> mais je ne dispose pas d&#8217;une sonde JTAG. Le boot de la carte sur la flash NOR ou NAND se fait par l&#8217;intermédiaire des mini-interrupteurs présents dans le coin inférieur gauche de la carte. On dispose de trois choix pour le boot:</p>
<p>La version de U-Boot livrée sur le DVD fourni avec la carte est nommé &#8216;u-boot-tq6410-20100829.tar.gz&#8217; ce qui me parait un peu ancien. Je décide donc de me rendre sur le site de U-Boot et de télécharger une version plus récente. La gestion des sources se fait avec Git et de plus il y a un <a href="http://git.denx.de/?p=u-boot/u-boot-samsung.git;a=summary" target="_blank">dépot pour les SoC de Samsung</a>. On va donc rapatrier tout ça et en profiter pour jeter un coup d&#8217;oeil au &#8216;README&#8217;:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code102'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706102"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p706code102"><pre class="text" style="font-family:monospace;">root@casimir:~# aptitude install git
root@casimir:~# mkdir u-boot-TQ6410
root@casimir:~# cd u-boot-TQ6410/
root@casimir:~/u-boot-TQ6410# git clone git://git.denx.de/u-boot-samsung.git
Cloning into u-boot-samsung...
remote: Counting objects: 146388, done.
remote: Compressing objects: 100% (36699/36699), done.
remote: Total 146388 (delta 118824), reused 135758 (delta 108242)
Receiving objects: 100% (146388/146388), 38.18 MiB | 30 KiB/s, done.
Resolving deltas: 100% (118824/118824), done.
root@casimir:~/u-boot-TQ6410# cd u-boot-samsung/
root@casimir:~/u-boot-TQ6410/u-boot-samsung# more README</pre></td></tr></table></div>

<p>Dans ce README, vous aurez la liste de tous les paramètres de configuration ainsi que la méthode de compilation (entre autres). En fouillant dans la liste des cartes, je ne trouve qu&#8217;une carte SMDK6400, je vais donc compiler pour cette cible&#8230;</p>
<p>Je n&#8217;ai pas d&#8217;installer ni la commande &#8216;make&#8217;, ni les compilateurs gcc et g++, donc on installe le tout:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code103'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706103"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p706code103"><pre class="text" style="font-family:monospace;">root@casimir:~/u-boot-TQ6410/u-boot-samsung# aptitude install make gcc g++</pre></td></tr></table></div>

<p>On configure la génération de code pour une carte smdk6400 et on lance la cross-compilation:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code104'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706104"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p706code104"><pre class="text" style="font-family:monospace;">root@casimir:~/u-boot-TQ6410/u-boot-samsung# make smdk6400_config
root@casimir:~/u-boot-TQ6410/u-boot-samsung# make CROSS_COMPILE=arm-linux-gnueabi-</pre></td></tr></table></div>

<p>Au bout de quelques minutes, on obtient un fichier u-boot.bin. Je démarre ensuite la carte sur la flash NAND et je choisis l&#8217;option &#8216;Download u-boot.bin&#8217; (lettre &#8216;v&#8217;) dans le menu de U-Boot. Par l&#8217;intermediaire du logiciel DNW sous Windows je télécharge le u-boot.bin fraichement compilé dans la NAND de la carte. Je redémarre la carte et&#8230; cela ne fonctionne pas !!</p>
<p>Ce n&#8217;est pas très étonnent en soi car on a compilé pour un s3c6400 et pas s3c6410. Pour revenir à une situation normale, il faut démarrer sur la flash NOR, choisir la lettre &#8216;v&#8217; dans le menu de U-Boot puis transférer le fichier u-boot.bin du DVD fourni avec la carte grace au logiciel DNW. Ouf&#8230;Situation redevenu normale !</p>
<p>Je ne peux pas compiler directement un u-boot à partir du site, donc je me rabat sur l&#8217;archive fournie sur le DVD du nom de &#8216;u-boot-tq6410-20100829.tar.gz&#8217; dans le répertoire &#8216;linux&#8217;. Je copie cette archive dans le répertoire u-boot-TQ6410 sur ma machine de travail puis je désarchive l&#8217;ensemble et enfin je rentre dans le répertoire &#8216;u-boot-tq6410:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code105'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706105"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p706code105"><pre class="text" style="font-family:monospace;">root@casimir:~/u-boot-TQ6410# cp /multimedia/Electronique/TQ6410/DVD/linux/u-boot-tq6410-20100829.tar.gz .
root@casimir:~/u-boot-TQ6410# tar xzvf u-boot-tq6410-20100829.tar.gz
root@casimir:~/u-boot-TQ6410# cd u-boot-tq6410</pre></td></tr></table></div>

<p>Avant de me lancer dans la compilation de u-boot, je parcours les répertoires de cette archive&#8230;Ce qui est rassurant c&#8217;est de trouver un changelog de chez Samsung, dans le Makefile on trouve des entrées pour smdk2440, smdk6410, tq6410,etc&#8230;On nettoie l&#8217;ensemble puis on lance la compilation:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code106'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706106"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p706code106"><pre class="text" style="font-family:monospace;">root@casimir:~/u-boot-TQ6410# make CROSS_COMPILE=arm-linux-gnueabi- distclean
root@casimir:~/u-boot-TQ6410# make CROSS_COMPILE=arm-linux-gnueabi- tq6410_config
root@casimir:~/u-boot-TQ6410# make CROSS_COMPILE=arm-linux-gnueabi-</pre></td></tr></table></div>

<p>Au bout de quelques minutes, vous obtenez un nouveau fichier u-boot.bin qu&#8217;il faut transférer sur la carte avec l&#8217;utilitaire DNW. Au lancement de la carte, le menu est identique seul la date de compilation à changer (dans mon cas Aug 1 2011). Le menu de U-Boot est personnalisé, j&#8217;aimerai modifier ce menu, je cherche donc dans les codes sources. En fait il faut éditer le fichier &#8216;common/main.c&#8217; et modifier la fonction &#8216;FriendlyARMMenu&#8217;. Je fais juste une modification cosmétique pour vérifier que l&#8217;on peut modifier ce menu. Je recompile le tout et j&#8217;obtient:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code107'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706107"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code" id="p706code107"><pre class="text" style="font-family:monospace;">##### U-Boot 1.1.6 B01 for 6410, by esky-sh #####
##### Modif. par O. DARTOIS pour BTS IRIS   #####
&nbsp;
[f] Format the nand flash
[v] Download u-boot.bin
[k] Download Linux/Android kernel
[y] Download root yaffs2 image
[a] Download Absolute User Application
[n] Download Nboot.nb0 for WinCE
[w] Download WinCE NK.nb0
[s] Set the boot parameter of Linux
[b] Boot Linux
[q] Quit to shell
NAND Flash size: 256 MiB
Enter your Selection:</pre></td></tr></table></div>

<p>Cela semble correct, si vous devez modifier de manière plus conséquente le menu, vous pourrez donc le faire&#8230;</p>
<p><em>Conclusion</em>: même si l&#8217;on a réussi à compiler et à installer un nouveau U-Boot sur la carte, je ne suis qu&#8217;à moitié satisfait. J&#8217;aurais voulu pouvoir compiler les nouvelles versions de U-Boot pour cette carte. De plus malgré ma demande sur le site de samsung pour obtenir un accès au code opensource de leurs SoCs, je n&#8217;ai pas eu de réponse de leur part. Donc je ne sais pas si Samsung maintient toujours un &#8216;U-Boot personnalisé&#8217; pour leurs cartes SMDK. Je passe donc maintenant à la troisième étape : la compilation d&#8217;un noyau linux personnalisé.</p>
<h2>3. Compilation d&#8217;un noyau linux personnalisé pour la carte TQ6410</h2>
<p>Cette carte sera utilisée dans un milieu industriel, nous ne nous servirons donc pas de toutes ces capacités &#8216;multimédia&#8217; et de supports externes (USB, carte SD,etc&#8230;). Par contre il faut impérativement garder les GPIOs, l&#8217;ethernet  et les ports séries.</p>
<p>Cette fois-ci je prends le noyau linux livré sur le DVD. Le fichier s&#8217;appelle &#8220;linux-2.6.28.6-20110319.tar.gz&#8221; dans le répertoire linux. Je créé un répertoire &#8216;Noyau_Linux&#8217; puis je désarchive le noyau:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code108'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706108"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p706code108"><pre class="text" style="font-family:monospace;">root@casimir:~# mkdir Noyau_Linux
root@casimir:~# cd Noyau_Linux
root@casimir:~/Noyau_Linux# cp /multimedia/Electronique/TQ6410/DVD/linux/linux-2.6.28.6-20110319.tar.gz .
root@casimir:~/Noyau_Linux# tar xzvf linux-2.6.28.6-20110319.tar.gz
root@casimir:~/Noyau_Linux# cd linux-2.6.28.6</pre></td></tr></table></div>

<p>Dans le répertoire vous trouverez les configurations du vendeur de la carte (config_tq6410_xx avec xx fonction de la taille de l&#8217;écran tactile). Nous disposons de l&#8217;écran 7 pouces donc la configuration à prendre sera config_tq6410_a70 et nous allons la prendre comme configuration par défaut. Pour configurer votre noyau, nous allons utiliser l&#8217;interface texte (menuconfig), il faut donc installer les paquets suivants:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code109'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706109"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p706code109"><pre class="text" style="font-family:monospace;">root@casimir:~/Noyau_Linux/linux-2.6.28.6# aptitude install ncurses-bin
root@casimir:~/Noyau_Linux/linux-2.6.28.6# make mrproper
root@casimir:~/Noyau_Linux/linux-2.6.28.6# cp config_tq6410_a70 .config
root@casimir:~/Noyau_Linux/linux-2.6.28.6# make arch=arm menuconfig</pre></td></tr></table></div>

<p>Choix dans la configuration du noyau:</p>
<ul>
<li>Pas de &#8220;ramdisk&#8221; initial</li>
<li>Désactivation du chargements des modules : noyau monolitique</li>
<li>Dans &#8220;System type&#8221; prendre le SoC Samsung S3C64XX</li>
<li>Dans &#8220;Floating Point Emulation&#8221; je prends l&#8217;option VFP car le S3C6410 dispose d&#8217;une telle unité de calcul</li>
<li>Désactivation du convertisseur analogique numérique du SoC car erreur de compilation</li>
<li>Désactivation complète du support SCSI</li>
<li>Désactivation du &#8220;S3C Keybord&#8221; : les boutons poussoirs sur la carte</li>
<li>Désactivation du support SPI et I2C</li>
<li>Désactivation de la partie &#8220;Multimédia&#8221; : V4L</li>
<li>Dans la gestion du framebuffer du S3C6410, je met le nombre de framebuffer à 1</li>
<li>Pas de support pour les cartes sons, pas de support HID, pas de support de l&#8217;USB</li>
<li>Support du système de fichier ext3, yaffs2, ubifs (pas de support ext4, dos, vfat)</li>
<li>Pas de support de NFS car le système racine ne sera pas exporté par ce moyen, en conséquence je désactive aussi l&#8217;IP Kernel autoconfiguration&#8217;</li>
<li>Diverses optimisations pour réduire la taille du noyau&#8230;(allocation mémoire par SLUB)</li>
</ul>
<p>Cette configuration minimum est disponible au téléchargement en fin d&#8217;article sous le nom &#8216;config_TQ6410_OD_mini&#8217;.</p>
<p>U-Boot nécessite un noyau spécialement préparé pour lui, il faut donc installer la commande &#8216;mkimage&#8217; puis lancez la compilation pour une image &#8216;uImage&#8217;:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code110'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706110"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p706code110"><pre class="text" style="font-family:monospace;">root@casimir:~/Noyau_Linux/linux-2.6.28.6# aptitude install uboot-mkimage
root@casimir:~/Noyau_Linux/linux-2.6.28.6# make CROSS_COMPILE=arm-linux-gnueabi-
ARCH=arm CFLAGS=&quot;-march=armv6&quot; CXXFLAGS=&quot;-march=armv6&quot; uImage
...
  Kernel: arch/arm/boot/Image is ready
  Kernel: arch/arm/boot/zImage is ready
  UIMAGE  arch/arm/boot/uImage
Image Name:   Linux-2.6.28.6-IRIS-Turgot-O.Dar
Created:      Wed Aug  3 11:43:54 2011
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    1478116 Bytes = 1443.47 kB = 1.41 MB
Load Address: 0x50008000
Entry Point:  0x50008000
  Image arch/arm/boot/uImage is ready</pre></td></tr></table></div>

<p>Le noyau est disponible dans le répertoire arch/arm/boot/ sous le nom uImage. Il faut maintenant transférer ce noyau dans la flash NAND de la carte. Lancez minicom, arrêtez U-Boot puis choisissez l&#8217;option &#8216;Download Linux/Android Kernel&#8217; (lettre &#8216;k&#8217;) puis transférer le noyau avec l&#8217;utilitaire DNW:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code111'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706111"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p706code111"><pre class="text" style="font-family:monospace;">Enter your Selection:k
Downloading Linux/Android Kernel from USB...
Insert a OTG cable into the connector!
OTG cable Connected!
Download address 0xc0000000
Download Done!! Download Address: 0xc0000000, Download Filesize:0x168e24
Checksum is being calculated..
Checksum O.K.
Downloading Linux/Android Kernel successed
Writing Linux/Android Kernel into NAND...
Erasing at 0x560000 -- 100% complete.
&nbsp;
Writing data at 0x1ff800 -- 100% complete.
Writing Linux/Android Kernel successed</pre></td></tr></table></div>

<p>Il faut maintenant démarrer ce nouveau noyau même sans système de fichiers racine pour le tester. Pour cela on va modifier la ligne de paramètres que l&#8217;on passe au noyau avec l&#8217;option &#8216;Set the boot parameter of Linux&#8217; (lettre &#8217;s&#8217;). Tapez alors la ligne suivante pour obtenir la sortie du noyau vers la voie série, préciser le futur &#8216;root-fs&#8217; (ici sur une carte SD) et attendre que celui-ci soit prêt lors du montage de la carte (rootwait), l&#8217;exécutable à lancer aprés le noyau (ici /sbin/init).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code112'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706112"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p706code112"><pre class="text" style="font-family:monospace;">console=ttySAC0,115200 root=/dev/mmcblk0p1 init=/sbin/init rootwait</pre></td></tr></table></div>

<p>Normalement tout doit bien se passer. La taille, après optimisation, de mon noyau est de 1,1Mo. Cette petite taille permet un chargement rapide depuis la flash, une décompression rapide et un boot du noyau jusqu&#8217;au passage à INIT en moins de 4s. Si j&#8217;ai le temps je ferais un article sur l&#8217;optimisation du boot. Ci-dessous les messages de boot du noyau:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code113'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706113"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
</pre></td><td class="code" id="p706code113"><pre class="text" style="font-family:monospace;">Starting kernel ...
&nbsp;
Uncompressing Linux............................................................................. done, booting the kernel.
Linux version 2.6.28.6-IRIS-Turgot-O.Dartois (root@casimir) (gcc version 4.4.5 (Debian 4.4.5-8) ) #10 PREEMPT Thu Aug 4 10:53:55 CEST 2011
CPU: ARMv6-compatible processor [410fb766] revision 6 (ARMv7), cr=00c5387f
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: SMDK6410
Memory policy: ECC disabled, Data cache writeback
CPU S3C6410 (id 0x36410101)
S3C24XX Clocks, (c) 2004 Simtec Electronics
S3C64XX: PLL settings, A=532000000, M=532000000, E=24000000
S3C64XX: HCLKx2=266000000, HCLK=133000000, PCLK=66500000
div1: 00000555
mout_apll: source is fout_apll (1), rate is 532000000
mout_epll: source is fout_epll (1), rate is 24000000
mout_mpll: source is mpll (1), rate is 532000000
mmc_bus: source is dout_mpll (1), rate is 44333333
mmc_bus: source is dout_mpll (1), rate is 44333333
mmc_bus: source is dout_mpll (1), rate is 44333333
usb-host-bus: source is mout_epll (0), rate is 24000000
uclk1: source is dout_mpll (1), rate is 66500000
spi-bus: source is mout_epll (0), rate is 24000000
spi-bus: source is mout_epll (0), rate is 24000000
audio-bus0: source is mout_epll (0), rate is 24000000
audio-bus1: source is mout_epll (0), rate is 24000000
audio-bus2: source is mout_epll (0), rate is 24000000
irda-bus: source is mout_epll (0), rate is 24000000
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
Kernel command line: console=ttySAC0,115200 root=/dev/mmcblk0p1 rootwait int=/sbin/init printk.time=1
[    0.000000] PID hash table entries: 512 (order: 9, 2048 bytes)
[21474536.480000] Console: colour dummy device 80x30
[21474536.480000] s3c24xx_serial_init_ports: initialising ports=4...
[21474536.480000] console [ttySAC0] enabled
[21474536.485000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[21474536.495000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[21474536.510000] Memory: 128MB = 128MB total
[21474536.510000] Memory: 127216KB available (2132K code, 286K data, 96K init)
[21474536.515000] SLUB: Genslabs=12, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[21474536.520000] Calibrating delay loop... 353.89 BogoMIPS (lpj=884736)
[21474536.635000] Mount-cache hash table entries: 512
[21474536.635000] CPU: Testing write buffer coherency: ok
[21474536.640000] net_namespace: 288 bytes
[21474536.645000] NET: Registered protocol family 16
[21474536.670000] S3C6410: Initialising architecture
[21474536.670000] S3C DMA-pl080 Controller Driver, (c) 2006-2007 Samsung Electronics
[21474536.675000] Total 32 DMA channels will be initialized.
[21474536.720000] NET: Registered protocol family 2
[21474536.765000] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[21474536.765000] TCP established hash table entries: 4096 (order: 3, 32768 bytes)
[21474536.770000] TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
[21474536.775000] TCP: Hash tables configured (established 4096 bind 4096)
[21474536.780000] TCP reno registered
[21474536.800000] NET: Registered protocol family 1
[21474536.825000] yaffs Aug  4 2011 10:49:48 Installing.
[21474536.830000] msgmni has been set to 248
[21474536.830000] io scheduler noop registered (default)
[21474536.835000] S3C_LCD clock got enabled :: 133.000 Mhz
[21474536.850000] LCD TYPE :: LTE480WV will be initialized
[21474536.850000] Window[0] - FB1: map_video_memory: clear ff000000:000bb800
[21474536.855000]             FB1: map_video_memory: dma=57100000 cpu=ff000000 size=000bb800
[21474536.860000] Window[0] - FB2: map_video_memory: clear ff05dc00:0005dc00
[21474536.865000]             FB2: map_video_memory: dma=5715dc00 cpu=ff05dc00 size=0005dc00
[21474536.880000] Console: switching to colour frame buffer device 100x30
[21474536.890000] fb0: s3cfb frame buffer device
[21474536.895000] backlight	initialized
[21474536.900000] backlight: 60
[21474536.940000] leds	initialized
[21474536.940000] buttons	initialized
[21474536.940000] pwm	initialized
[21474536.940000] s3c6400-uart.0: s3c2410_serial0 at MMIO 0x7f005000 (irq = 16) is a S3C6400/10
[21474536.945000] s3c6400-uart.1: s3c2410_serial1 at MMIO 0x7f005400 (irq = 20) is a S3C6400/10
[21474536.950000] s3c6400-uart.2: s3c2410_serial2 at MMIO 0x7f005800 (irq = 24) is a S3C6400/10
[21474536.955000] s3c6400-uart.3: s3c2410_serial3 at MMIO 0x7f005c00 (irq = 28) is a S3C6400/10
[21474536.960000] dm9000 Ethernet Driver
[21474536.965000] dm9000: dm9000_probe, init GPIO/EINT.
[21474536.970000] dm9000: dm9000_probe2
[21474536.975000] dm9000: dm9000_probe3
[21474536.980000] eth0: dm9000 at f7b00300,f7b00304 IRQ 108 MAC: 08:90:90:90:90:90
[21474536.985000] S3C NAND Driver, (c) 2008 Samsung Electronics
[21474536.990000] S3C NAND Driver is using hardware ECC.
[21474536.995000] NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
[21474537.000000] Creating 3 MTD partitions on &quot;NAND 256MiB 3,3V 8-bit&quot;:
[21474537.005000] 0x00000000-0x00080000 : &quot;Bootloader&quot;
[21474537.015000] 0x00080000-0x00580000 : &quot;Kernel&quot;
[21474537.020000] 0x00580000-0x10000000 : &quot;File System&quot;
[21474537.065000] mice: PS/2 mouse device common for all mice
[21474537.065000] S3C Touchscreen driver, (c) 2008 Samsung Electronics
[21474537.070000] S3C TouchScreen got loaded successfully : 12 bits
[21474537.080000] input: S3C TouchScreen as /class/input/input0
[21474537.125000] S3C24XX RTC, (c) 2004,2006 Simtec Electronics
[21474537.125000] s3c2410_rtc: tick irq 34, alarm irq 92
[21474537.130000] s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling
[21474537.135000] s3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc0
[21474537.140000] S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
[21474537.145000] s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
[21474537.150000] sdhci: Secure Digital Host Controller Interface driver
[21474537.155000] sdhci: Copyright(c) Pierre Ossman
[21474537.155000] s3c-sdhci s3c-sdhci.0: clock source 0: hsmmc (133000000 Hz)
[21474537.160000] s3c-sdhci s3c-sdhci.0: clock source 1: hsmmc (133000000 Hz)
[21474537.165000] s3c-sdhci s3c-sdhci.0: clock source 2: mmc_bus (44333333 Hz)
[21474537.170000] [SDHCI]to add external irq as a card detect signal......
[21474537.175000] [SDHCI]if (pdata-&amp;gt;cfg_ext_cd)......
[21474537.180000] mmc0: SDHCI controller on samsung-hsmmc [s3c-sdhci.0] using ADMA
[21474537.185000] [SDHCI]request_irq......
[21474537.190000] sdhci: card inserted.
[21474537.205000] TCP cubic registered
[21474537.205000] NET: Registered protocol family 17
[21474537.205000] VFP support v0.3: implementor 41 architecture 1 part 20 variant b rev 5
[21474537.225000] s3c2410-rtc s3c2410-rtc: setting system clock to 2011-08-04 09:50:52 UTC (1312451452)
[21474537.225000] Waiting for root device /dev/mmcblk0p1...
[21474537.250000] mmc0: new high speed SD card at address 0007
[21474537.250000] mmcblk0: mmc0:0007 SD02G 1.83 GiB
[21474537.255000]  mmcblk0: p1
[21474537.340000] EXT3-fs warning: maximal mount count reached, running e2fsck is recommended
[21474537.340000] kjournald starting.  Commit interval 5 seconds
[21474537.475000] EXT3 FS on mmcblk0p1, internal journal
[21474537.475000] EXT3-fs: mounted filesystem with ordered data mode.
[21474537.480000] VFS: Mounted root (ext3 filesystem).
[21474537.485000] Freeing init memory: 96K
INIT: version 2.88 booting
Using makefile-style concurrent boot in runlevel S.
Starting the hotplug events dispatcher: udevd.
Synthesizing the initial hotplug events...done.
Waiting for /dev to be fully populated...done.
Activating swap...done.
Cleaning up ifupdown....
Setting up networking....
Activating lvm and md swap...done.
Checking file systems...fsck from util-linux-ng 2.17.2
done.
Mounting local filesystems...done.
Activating swapfile swap...done.
Cleaning up temporary files....
Configuring network interfaces...[21474550.970000] eth0: link down
done.
Cleaning up temporary files....
Setting kernel variables ...done.
INIT: Entering runlevel: 2
Using makefile-style concurrent boot in runlevel 2.
Starting enhanced syslogd: rsyslogd.
Starting periodic command scheduler: cron.
Starting system message bus: dbus.
&nbsp;
Debian GNU/Linux 6.0 TQ6410-Iris s3c2410_serial0
&nbsp;
TQ6410-Iris login:</pre></td></tr></table></div>

<p><em>Remarque</em>: vous pouvez voir que le boot noyau prend environ 1s aprés décompression ! Ici le &#8216;rootfs&#8217; existe c&#8217;est pour cette raison que l&#8217;on arrive à un &#8216;login&#8217;. Toutes les optimisations de temps de boot ne sont pas exploitées ici&#8230;</p>
<p>Puisque l&#8217;on parle de système de fichiers racine, voyons comment le réaliser&#8230;</p>
<h2>4. Création du système de fichiers racine (ou &#8216;rootfs&#8217;) basé sur Debian Squeeze  Grip</h2>
<p>On part d&#8217;une distribution Debian pour la stabilité et le système de gestion des paquets. Dans un premier temps, on ne va pas faire de l&#8217;embarqué pur, on va faire en sorte d&#8217;avoir une plateforme de test assez souple. Par la suite on pourra optimiser le &#8216;rootfs&#8217; en travaillant avec BusyBox. Tout commence sur la machine de développement, on va construire le système de fichiers racine avec l&#8217;utilitaire &#8216;Debootstrap&#8217;. En résumé on va :</p>
<ul>
<li>formater en ext3 une carte SD de 2Go</li>
<li>créer sur cette carte un système de fichier racine avec debootstrap</li>
<li>effectuer quelques modifications pour démarrer sur ce système</li>
<li>démarrer sur cette carte SD depuis la carte TQ6410 et terminer l&#8217;installation</li>
<li>faire les modifications finales sur le système</li>
</ul>
<p>Les traces de ces étapes sont présentés ci-dessous (sdd est à remplacer avec le bon périphérique : affichez les messages du  noyau avec dmesg et lisez les dernières lignes après avoir inséré votre carte) :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code114'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706114"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p706code114"><pre class="text" style="font-family:monospace;">root@casimir:~# fdisk /dev/sdd
...création d'une partition primaire de type linux non bootable de la taille de la carte SD
root@casimir:~# mkfs.ext3 -L rootfs -m 0 /dev/sdd1
root@casimir:~# tune2fs -c 200 -C 0 /dev/sdd1
root@casimir:~# tune2fs -l /dev/sdd1
root@casimir:~# mount /dev/sdd1 /mnt
root@casimir:~# aptitude install debootstrap
root@casimir:~# debootstrap --arch=armel --foreign squeeze /mnt http://www.emdebian.org/grip/
root@casimir:~# echo &quot;deb http://www.emdebian.org/grip/ squeeze main&quot; &gt;&gt; /mnt/etc/apt/sources.list
root@casimir:~# echo &quot;proc /proc proc none 0 0&quot; &gt;&gt; /mnt/etc/fstab
root@casimir:~# echo &quot;TQ6410-Iris&quot; &gt; /mnt/etc/hostname
root@casimir:~# mkdir -p /mnt/usr/share/man/man1/
root@casimir:~# umount /mnt</pre></td></tr></table></div>

<p>Maintenant insérez la carte SD sur la TQ6410, démarrez puis arrêtez U-Boot. Changez les paramètres de chargement du noyau (lettre &#8217;s&#8217;) pour démarrer sur la carte SD avec un shell minimum pour terminer l&#8217;installation:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code115'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706115"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p706code115"><pre class="text" style="font-family:monospace;">ttySAC0,115200 root=/dev/mmcblk0p1 rootwait init=/bin/sh</pre></td></tr></table></div>

<p>On passe à la deuxième phase d&#8217;installation du système de fichiers racine, cette fois ci directement sur la carte:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code116'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706116"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p706code116"><pre class="text" style="font-family:monospace;"># /debootstrap/debootstrap --second-stage
[... ...]
#echo s3c2410_serial0 &gt;&gt; /etc/securetty
#printf &quot;T0:123:respawn:/sbin/getty 115200 s3c2410_serial0\n&quot; &gt;&gt; /etc/inittab
#printf &quot;auto eth0\niface eth0 inet dhcp\n&quot; &gt;&gt; /etc/network/interfaces
#passwd
#reboot</pre></td></tr></table></div>

<p>Explications des commandes qui précèdent : suite de l&#8217;installation des paquetages (second stage install) soyez patient&#8230;puis on rajoute à securetty (terminaux sur lesquels on peut se connecter)  le port série par lequel on va se logger. Ici vous n&#8217;avez plus ttySAC0 car udev est passé par là et à donc changer les noms des ports séries (regardez les messages du noyau). On rajoute aussi dans /etc/inittab une ligne qui permet de lancer automatiquement une console sur le port série dans les niveaux d&#8217;exécution 1,2 et 3. On configure le réseau en mode automatique (DHCP) en rajoutant les lignes dans le fichier /etc/network/interfaces. On fixe le mot de passe root et enfin on redémarre.</p>
<p>Encore une fois il faudra modifier la ligne de commande que U-Boot passe au noyau en:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code117'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706117"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p706code117"><pre class="text" style="font-family:monospace;">console=ttySAC0,115200 root=/dev/mmcblk0p1 init=/sbin/init rootwait</pre></td></tr></table></div>

<p>Vous allez observer les messages du noyau, puis le lancement de INIT qui va amorcer le système jusqu&#8217;à l&#8217;obtention d&#8217;un login. Identifiez-vous &#8216;root&#8217; avec le mot de passe que vous avez saisi précédemment. Si pendant le démarrage noyau le démon udevd se plaint que le répertoire .udev/ existe déjà dans le répertoire /dev, il faudra redémarrer avec init=/bin/sh puis supprimer ce répertoire.</p>
<p>Vous avez donc maintenant une plateforme debian qui fonctionne sur un système embarqué. Ce système de base utilise près de 80Mo (ce qui est déjà lourd) mais vous avez toutes les fonctionnalités d&#8217;une debian classique. Le système est donc facilement administrable par la suite, l&#8217;ajout/suppression de paquets se fera très simplement avec aptitude.</p>
<p>Pour mémoire, cette carte doit être utilisé dans le cadre du développement d&#8217;une application graphique pour superviser un process industriel. Dans un premier temps, on facilite donc la tache des programmeurs en ayant une plateforme ressemblant à une station de travail avec de l&#8217;espace disque (on travaille avec une carte SD de 2G0). Une fois l&#8217;application développée et testée, on optimisera le système (utilisation de busybox, binaire statique, rootfs réduit au minimum sur flash NAND).</p>
<p>Pour terminer cette partie, une trace complète du boot de la carte réalisé avec GrabSerial pour faire des tests de temps de démarrage:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code118'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706118"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
</pre></td><td class="code" id="p706code118"><pre class="text" style="font-family:monospace;">Opening serial port /dev/ttyS0
115200:8N1:xonxoff=0:rtcdtc=0
Printing timing information for each line
Matching pattern 'Starting kernel.*' to set base time
Use Control-C to stop...
[    0.000004]
[    0.288957]
[    0.289171] U-Boot 1.1.6 (Aug  5 2011 - 11:50:17) for TQ6410
[    0.293743]
[    0.293901]
[    0.294050] CPU:     S3C6410@532MHz
[    0.296300]          Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
[    0.303853] Board:   TQ6410
[    0.305418] DRAM:    128 MB
[    0.306917] Flash:   0 kB
[    0.308178] NAND:    256 MB
[    0.403949] In:      serial
[    0.405456] Out:     serial
[    0.406855] Err:     serial
[    0.483983] MAC: 08:90:90:90:90:90
[    0.486081] Hit any key to stop autoboot:  3  2  1  0
[    3.471948]
[    3.472140] NAND read: device 0 offset 0x80000, size 0x140000
[    3.476632]
[    3.476805] Reading data from 0x80000 --   0% complete....
[    4.712153]  1310720 bytes read: OK
[    4.714419] ## Booting image at c0008000 ...
[    4.717525]    Image Name:   Linux-2.6.28.6-IRIS-Turgot-O.Dar
[    4.722157]    Image Type:   ARM Linux Kernel Image (uncompressed)
[    4.727189]    Data Size:    1246092 Bytes =  1.2 MB
[    4.730954]    Load Address: 50008000
[    4.733404]    Entry Point:  50008000
[    5.039941] OK
[    5.040271]
[    5.040459] Starting kernel ...
[    0.001796]
[    0.007486] Uncompressing Linux................................................................................. done, booting the kernel.
[    0.567520] [    0.000000] Linux version 2.6.28.6-IRIS-Turgot-O.Dartois (root@casimir) (gcc version 4.4.5 (Debian 4.4.5-8) ) #23 PREEMPT Sun Aug 7 13:22:45 CEST 2011
[    0.581501] [    0.000000] CPU: ARMv6-compatible processor [410fb766] revision 6 (ARMv7), cr=00c5387f
[    0.589758] [    0.000000] CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
[    0.597419] [    0.000000] Machine: SMDK6410
[    0.600475] [    0.000000] Memory policy: ECC disabled, Data cache writeback
[    0.606403] [    0.000000] CPU S3C6410 (id 0x36410101)
[    0.614901] [    0.000000] S3C24XX Clocks, (c) 2004 Simtec Electronics
[    0.616787] [    0.000000] S3C64XX: PLL settings, A=532000000, M=532000000, E=24000000
[    0.621468] [    0.000000] S3C64XX: HCLKx2=266000000, HCLK=133000000, PCLK=66500000
[    0.627644] [    0.000000] div1: 00000555
[    0.628648] [    0.000000] mout_apll: source is fout_apll (1), rate is 532000000
[    0.635804] [    0.000000] mout_epll: source is fout_epll (1), rate is 24000000
[    0.640155] [    0.000000] mout_mpll: source is mpll (1), rate is 532000000
[    0.647749] [    0.000000] mmc_bus: source is dout_mpll (1), rate is 44333333
[    0.652045] [    0.000000] mmc_bus: source is dout_mpll (1), rate is 44333333
[    0.657073] [    0.000000] mmc_bus: source is dout_mpll (1), rate is 44333333
[    0.664213] [    0.000000] usb-host-bus: source is mout_epll (0), rate is 24000000
[    0.671772] [    0.000000] uclk1: source is dout_mpll (1), rate is 66500000
[    0.676240] [    0.000000] spi-bus: source is mout_epll (0), rate is 24000000
[    0.683605] [    0.000000] spi-bus: source is mout_epll (0), rate is 24000000
[    0.688184] [    0.000000] audio-bus0: source is mout_epll (0), rate is 24000000
[    0.695644] [    0.000000] audio-bus1: source is mout_epll (0), rate is 24000000
[    0.700284] [    0.000000] audio-bus2: source is mout_epll (0), rate is 24000000
[    0.707533] [    0.000000] irda-bus: source is mout_epll (0), rate is 24000000
[    0.712576] [    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512
[    0.720433] [    0.000000] Kernel command line: console=ttySAC0,115200 root=/dev/mmcblk0p1 rootwait init=/sbin/init
[    0.731529] [    0.000000] PID hash table entries: 512 (order: 9, 2048 bytes)
[    0.745040] [21474536.480000] Console: colour dummy device 80x30
[    0.746652] [21474536.480000] s3c24xx_serial_init_ports: initialising ports=4...
[    0.752795] [21474536.480000] console [ttySAC0] enabled
[    0.754150] [21474536.485000] Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
[    0.760837] [21474536.490000] Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
[    0.771485] [21474536.505000] Memory: 128MB = 128MB total
[    0.775965] [21474536.505000] Memory: 127088KB available (2276K code, 286K data, 96K init)
[    0.780887] [21474536.510000] SLUB: Genslabs=12, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.791570] [21474536.515000] Calibrating delay loop... 353.89 BogoMIPS (lpj=884736)
[    0.896457] [21474536.625000] Mount-cache hash table entries: 512
[    0.900846] [21474536.625000] CPU: Testing write buffer coherency: ok
[    0.908049] [21474536.630000] net_namespace: 288 bytes
[    0.911823] [21474536.635000] NET: Registered protocol family 16
[    0.916045] [21474536.645000] S3C6410: Initialising architecture
[    0.920419] [21474536.645000] S3C DMA-pl080 Controller Driver, (c) 2006-2007 Samsung Electronics
[    0.928430] [21474536.650000] Total 32 DMA channels will be initialized.
[    0.947479] [21474536.675000] NET: Registered protocol family 2
[    0.991496] [21474536.720000] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.996502] [21474536.720000] TCP established hash table entries: 4096 (order: 3, 32768 bytes)
[    1.004716] [21474536.725000] TCP bind hash table entries: 4096 (order: 2, 16384 bytes)
[    1.013681] [21474536.730000] TCP: Hash tables configured (established 4096 bind 4096)
[    1.021195] [21474536.735000] TCP reno registered
[    1.031494] [21474536.755000] NET: Registered protocol family 1
[    1.043492] [21474536.765000] JFFS2 version 2.2. (NAND) (SUMMARY)  Â© 2001-2006 Red Hat, Inc.
[    1.049080] [21474536.770000] yaffs Aug  7 2011 00:09:52 Installing.
[    1.057092] [21474536.775000] msgmni has been set to 248
[    1.058617] [21474536.775000] io scheduler noop registered (default)
[    1.063791] [21474536.780000] S3C_LCD clock got enabled :: 133.000 Mhz
[    1.068993] [21474536.795000] LCD TYPE :: LTE480WV will be initialized
[    1.075952] [21474536.795000] Window[0] - FB1: map_video_memory: clear ff000000:000bb800
[    1.080818] [21474536.800000]             FB1: map_video_memory: dma=57100000 cpu=ff000000 size=000bb800
[    1.091572] [21474536.805000] Window[0] - FB2: map_video_memory: clear ff05dc00:0005dc00
[    1.099483] [21474536.810000]             FB2: map_video_memory: dma=5715dc00 cpu=ff05dc00 size=0005dc00
[    1.123509] [21474536.825000] Console: switching to colour frame buffer device 100x30
[    1.131343] [21474536.835000] fb0: s3cfb frame buffer device
[    1.137452] [21474536.840000] backlight	initialized
[    1.143489] [21474536.845000] backlight: 60
[    1.144485] [21474536.860000] leds	initialized
[    1.148332] [21474536.860000] pwm	initialized
[    1.151957] [21474536.860000] s3c6400-uart.0: s3c2410_serial0 at MMIO 0x7f005000 (irq = 16) is a S3C6400/10
[    1.160224] [21474536.870000] s3c6400-uart.1: s3c2410_serial1 at MMIO 0x7f005400 (irq = 20) is a S3C6400/10
[    1.168514] [21474536.875000] s3c6400-uart.2: s3c2410_serial2 at MMIO 0x7f005800 (irq = 24) is a S3C6400/10
[    1.176715] [21474536.880000] s3c6400-uart.3: s3c2410_serial3 at MMIO 0x7f005c00 (irq = 28) is a S3C6400/10
[    1.186421] [21474536.885000] dm9000 Ethernet Driver
[    1.190548] [21474536.885000] dm9000: dm9000_probe, init GPIO/EINT.
[    1.197018] [21474536.890000] dm9000: dm9000_probe2
[    1.201072] [21474536.895000] dm9000: dm9000_probe3
[    1.202422] [21474536.900000] eth0: dm9000 at f7b00300,f7b00304 IRQ 108 MAC: 08:90:90:90:90:90
[    1.208523] [21474536.905000] S3C NAND Driver, (c) 2008 Samsung Electronics
[    1.215927] [21474536.915000] S3C NAND Driver is using hardware ECC.
[    1.220201] [21474536.915000] NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
[    1.230312] [21474536.920000] Creating 3 MTD partitions on &quot;NAND 256MiB 3,3V 8-bit&quot;:
[    1.236422] [21474536.925000] 0x00000000-0x00080000 : &quot;Bootloader&quot;
[    1.241708] [21474536.930000] 0x00080000-0x00580000 : &quot;Kernel&quot;
[    1.247327] [21474536.935000] 0x00580000-0x10000000 : &quot;File System&quot;
[    1.287488] [21474536.980000] S3C Touchscreen driver, (c) 2008 Samsung Electronics
[    1.293536] [21474536.980000] S3C TouchScreen got loaded successfully : 12 bits
[    1.299182] [21474536.985000] input: S3C TouchScreen as /devices/virtual/input/input0
[    1.311489] [21474537.005000] S3C24XX RTC, (c) 2004,2006 Simtec Electronics
[    1.318452] [21474537.005000] s3c2410_rtc: tick irq 34, alarm irq 92
[    1.324809] [21474537.010000] s3c2410-rtc s3c2410-rtc: rtc disabled, re-enabling
[    1.332221] [21474537.015000] s3c2410-rtc s3c2410-rtc: rtc core: registered s3c as rtc0
[    1.340306] [21474537.020000] S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
[    1.347792] [21474537.030000] s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq enabled
[    1.357097] [21474537.035000] sdhci: Secure Digital Host Controller Interface driver
[    1.364903] [21474537.040000] sdhci: Copyright(c) Pierre Ossman
[    1.370816] [21474537.045000] s3c-sdhci s3c-sdhci.0: clock source 0: hsmmc (133000000 Hz)
[    1.379047] [21474537.050000] s3c-sdhci s3c-sdhci.0: clock source 1: hsmmc (133000000 Hz)
[    1.387309] [21474537.055000] s3c-sdhci s3c-sdhci.0: clock source 2: mmc_bus (44333333 Hz)
[    1.395645] [21474537.060000] [SDHCI]to add external irq as a card detect signal......
[    1.403593] [21474537.065000] [SDHCI]if (pdata-&amp;gt;cfg_ext_cd)......
[    1.409657] [21474537.070000] mmc0: SDHCI controller on samsung-hsmmc [s3c-sdhci.0] using ADMA
[    1.418297] [21474537.075000] [SDHCI]request_irq......
[    1.423347] [21474537.080000] sdhci: card inserted.
[    1.428779] [21474537.085000] TCP cubic registered
[    1.434598] [21474537.090000] NET: Registered protocol family 17
[    1.436263] [21474537.095000] VFP support v0.3: implementor 41 architecture 1 part 20 variant b rev 5
[    1.441529] [21474537.105000] s3c2410-rtc s3c2410-rtc: setting system clock to 2011-08-07 20:03:34 UTC (1312747414)
[    1.446252] [21474537.115000] Waiting for root device /dev/mmcblk0p1...
[    1.839493] [21474537.520000] mmc0: new high speed SD card at address 0002
[    1.844010] [21474537.520000] mmcblk0: mmc0:0002 00000 1.86 GiB
[    1.847723] [21474537.525000]  mmcblk0: p1
[    1.859526] [21474537.545000] kjournald starting.  Commit interval 5 seconds
[    1.867483] [21474537.550000] EXT3 FS on mmcblk0p1, internal journal
[    1.872305] [21474537.550000] EXT3-fs: mounted filesystem with ordered data mode.
[    1.879762] [21474537.555000] VFS: Mounted root (ext3 filesystem).
[    1.885848] [21474537.560000] Freeing init memory: 96K
[    2.135521] INIT: version 2.88 booting
[    2.335501] Using makefile-style concurrent boot in runlevel S.
[    2.951538] Starting the hotplug events dispatcher: udevd.
[    3.439497] Synthesizing the initial hotplug events...done.
[    3.843493] Waiting for /dev to be fully populated...done.
[    5.083503] Activating swap...done.
[    7.415484] Cleaning up ifupdown....
[    7.523493] Setting up networking....
[    8.247491] Activating lvm and md swap...done.
[    8.287498] Checking file systems...fsck from util-linux-ng 2.17.2
[    8.403493] done.
[    8.455494] Mounting local filesystems...done.
[    8.487493] Activating swapfile swap...done.
[    8.563490] Cleaning up temporary files....
[    8.935547] Configuring network interfaces...[21474544.705000] eth0: link down
[    9.119495] done.
[    9.211492] Cleaning up temporary files....
[    9.531489] Setting kernel variables ...done.
[    9.807515] INIT: Entering runlevel: 2
[    9.875529] Using makefile-style concurrent boot in runlevel 2.
[   10.495507] Starting enhanced syslogd: rsyslogd[21474546.705000] eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
[   11.647491] .
[   11.715496] Starting periodic command scheduler: cron.
[   13.063506]
[   13.067494] Debian GNU/Linux 6.0 TQ6410-Iris s3c2410_serial0
[   13.072671]
[   13.079498] TQ6410-Iris login:</pre></td></tr></table></div>

<p>On remarquera que le compteur de temps est remis à 0 lorsque la chaine &#8220;Starting Kernel&#8221; apparait. Le boot de noyau (décompression comprise) jusqu&#8217;au passage à INIT prend 2,1s. Le login apparait lui après 13s. Dans ce cas la configuration IP était fixé donc pas de requête DHCP.</p>
<h2>5. Développement d&#8217;applications graphiques sur plateforme TQ6410</h2>
<p>Comme je ne sais pas encore avec &#8220;quoi&#8221; on va programmer pour faire une application graphique, je reste une fois de plus générique : on va compléter l&#8217;installation précédente par l&#8217;installation de X.org et de l&#8217;écran tactile. Peut-être X ne sera pas utilisé et on travaillera directement avec le framebuffer sous Qt Embedded&#8230;</p>
<p>Il existe sous GNU/Linux deux manières de gérer les écrans tactiles evtouch et tslib. Comme je n&#8217;ai jamais pu faire fonctionner correctement evtouch, nous allons installer tslib. Il faut juste installer un paquetage, exporter une variable qui indique le périphérique qui pointe vers l&#8217;écran tactile (ici /dev/input/event0 car les boutons poussoirs de la carte sont désactivés) et enfin on lance l&#8217;utilitaire de calibration puis de tests:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code119'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706119"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p706code119"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# aptitude install libts-bin
root@TQ6410-Iris:~# export TSLIB_TSDEVICE=/dev/input/event0
root@TQ6410-Iris:~# ts_calibrate
root@TQ6410-Iris:~# ts_test</pre></td></tr></table></div>

<p>On se lance alors dans l&#8217;installation de X.org par la commande suivante (attention pas du tout optimisé on installe en &#8216;gros&#8217;) puis on installe le gestionnaire de l&#8217;écran tactile pour X, on lance le client X à l&#8217;ancienne mode (fond d&#8217;écran &#8216;hachuré&#8217;) et un petit xeyes pour la route :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code120'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706120"><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code" id="p706code120"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# aptitude install xorg
root@TQ6410-Iris:~# aptitude install xserver-xorg-input-tslib
root@TQ6410-Iris:~# X -retro &amp;;
root@TQ6410-Iris:~# xeyes -display :0.0</pre></td></tr></table></div>

<p>Si vous voulez directement lancer l&#8217;interface graphique, il faut installer le paquetage nodm :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code121'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706121"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p706code121"><pre class="text" style="font-family:monospace;">root@TQ6410-Iris:~# aptitude install nodm</pre></td></tr></table></div>

<p>Puis faire les modifications suivantes dans son fichier de configuration /etc/default/nodm:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p706code122'); return false;">View Code</a> TEXT</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p706122"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p706code122"><pre class="text" style="font-family:monospace;">NODM_ENABLE = true
NODM_FIRST_VT=2 car j'ai désactivé les autes terminaux virtuels dans /etc/inittab
NODM_X_OPTIONS = 'vt2 -nolisten tcp'</pre></td></tr></table></div>

<p>Redémarrez et vous allez obtenir au bout de quelques secondes un écran &#8216;graphique&#8217; avec un terminal qui prend tout l&#8217;écran. Donc ca fonctionne correctement mais c&#8217;est pas top&#8230;il faudrait installer un gestionnaire de fenêtre voire de bureau&#8230;</p>
<p>Alors je ne vous encourage pas à installer gnome ou kde mais plutôt matchbox&#8230;et exporter la variable DISPLAY=:0.0 !</p>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2011/08/01/personnalisation-de-la-carte-tq6410-noyau-linux-et-systeme-de-fichiers-racine-emdebian-squeeze/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Présentation Carte TQ6410 (compatible FriendlyARM Mini 6410)</title>
		<link>http://innovelectronique.fr/2011/07/27/presentation-carte-tq6410-compatible-friendlyarm-mini-6410/</link>
		<comments>http://innovelectronique.fr/2011/07/27/presentation-carte-tq6410-compatible-friendlyarm-mini-6410/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 18:40:10 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[Linux Embarqué]]></category>

		<category><![CDATA[emdebian]]></category>

		<category><![CDATA[QT]]></category>

		<category><![CDATA[TQ6410]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=652</guid>
		<description><![CDATA[J&#8217;ai récemment fait l&#8217;acquisition d&#8217;une carte TQ6410 (SoC Samsung s3c6410 ARM11, Flash NOR: 1Mo, Flash NAND: 256Mo, RAM: 128Mo) avec un écran tactile de 7 pouces dans le but de développer une application industrielle avec des élèves de seconde année BTS IRIS. Cette carte ressemble à une autre carte bien connu : la FriendlyARM 6410. [...]]]></description>
			<content:encoded><![CDATA[<p>J&#8217;ai récemment fait l&#8217;acquisition d&#8217;une carte TQ6410 (SoC Samsung s3c6410 ARM11, <a href="http://fr.wikipedia.org/wiki/M%C3%A9moire_flash">Flash NOR</a>: 1Mo, <a href="http://fr.wikipedia.org/wiki/M%C3%A9moire_flash">Flash NAND</a>: 256Mo, RAM: 128Mo) avec un écran tactile de 7 pouces dans le but de développer une application industrielle avec des élèves de seconde année BTS IRIS. Cette carte ressemble à une autre carte bien connu : la <a href="http://www.friendlyarm.net/products/mini6410?lang=en" target="_blank">FriendlyARM 6410</a>. Cette carte provient d&#8217;un vendeur sur e-bay (<a href="http://stores.ebay.fr/esky-shn" target="_blank">esky-sh</a>) au prix de 175 € (frais de port compris, frais de douanes en sus). Dans l&#8217;article qui suit je détaille la prise en main de cette carte : déballage, quelques tests mais surtout l&#8217;installation d&#8217;une emDebian pour faciliter la gestion des paquets et en faire une base générique de développement. Le but final est d&#8217;implanter une application fonctionnant avec le kit graphique <a href="http://qt.nokia.com/" target="_blank">Qt de Nokia</a>&#8230;<span id="more-652"></span></p>
<h1>Déballage</h1>
<p>En déballant le paquet de la TQ6410 vous trouvez:</p>
<ul>
<li>La carte électronique TQ6410</li>
<li>Un écran LCD TFT de 7 pouces de marque Innolux AT070TN92 avec dalle tactile résistive et cadre de fixation</li>
<li>un câble série droit équipé avec des connecteurs DB9</li>
<li>un câble ethernet droit</li>
<li>un câble USB</li>
<li>un DVD-R gravé avec les ressources logiciels (cross-compilateur, source du noyau linux, &#8220;rootfs&#8221; linux, android,WinCE, exemples de codes,etc&#8230;)</li>
<li>une alimentation à découpage 12V-1A (livrée avec une fiche américaine !). Cette alimentation est insuffisante pour assurer un fonctionnement correct de la carte et de l&#8217;écran 7 pouces. Il faudra donc faire l&#8217;acquisition d&#8217;un autre bloc d&#8217;alimentation.</li>
</ul>
<p>Si vous voulez des &#8220;visuels&#8221; de cette carte, faites une recherche avec un <a href="http://www.google.fr/search?tbm=isch&amp;hl=fr&amp;source=hp&amp;biw=1366&amp;bih=653&amp;q=TQ6410&amp;gbv=2&amp;oq=TQ6410&amp;aq=f&amp;aqi=&amp;aql=&amp;gs_sm=e&amp;gs_upl=5288l7316l0l7916l6l6l0l3l0l0l229l578l0.1.2l3" target="_blank">moteur de recherche</a> !</p>
<h1>Découverte de la carte</h1>
<p>Pour faire quelques tests sur la carte, je câble l&#8217;ensemble:</p>
<ul>
<li>Connexion de l&#8217;écran sur la carte (attention les connecteurs sont TRÈS fragiles)</li>
<li>Connexion de l&#8217;alimentation après changement de la fiche d&#8217;origine pour une fiche française</li>
<li>Connexion du câble série sur la carte et sur un PC fonctionnant sous GNU/Linux</li>
<li>Connexion du câble USB sur la carte en vu d&#8217;une connexion ultérieure sur un PC fonctionnant sous Microsoft Windows7</li>
</ul>
<p>Avant d&#8217;alimenter le tout en basculant l&#8217;interrupteur M/A sur le coté de la carte, je lis quelques documentations du DVD. Vous y apprendrez que :</p>
<ul>
<li>le chargeur de démarrage est <a href="http://www.denx.de/wiki/U-Boot" target="_blank">U-Boot</a> aussi bien dans la FLASH NAND que NOR (normalement il est donc impossible de bloquer la carte en écrasant le chargeur de démarrage : on démarre toujours depuis la NAND, si problème on démarre depuis la NOR et on réinstalle U-Boot sur la NAND).</li>
<li>le noyau linux est un 2.6.28 patché pour supporter le S3C6410 de Samsung</li>
<li>le système pré-installé dans la NAND est un GNU/Linux avec un environnement<a href="http://fr.wikipedia.org/wiki/Qt_Extended"> QTExtended (Qtopia)</a></li>
</ul>
<p>Pour avoir quelques informations supplémentaires, nous allons observer la voie série. L&#8217;environnement de développement sera une machine sous GNU/Linux <a href="http://www.debian.org/index.fr.html" target="_blank">Debian</a> 6 (Squeeze). Pour interagir avec la voie série, nous allons utiliser <a href="http://alioth.debian.org/projects/minicom/" target="_blank">Minicom</a>. Il faut donc l&#8217;installer :</p>
<pre>root@casimir:~#aptitude install minicom</pre>
<p>puis le configurer :</p>
<pre>root@casimir:~#minicom -s</pre>
<p>La rubrique qui nous intéresse est &#8220;Configuration du port série&#8221;. Dans cette rubrique il faut régler le port série sur &#8220;/dev/ttyS0&#8243; si vous utilisez le premier port série (COM1: sous Microsoft Windows) (remarque: si vous utilisez un adaptateur USB-Série son nom sera vraisemblablement ttyUSB0), le &#8220;Débit/Parité/Bits&#8221; sur 115200 8N1, le &#8220;Contrôle de flux matériel et logiciel&#8221; sur &#8220;Non&#8221;. Sauvegardez vos réglages en revenant au menu principal et en choisissant l&#8217;option &#8220;Enregistrer config. sous dfl&#8221;. Sortez de minicom puis relancez-le en ignorant l&#8217;initialisation du modem avec:</p>
<pre>root@casimir:~#minicom -o</pre>
<p>Minicom attend alors du trafic sur la voie série&#8230;</p>
<h2>Amorçage par défaut : Noyau Linux et environnement QTopia</h2>
<p>Allumez alors la carte, vous devriez voir des messages du chargeur U-Boot. Appuyez sur la touche &#8216;entrée&#8217; pour interrompre le chargement ! Vous devriez avoir les messages suivants:</p>
<pre>OK

U-Boot 1.1.6 (Aug 29 2010 - 16:56:31) for TQ6410

CPU:     S3C6410@532MHz
         Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode)
Board:   TQ6410
DRAM:    128 MB
Flash:   0 kB
NAND:    256 MB
In:      serial
Out:     serial
Err:     serial
MAC: 08:90:90:90:90:90
Hit any key to stop autoboot:  3     &lt;= Appui sur la touche entrée
##### U-Boot 1.1.6 B01 for 6410, by esky-sh #####
[f] Format the nand flash
[v] Download u-boot.bin
[k] Download Linux/Android kernel
[y] Download root yaffs2 image
[a] Download Absolute User Application
[n] Download Nboot.nb0 for WinCE
[w] Download WinCE NK.nb0
[s] Set the boot parameter of Linux
[b] Boot Linux
[q] Quit to shell
NAND Flash size: 256 MiB
Enter your Selection:</pre>
<p>La carte dispose donc de U-Boot en version 1.1.6. On retrouve bien les quantités de mémoire prévues (pas de NOR car on démarre pour l&#8217;instant depuis la NAND). On arrête le chargement et on se retrouve avec le menu de U-Boot préparé par le revendeur esky-sh. Nous utiliserons centaines de ces options pour changer le noyau à charger ou encore le système de fichier racine. Pour continuer le chargement, appuyez sur la lettre &#8216;b&#8217;. Le noyau linux préparé par FriendlyARM démarre puis le système de fichier racine est chargé&#8230;On peut alors tester l&#8217;environnement QTopia préparé par <a href="http://www.friendlyarm.net/" target="_blank">FriendlyARM</a> après avoir calibré l&#8217;écran tactile&#8230;Je ne détaille pas plus pour l&#8217;instant, ci-dessous deux photographies de l&#8217;écran sous QTopia :</p>
<p style="text-align: center;"><a href="http://innovelectronique.fr/wp-content/uploads/2011/07/accueil-qtopia.jpg" rel="lightbox[652]"><img class="alignnone size-thumbnail wp-image-686" title="accueil-qtopia" src="http://innovelectronique.fr/wp-content/uploads/2011/07/accueil-qtopia-150x150.jpg" alt="accueil-qtopia" width="150" height="150" /></a> <a href="http://innovelectronique.fr/wp-content/uploads/2011/07/onglet-friendlyarml-qtopia.jpg" rel="lightbox[652]"><img class="alignnone size-thumbnail wp-image-687" title="onglet-friendlyarml-qtopia" src="http://innovelectronique.fr/wp-content/uploads/2011/07/onglet-friendlyarml-qtopia-150x150.jpg" alt="onglet-friendlyarml-qtopia" width="150" height="150" /></a></p>
<p style="text-align: left;"><em>Remarque</em>: si l&#8217;interface est en chinois, il faut aller sur le deuxième onglet et cliquez sur le drapeau pour passer la langue en anglais (voir la capture d&#8217;écran de droite ci-dessus).</p>
<h2>Amorçage sur un système Android</h2>
<p>La carte est vendu comme étant compatible avec un système Android 2.1. Il faut donc charger le noyau et le &#8220;rootfs&#8221; android précompilé fourni sur le DVD. Il faut démarrer sur la NAND flash, interrompre U-Boot puis dans le menu proposé, choisir l&#8217;option &#8220;Download Linux/Android kernel&#8221; (lettre &#8216;k&#8217;) pour le noyau ou &#8220;Download root yaffs2 image&#8221; (lettre &#8216;y&#8217;) pour le système de fichier racine. U-Boot attend alors la connexion du cable USB. Le transfert du noyau ou du système de fichier racine s&#8217;effectue avec l&#8217;utilitaire DNW.exe disponible dans le répertoire &#8216;Tools&#8217; du DVD. Ce logiciel fonctionne sous Windows et nécessite l&#8217;installation d&#8217;un pilote lors de la première insertion du câble (disponible lui aussi sur le DVD dans &#8216;Tools&#8217;). Si la carte est reconnu par le logiciel DNW, vous verrez dans la barre de titre [USB:OK]. Vous pouvez alors transférer votre noyau ou votre système de fichiers racine avec le menu &#8216;USB Port&#8217; puis &#8216;Transmit/Restore&#8217;. Sous Linux, il existe un logiciel du nom de <a href="http://www.friendlyarm.net/dl.php?file=usbpush.zip" target="_blank">USBPUSH</a> qui a les mêmes fonctionnalités mais je ne l&#8217;ai pas utilisé.</p>
<p>Dans notre cas le noyau Linux s&#8217;appelle zImage_a70_New et le système de fichier racine rootfs_android.img. La trace de ces opérations est présenté ci-dessous :</p>
<pre>##### U-Boot 1.1.6 B01 for 6410, by esky-sh #####
[f] Format the nand flash[v] Download u-boot.bin
[k] Download Linux/Android kernel
[y] Download root yaffs2 image
[a] Download Absolute User Application
[n] Download Nboot.nb0 for WinCE
[w] Download WinCE NK.nb0
[s] Set the boot parameter of Linux
[b] Boot Linux
[q] Quit to shellNAND
Flash size: 256 MiB
Enter your Selection:k
Downloading Linux/Android Kernel from USB...
OTG cable Connected!
Download address 0xc0000000
Download Done!!
Download Address: 0xc0000000, Download Filesize:0x2b6c0c
Checksum is being calculated...
Checksum O.K.
Downloading Linux/Android Kernel successed
Writing Linux/Android Kernel into NAND...
Erasing at 0x80000 --   2% complete.Erasing at 0xa0000 ... -- 100% complete.

Writing data at 0x80000 --   0% complete.
Writing data at 0x87000
...
Writing data at 0x33f800 -- 100% complete.
Writing Linux/Android Kernel successed

##### U-Boot 1.1.6 B01 for 6410, by esky-sh #####
[f] Format the nand flash
[v] Download u-boot.bin
[k] Download Linux/Android kernel
[y] Download root yaffs2 image
[a] Download Absolute User Application
[n] Download Nboot.nb0 for WinCE
[w] Download WinCE NK.nb0
[s] Set the boot parameter of Linux
[b] Boot Linux[q] Quit to shell
NAND Flash size: 256 MiB
Enter your Selection:y
Downloading yaffs2-image from USB...
Insert a OTG cable into the connector!
OTG cable Connected!
Download address 0xc0000000
Download Done!!
Download Address: 0xc0000000, Download Filesize:0x5ae7b40
Checksum is being calculated.......
Checksum O.K.
Downloading yaffs2-image successed
Writing yaffs2-image into NAND...
Erasing at 0x580000 --   0% complete.Erasing at 0x800000
...
99% complete.Erasing at 0xffe0000 -- 100% complete.

Writing data at 0x580000 --   0% complete.Writing data at 0x661800
...
Writing data at 0x5da6000 -- 100% complete.
Writing yaffs2-image successed</pre>
<p>Remarques:</p>
<ul>
<li>On voit que le chargement des noyaux ou des images &#8216;rootfs&#8217; ce fait en mémoire vive à l&#8217;adresse 0xC0000000 donc la taille du noyau ou du rootfs ne pourra excéder 128Mo même si l&#8217;on dispose de plus en mémoire NAND. Il faudra donc passer par une étape intermédiaire pour flasher un rootfs plus gros que 128Mo dans la NAND (indice: passer par une mémoire SD).</li>
<li>On note aussi l&#8217;adresse dans la NAND à laquelle est stocké le noyau: adresse de début: 0&#215;80000 et adresse de fin:0xA0000 soit un espace de XX octets. Pour le rootfs on a: adresse de début: 0&#215;580000 et adresse de fin: 0xFFE0000 soit un espace de XX octets.</li>
<li>On retrouvera ces valeurs lors du boot du noyau linux lors de la découverte des &#8220;partitions&#8221; de la NAND</li>
</ul>
<p>On lance alors le système avec l&#8217;option &#8220;Boot linux&#8221; (lettre &#8216;b&#8217;). Si ça ne démarre pas, fixez les paramètres à passer au noyau avec &#8220;Set the boot parameter of Linux&#8221; (lettre &#8217;s&#8217;) comme suit:</p>
<pre>root=/dev/mtdblock2 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200</pre>
<p>On obtient les messages suivants:</p>
<pre>NAND read: device 0 offset 0x80000, size 0x500000
Reading data from 0x80000 --   0% complete
...
Reading data from 0x57f800 -- 100% complete. 5242880 bytes read:
OK
Boot with zImage
Starting kernel ...
Uncompressing Linux......................................................................
Done. Booting the kernel.Linux version 2.6.28.6 (root@NX-W-3) (gcc version 4.4.1 (Sourcery G++ Lite 2009q3-67) )
#3 Sat Mar 19 18:36:33 CST 2011CPU: ARMv6-compatible processor [410fb766] revision 6 (ARMv7), cr=00c5387f
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
Machine: SMDK6410
Memory policy: ECC disabled, Data cache writeback
CPU S3C6410 (id 0x36410101)
...
yaffs_read_super: isCheckpointed
0xres = 800, yres = 480Took 62 samples...
Top left : X = 3268 Y = 1504Took 50 samples...
Top right : X =  762 Y = 1522Took 42 samples...
Bot right : X =  760 Y = 2731Took 49 samples...
Bot left : X = 3282 Y = 2746Took 43 samples...
Center : X = 2031 Y = 2124959.654785
-0.278430 0.001384-419.278076 0.000
pointercal_ioctl: -18247 90 62891936 11 20317 -27477808 65536180 0.310019
init: cannot open '/initlogo.rle'
eth0: link down
sh: can't access tty; job control turned off
# warning: `rild' uses 32-bit capabilities (legacy support in use)
eth0: link up, 100Mbps, full-duplex, lpa 0xC5E1
# uname -a
Linux localhost 2.6.28.6 #3 Sat Mar 19 18:36:33 CST 2011 armv6l GNU/Linux
# free
              total         used         free       shared      buffers
Mem:       106952        38028        68924            0            0
Swap:            0            0            0
Total:       106952        38028        68924
# free
              total         used         free       shared      buffers
Mem:       106952       104704         2248            0            0
Swap:            0            0            0
Total:       106952       104704         2248
# reboot</pre>
<p>Remarques:</p>
<ul>
<li>Le noyau utilisé ici est un 2.6.28 compilé pour un SoC SMDK6410</li>
<li>L&#8217;écran tactile n&#8217;étant pas calibré vous passez par cette étape (lignes Top Left, Top Right, etc&#8230;)</li>
<li>La mémoire vive utilisé avant lancement de l&#8217;interface graphique d&#8217;android est de 38Mo, lorsque l&#8217;environnement est complètement chargé on est à 104Mo sur 106Mo utilisé ! D&#8217;où trés certainement les problèmes de lenteur&#8230;</li>
</ul>
<p>Après 1 minute vous avez l&#8217;écran d’accueil d&#8217;Android puis on vérifie la version du noyau :</p>
<p style="text-align: center;"><a href="http://innovelectronique.fr/wp-content/uploads/2011/07/accueil-android.jpg" rel="lightbox[652]"><img class="size-thumbnail wp-image-671 alignnone" title="accueil-android" src="http://innovelectronique.fr/wp-content/uploads/2011/07/accueil-android-150x150.jpg" alt="accueil-android" width="150" height="150" /></a> <a href="http://innovelectronique.fr/wp-content/uploads/2011/07/android-version.jpg" rel="lightbox[652]"><img class="size-thumbnail wp-image-672 alignnone" title="android-version" src="http://innovelectronique.fr/wp-content/uploads/2011/07/android-version-150x150.jpg" alt="android-version" width="150" height="150" /></a></p>
<p>Android fonctionne donc sur cette plateforme cependant la dalle tactile n&#8217;est pas très réactive et globalement le fonctionnement est très lent. Selon moi, il n&#8217;est donc pas utilisable dans l&#8217;état, le peu de mémoire vive est très certainement la cause de cette lenteur (voir remarques ci-dessus). Cela peut donc servir ponctuellement de plateforme de développement android mais sans plus. Cependant un accès shell &#8216;root&#8217; est disponible par le biais de la voie série.</p>
<p>Les tests préliminaires s&#8217;arrêtent ici&#8230;Je ne teste pas Windows CE sur cette plateforme car nous n&#8217;avons pas de projet dans l&#8217;immédiat avec celui-ci. Je passe donc maintenant à la partie la plus intéressante pour nous : la personnalisation de cette plateforme pour nos besoins spécifiques.</p>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2011/07/27/presentation-carte-tq6410-compatible-friendlyarm-mini-6410/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Carte fille pour module DIL Net/PC DNP9200</title>
		<link>http://innovelectronique.fr/2011/06/25/carte-fille-pour-module-dil-netpc-dnp9200/</link>
		<comments>http://innovelectronique.fr/2011/06/25/carte-fille-pour-module-dil-netpc-dnp9200/#comments</comments>
		<pubDate>Sat, 25 Jun 2011 13:03:45 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[Linux Embarqué]]></category>

		<category><![CDATA[DNP9200]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=621</guid>
		<description><![CDATA[Même si cela n’intéressera que très peu de monde, je met à disposition une carte fille que j&#8217;ai développé pour les modules DNP9200 de SSV Embedded. Vous trouverez sensiblement ces mêmes cartes en vente sur leur site mais bien sur pas au même prix. En france, le revendeur de ces cartes est Lextronic. Les photographies, [...]]]></description>
			<content:encoded><![CDATA[<p>Même si cela n’intéressera que très peu de monde, je met à disposition une carte fille que j&#8217;ai développé pour les modules DNP9200 de <a href="http://www.dilnetpc.com/" target="_blank">SSV Embedded</a>. Vous trouverez sensiblement ces mêmes cartes en vente sur leur site mais bien sur pas au même prix. En france, le revendeur de ces cartes est <a href="http://www.lextronic.fr/P856-module-dilnetpc-dnp9200.html" target="_blank">Lextronic</a>. Les photographies, schéma électrique et typon sont disponibles dans la suite de l&#8217;article.</p>
<p><span id="more-621"></span></p>
<p>Cette carte est réalisable avec des moyens classiques. Les deux circuits CMS et les deux petits condensateurs CMS sont soudables &#8220;à la main&#8221; sans trop de problèmes. Le circuit imprimé est en simple face avec des straps du coté composants. Tous les composants sont disponibles chez Farnell sauf le connecteur ethernet chez RS (RadioSpares).</p>
<p>Cette carte permet les connections suivantes:</p>
<ul>
<li>Sur connecteur HE10-10 ou barrette mâle: Port A sur 8 bits, Port B sur 8 bits, Port C sur 4 bits, Alimentation 3,3V et Masse</li>
<li>Ports série: le port série complet (tous les signaux sont gérés matierellement, COM1) est disponible sur une barrette mâle au niveau 3,3V ou sur un connecteur DB9 au niveau RS232. Le deuxième port série (COM2) ne dispose que des signaux TX/RX matériellement, il est possible de piloter les signaux RTS/CTS et DSR/DTR logiciellement, encore une fois en 3,3V ou RS232 sur le deuxième connecteur DB9.</li>
<li>USB Host et USB Device</li>
<li>Port ethernet 10/100 Mb/s</li>
<li>Support de pile pour la RTC embarqué (pile CR2032)</li>
<li>Connecteur pour carte SD/MMC</li>
<li>Alimentation 3,3V protégé jusqu&#8217;à 500mA et alimentation 5V jusqu&#8217;à 100mA</li>
</ul>
<p>Cette carte est exploitée dans le cadre de projet de fin d&#8217;étude de BTS IRIS avec comme thème &#8220;Linux Embarqué&#8221;.</p>
<p>Si vous souhaitez obtenir le circuit imprimé de cette carte ou une version complète assemblée (sans le module DNP9200), merci de me contacter par mél. Les documents de fabrication sont disponibles ci-dessous au format Proteus Isis et Ares 7.8, ainsi qu&#8217;au format PDF.</p>
<p><a href="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-perce-sans-composants.jpg" rel="lightbox[621]"><img class="aligncenter size-thumbnail wp-image-634" title="circuit-imprime-dnp9200-perce-sans-composants" src="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-perce-sans-composants-150x150.jpg" alt="circuit-imprime-dnp9200-perce-sans-composants" width="150" height="150" /></a><a href="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-avec-cms.jpg" rel="lightbox[621]"><img class="aligncenter size-thumbnail wp-image-630" title="circuit-imprime-dnp9200-avec-cms" src="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-avec-cms-150x150.jpg" alt="circuit-imprime-dnp9200-avec-cms" width="150" height="150" /></a><a href="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-complet.jpg" rel="lightbox[621]"><img class="aligncenter size-thumbnail wp-image-633" title="circuit-imprime-dnp9200-complet" src="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-complet-150x150.jpg" alt="circuit-imprime-dnp9200-complet" width="150" height="150" /></a><a href="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-complet-p1.jpg" rel="lightbox[621]"><img class="aligncenter size-thumbnail wp-image-631" title="circuit-imprime-dnp9200-complet-p1" src="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-complet-p1-150x150.jpg" alt="circuit-imprime-dnp9200-complet-p1" width="150" height="150" /></a><a href="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-complet-p2.jpg" rel="lightbox[621]"><img class="aligncenter size-thumbnail wp-image-632" title="circuit-imprime-dnp9200-complet-p2" src="http://innovelectronique.fr/wp-content/uploads/2011/06/circuit-imprime-dnp9200-complet-p2-150x150.jpg" alt="circuit-imprime-dnp9200-complet-p2" width="150" height="150" /></a></p>
<div class="attachments"><dl class="attachments attachments-large"><dt class="icon"><a title="carte-support-dnp9200" href="?aid=627&pid=621&sa=0"><img src="http://innovelectronique.fr/wp-content/plugins/eg-attachments/images/pdf.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="carte-support-dnp9200" href="?aid=627&pid=621&sa=0">carte-support-dnp9200</a><br /><strong>Fichier: </strong>carte-support-dnp9200.pdf<br /><strong>Taille: </strong>73 Ko</dd></dl><dl class="attachments attachments-large"><dt class="icon"><a title="carte-support-dnp9200" href="?aid=628&pid=621&sa=0"><img src="http://innovelectronique.fr/wp-includes/images/crystal/default.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="carte-support-dnp9200" href="?aid=628&pid=621&sa=0">carte-support-dnp9200</a><br /><strong>Fichier: </strong>carte-support-dnp9200.dsn<br /><strong>Taille: </strong>173 Ko</dd></dl><dl class="attachments attachments-large"><dt class="icon"><a title="carte-support-dnp9200" href="?aid=629&pid=621&sa=0"><img src="http://innovelectronique.fr/wp-includes/images/crystal/default.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="carte-support-dnp9200" href="?aid=629&pid=621&sa=0">carte-support-dnp9200</a><br /><strong>Fichier: </strong>carte-support-dnp9200.lyt<br /><strong>Taille: </strong>92 Ko</dd></dl><dl class="attachments attachments-large"><dt class="icon"><a title="carte-support-dnp9200-typon" href="?aid=626&pid=621&sa=0"><img src="http://innovelectronique.fr/wp-content/plugins/eg-attachments/images/pdf.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="carte-support-dnp9200-typon" href="?aid=626&pid=621&sa=0">carte-support-dnp9200-typon</a><br /><strong>Fichier: </strong>carte-support-dnp9200-typon.pdf<br /><strong>Taille: </strong>31 Ko</dd></dl><dl class="attachments attachments-large"><dt class="icon"><a title="carte-support-dnp9200-typon-et-implantation" href="?aid=625&pid=621&sa=0"><img src="http://innovelectronique.fr/wp-content/plugins/eg-attachments/images/pdf.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="carte-support-dnp9200-typon-et-implantation" href="?aid=625&pid=621&sa=0">carte-support-dnp9200-typon-et-implantation</a><br /><strong>Fichier: </strong>carte-support-dnp9200-typon-et-implantation.pdf<br /><strong>Taille: </strong>36 Ko</dd></dl></div>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2011/06/25/carte-fille-pour-module-dil-netpc-dnp9200/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Régulation de température - Couveuse à œufs</title>
		<link>http://innovelectronique.fr/2010/12/12/regulation-de-temperature/</link>
		<comments>http://innovelectronique.fr/2010/12/12/regulation-de-temperature/#comments</comments>
		<pubDate>Sun, 12 Dec 2010 21:18:29 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[µC PIC]]></category>

		<category><![CDATA[miel]]></category>

		<category><![CDATA[oeufs]]></category>

		<category><![CDATA[régulation]]></category>

		<category><![CDATA[température]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=581</guid>
		<description><![CDATA[Un collègue m&#8217;a récemment demandé si je pouvais lui faire un montage &#8220;pour pas cher&#8221; qui lui permette de réguler la température de sa couveuse à œufs ou encore de lui défiger son miel. Dans les deux cas le système doit juste commander une résistance chauffante voire une simple ampoule à incandescence pour maintenir la [...]]]></description>
			<content:encoded><![CDATA[<p>Un collègue m&#8217;a récemment demandé si je pouvais lui faire un montage &#8220;pour pas cher&#8221; qui lui permette de réguler la température de sa couveuse à œufs ou encore de lui défiger son miel. Dans les deux cas le système doit juste commander une résistance chauffante voire une simple ampoule à incandescence pour maintenir la température de consigne. La suite de l&#8217;article décrit cette réalisation.<span id="more-581"></span></p>
<p>Le cahier des charges était le suivant:</p>
<ul>
<li>l&#8217;ensemble doit rester à un prix abordable</li>
<li>le réglage de la température se fait à l&#8217;aide de deux boutons plutôt qu&#8217;un potentiomètre</li>
<li>la température de consigne et la température mesurée doivent être visualisées</li>
<li>la régulation de température doit se faire à +/- 0.2°C prés</li>
<li>la partie commande de puissance doit être isolée de la partie basse tension</li>
<li>le tout doit tenir dans un boitier plastique pour éviter le contact avec le secteur</li>
</ul>
<p>Les solutions retenues sont donc les suivantes:</p>
<ul>
<li>utilisation de composants standards facilement disponibles: un PIC16F886, un afficheur LCD 16&#215;2 standard, un capteur de température bon marché mais suffisamment précis sur bus I2C, un triac pour la commande de puissance</li>
<li>deux boutons poussoirs, un rouge et un bleu, serviront à régler la température de consigne ainsi que l&#8217;hystérésis</li>
<li>la visualisation de la température mesurée, de la température de consigne et de l&#8217;hystérésis se font à l&#8217;aide d&#8217;un afficheur LCD alphanumérique 2 lignes de 16 caractères (afficheur 16&#215;2). Le contraste est réglable par un potentiomètre</li>
<li>la sonde de température sera un DS1621 sur bus I2C. On utilisera un mode de mesure particulier pour obtenir une meilleure précision (de l&#8217;ordre de +/- 0.1°C)</li>
<li>l&#8217;isolation entre la partie basse tension et haute tension se fera à l&#8217;aide d&#8217;un optotriac MOC3021</li>
<li>une DEL visualisera la mise en et hors tension de la résistance chauffante</li>
<li>le tout tient dans un boitier plastique transparent de chez Hammond</li>
<li>enfin la régulation se fera par hystérésis et non sous forme d&#8217;un PID</li>
<li>l&#8217;alimentation se fera à l&#8217;aide de n&#8217;importe quel bloc secteur du commerce pouvant fournir une tension alternative ou continu de 9V sous 200mA</li>
<li>les connections se font à l&#8217;aide de bornier à vis</li>
</ul>
<p>J&#8217;obtiens donc le schéma électrique suivant:</p>
<p style="text-align: center;"><a href="http://innovelectronique.fr/wp-content/uploads/2010/12/couveuse-regulation-temp.png" rel="lightbox[581]"></a><a href="http://innovelectronique.fr/wp-content/uploads/2010/12/couveuse-regulation-temp3.png" rel="lightbox[581]"><img class="aligncenter size-thumbnail wp-image-608" title="Schéma électrique du régulateur de température" src="http://innovelectronique.fr/wp-content/uploads/2010/12/couveuse-regulation-temp3-150x150.png" alt="Schéma électrique du régulateur de température" width="150" height="150" /></a></p>
<p>Première remarque: le capteur de température analogique LM35 du schéma n&#8217;est pas câblé sur le prototype final. C&#8217;était juste &#8220;au cas où&#8221; je n&#8217;aurais pas été satisfait du capteur I2C. En adaptant le code C, on peut supprimer le capteur I2C et le remplacer par ce capteur. La précision par contre sera bien moindre.</p>
<p>Deuxième remarque: la résistance R9 du schéma est un résistance de rappel au plus. Elle n&#8217;est pas câblée dans le prototype final car la sortie RA4 du PIC16F886 n&#8217;est pas une sortie à collecteur ouvert. Par contre si vous changez de PIC, par exemple pour un 16F876, cette résistance est indispensable pour piloter correctement l&#8217;afficheur LCD.</p>
<p>Troisième remarque: le réseau R7-C7 permet au triac d&#8217;encaisser un &#8220;dV/dT&#8221; important, c&#8217;est-à-dire une montée rapide de la tension. Il est surtout utile si le triac commande une charge inductive. Suivant le modèle de triac employé (&#8221;snubberless&#8221; ou non: voir dans la documentation constructeur du triac) ce réseau est nécessaire ou non. Ici on pourrait le supprimer car on doit commander un élément purement résistif mais comme on ne sait jamais ce circuit protègera le triac.</p>
<p>Quatrième remarque: les fusibles FU1 et FU2 sont en fait des fusibles &#8220;polyswitch&#8221;. Le<a href="http://claude.dreschel.free.fr/composants/polyswitch.htm" target="_blank"> fusible polyswitch</a> s&#8217;ouvre lorsque sa température interne dépasse 110°C. Cette augmentation de température peut être du à un courant fort le traversant. Lorsque le polyswitch refroidi, il retrouve sa conductivité. Il remplace donc un fusible classique. Par contre le temps de réaction de ces fusibles peut être assez long (de l&#8217;ordre de la seconde) donc s&#8217;il faut protéger un système de manière très rapide, le fusible rapide reste la meilleure solution.</p>
<p>Un exemple de routage et une réalisation du typon sont présentés ci-dessous:</p>
<p style="text-align: center;"><a href="http://innovelectronique.fr/wp-content/uploads/2010/12/typon-couveuse.jpg" rel="lightbox[581]"><img class="size-thumbnail wp-image-583 aligncenter" title="Exemple de typon et Circuit imprimé du prototype" src="http://innovelectronique.fr/wp-content/uploads/2010/12/typon-couveuse-150x150.jpg" alt="Exemple de typon et Circuit imprimé du prototype" width="150" height="150" /></a></p>
<p>Remarque: Sur le typon ci-dessus, il manque trois composants: les fusibles FU1, FU2 et la diode zener de protection D2. Sur le routage Ares présenté à la fin de cet article, ces composants sont bien implantés.</p>
<p>Le prototype final se présente de la manière suivante:</p>
<table border="0">
<tbody>
<tr>
<td><a href="http://innovelectronique.fr/wp-content/uploads/2010/12/face-avant-couveuse.jpg" rel="lightbox[581]"><img class="alignleft size-thumbnail wp-image-610" title="Face avant du régulateur dee température" src="http://innovelectronique.fr/wp-content/uploads/2010/12/face-avant-couveuse-150x150.jpg" alt="Face avant du régulateur dee température" width="150" height="150" /></a></td>
<td>Dans la photographie ci-contre, vous voyez les boutons de réglage de l&#8217;hysteresis et de la consigne : bouton bleu (-) et bouton rouge (+). L&#8217;écran LCD est visible à travers le capot du boitier. Sur le coté droit, vous avez l&#8217;arrivée du 220V et la sortie vers la charge résistive. Sur le coté gauche, vous avez le fil d&#8217;alimentation de l&#8217;électronique basse tension issu d&#8217;un &#8220;bloc secteur&#8221; de récupération et le fil qui part vers le capteur I2C de température (cordon de souris usagé). Le porte fusible à l&#8217;intérieur n&#8217;est pas câblé, c&#8217;était juste un essai d&#8217;encombrement <img src='http://innovelectronique.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </td>
</tr>
<tr>
<td><a href="http://innovelectronique.fr/wp-content/uploads/2010/12/cote-droit-couveuse.jpg" rel="lightbox[581]"><img class="alignleft size-thumbnail wp-image-611" title="Coté droit du régulateur de température" src="http://innovelectronique.fr/wp-content/uploads/2010/12/cote-droit-couveuse-150x150.jpg" alt="Coté droit du régulateur de température" width="150" height="150" /></a></td>
<td>Sur le coté droit du boitier, on voit les câbles &#8220;secteur&#8221; : l&#8217;arrivée 220V à gauche et le départ vers la charge résistive à droite. Les fils sont introduits dans des borniers à vis et le boitier est percé en conséquence.</td>
</tr>
<tr>
<td><a href="http://innovelectronique.fr/wp-content/uploads/2010/12/cote-gauche-couveuse.jpg" rel="lightbox[581]"><img class="alignleft size-thumbnail wp-image-612" title="Coté gauche du régulateur de température" src="http://innovelectronique.fr/wp-content/uploads/2010/12/cote-gauche-couveuse-150x150.jpg" alt="Coté gauche du régulateur de température" width="150" height="150" /></a></td>
<td>Sur le coté gauche du boitier vous trouvez le bornier pour l&#8217;alimentation continue issue d&#8217;un bloc secteur quelconque fournissant une tension de 7V à 20V continu ou alternatif sous 200mA. Le fil blanc du capteur de température a été récupéré sur une vieille souris.</td>
</tr>
<tr>
<td><a href="http://innovelectronique.fr/wp-content/uploads/2010/12/face-arriere-couveuse.jpg" rel="lightbox[581]"><img class="alignleft size-thumbnail wp-image-613" title="Face arrière du régulateur de température" src="http://innovelectronique.fr/wp-content/uploads/2010/12/face-arriere-couveuse-150x150.jpg" alt="Face arrière du régulateur de température" width="150" height="150" /></a></td>
<td>Les composants sont visibles sur le dessous du boitier. Vous reconnaitrez le PIC16F886, le régulateur linéaire 5V au dessus de lui, le triac sur la droite. Le CI blanc est l&#8217;optotriac. Enfin si vous êtes observateur (la photographie est relativement floue), vous verrez que le boitier est percé pour utiliser un tournevis plat pour serrer les câbles dans les différents borniers ainsi que pour le réglage du contraste de l&#8217;afficheur LCD.</td>
</tr>
</tbody>
</table>
<p>Un petit test avant de mettre le tout dans son boitier plastique :</p>
<p><iframe title="YouTube video player" width="425" height="349" src="http://www.youtube.com/embed/uQyfsEyHxBI?rel=0" frameborder="0" allowfullscreen></iframe></p>
<p>Je met en pièce jointe le schéma électrique ainsi que le routage au format Proteus 7.4 (Isis et Ares). Le code C de l&#8217;application a été développé avec CCS et est disponible sur demande.</p>
<p>Comme d&#8217;habitude si vous êtes intéressé par cette réalisation, vous pouvez obtenir un kit complet ou partiel en me contactant. Le prix du kit complet pour ce montage (CI percé et composants : PIC programmé) s&#8217;élève à 60euros.</p>
<div class="attachments"><dl class="attachments attachments-large"><dt class="icon"><a title="couveuse-regulation-temp" href="?aid=589&pid=581&sa=0"><img src="http://innovelectronique.fr/wp-includes/images/crystal/default.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="couveuse-regulation-temp" href="?aid=589&pid=581&sa=0">couveuse-regulation-temp</a><br /><strong>Fichier: </strong>couveuse-regulation-temp.dsn<br /><strong>Taille: </strong>154 Ko</dd></dl><dl class="attachments attachments-large"><dt class="icon"><a title="couveuse-regulation-temp" href="?aid=590&pid=581&sa=0"><img src="http://innovelectronique.fr/wp-includes/images/crystal/default.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="couveuse-regulation-temp" href="?aid=590&pid=581&sa=0">couveuse-regulation-temp</a><br /><strong>Fichier: </strong>couveuse-regulation-temp.lyt<br /><strong>Taille: </strong>85 Ko</dd></dl></div>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2010/12/12/regulation-de-temperature/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Pinguino et matrice de DELs</title>
		<link>http://innovelectronique.fr/2010/11/01/pinguino-et-matrice-de-dels/</link>
		<comments>http://innovelectronique.fr/2010/11/01/pinguino-et-matrice-de-dels/#comments</comments>
		<pubDate>Mon, 01 Nov 2010 13:50:50 +0000</pubDate>
		<dc:creator>Olivier</dc:creator>
		
		<category><![CDATA[µC PIC]]></category>

		<category><![CDATA[Afficheur DELS]]></category>

		<category><![CDATA[Pinguino]]></category>

		<guid isPermaLink="false">http://innovelectronique.fr/?p=569</guid>
		<description><![CDATA[Dans cet article j&#8217;ai présenté un module pré-assemblé qui pilote une matrice de DELs. J&#8217;avais aussi réalisé un circuit PINGUINO parce que le concept &#8220;OpenHardware&#8221; et &#8220;OpenSoftWare&#8221; me convient par rapport à ma philosophie du partage du savoir. Donc pourquoi ne pas utiliser les deux dans mon premier véritable projet avec Pinguino&#8230;Voici à quoi ressemble [...]]]></description>
			<content:encoded><![CDATA[<p>Dans cet <a href="http://innovelectronique.fr/2010/10/29/afficheur-alphanumerique-a-dels-defilant/" target="_blank">article</a> j&#8217;ai présenté un module pré-assemblé qui pilote une matrice de DELs. J&#8217;avais aussi réalisé un circuit <a href="http://www.hackinglab.org/" target="_blank">PINGUINO</a> parce que le concept &#8220;OpenHardware&#8221; et &#8220;OpenSoftWare&#8221; me convient par rapport à ma philosophie du partage du savoir. Donc pourquoi ne pas utiliser les deux dans mon premier véritable projet avec Pinguino&#8230;<span id="more-569"></span>Voici à quoi ressemble le montage en deux photos. Vous remarquerez que c&#8217;est très simple&#8230;seulement trois fils en dehors des alimentations.</p>
<p><div id="attachment_570" class="wp-caption alignnone" style="width: 310px"><a href="http://innovelectronique.fr/wp-content/uploads/2010/11/module-pinguino-et-afficheur.jpg" rel="lightbox[569]"><img class="size-medium wp-image-570 " title="Module Pinguino avec le module à DELs" src="http://innovelectronique.fr/wp-content/uploads/2010/11/module-pinguino-et-afficheur-300x207.jpg" alt="Module Pinguino avec le module à DELs" width="300" height="207" /></a>Module Pinguino avec le module à DELs</dt>
</dl>
</div>
<div class="mceTemp">
<dl id="attachment_572" class="wp-caption alignnone" style="width: 310px;">
<dt class="wp-caption-dt"><a href="http://innovelectronique.fr/wp-content/uploads/2010/11/module-pinguino-et-afficheur-en-fonction1.jpg" rel="lightbox[569]"><img class="size-medium wp-image-572" title="Afficheur piloté par le Puinguino" src="http://innovelectronique.fr/wp-content/uploads/2010/11/module-pinguino-et-afficheur-en-fonction1-300x230.jpg" alt="Afficheur piloté par le Puinguino" width="300" height="230" /></a><p class="wp-caption-text">Afficheur piloté par le Puinguino</p></div></p>
<p>Bien sur la petite vidéo qui va bien <img src='http://innovelectronique.fr/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> :<br />
<object width="425" height="344" data="http://www.youtube.com/v/02VzvK478Q0?hl=fr&amp;fs=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/02VzvK478Q0?hl=fr&amp;fs=1" /><param name="allowfullscreen" value="true" /></object></p>
<p>En fin d&#8217;article vous trouverez trois programmes :</p>
<ul>
<li>le premier programme montre comment faire un BarGraph</li>
<li>le deuxième simule un analyseur de spectre</li>
<li>le troisième est celui de la vidéo ci-dessus</li>
</ul>
<p>Si vous souhaitez un module pinguino ou le circuit imprimé (percé ou non) n&#8217;hésitez pas à me contacter.</p>
<p>Bonne lecture et bon test !</p>
<div class="attachments"><dl class="attachments attachments-large"><dt class="icon"><a title="scrolling.pde" href="?aid=579&pid=569&sa=0"><img src="http://innovelectronique.fr/wp-includes/images/crystal/default.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="scrolling.pde" href="?aid=579&pid=569&sa=0">scrolling.pde</a><br /><strong>Fichier: </strong>scrolling.pde<br /><strong>Taille: </strong>10 Ko</dd></dl><dl class="attachments attachments-large"><dt class="icon"><a title="simuspectre.pde" href="?aid=578&pid=569&sa=0"><img src="http://innovelectronique.fr/wp-includes/images/crystal/default.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="simuspectre.pde" href="?aid=578&pid=569&sa=0">simuspectre.pde</a><br /><strong>Fichier: </strong>simuspectre.pde<br /><strong>Taille: </strong>4 Ko</dd></dl><dl class="attachments attachments-large"><dt class="icon"><a title="test-afficheur-pinguino.pde" href="?aid=577&pid=569&sa=0"><img src="http://innovelectronique.fr/wp-includes/images/crystal/default.png" width="48" height="48" alt="" /></a></dt><dd class="caption"><strong>Titre: </strong><a title="test-afficheur-pinguino.pde" href="?aid=577&pid=569&sa=0">test-afficheur-pinguino.pde</a><br /><strong>Fichier: </strong>test-afficheur-pinguino.pde<br /><strong>Taille: </strong>2 Ko</dd></dl></div>
]]></content:encoded>
			<wfw:commentRss>http://innovelectronique.fr/2010/11/01/pinguino-et-matrice-de-dels/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

