<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://wikifr.techno-innov.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nathael</id>
	<title>Wiki Techno-Innov - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://wikifr.techno-innov.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Nathael"/>
	<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php/Sp%C3%A9cial:Contributions/Nathael"/>
	<updated>2026-04-04T04:23:23Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/Module_RFSub1G&amp;diff=166</id>
		<title>Products/Module RFSub1G</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/Module_RFSub1G&amp;diff=166"/>
		<updated>2023-01-22T19:42:00Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « {{DISPLAYTITLE:Module RF-Sub1GHz}} right  == Description == Le module &amp;quot;RF-Sub1GHz&amp;quot; est un module de communication RF (Radio-Fréquence)... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Module RF-Sub1GHz}}&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
Le module &amp;quot;RF-Sub1GHz&amp;quot; est un module de communication RF (Radio-Fréquence) qui utilise l&#039;émetteur-récepteur sans-fil CC1101 de Texas Instruments et le microcontrôleur LPC1224 de NXP.&amp;lt;br /&amp;gt;&lt;br /&gt;
Il est décliné en trois version :&lt;br /&gt;
* UEXT&lt;br /&gt;
* USB&lt;br /&gt;
* Standalone&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
* Connecteur P2&lt;br /&gt;
* Connecteur P3&lt;br /&gt;
* Connecteur P4&lt;br /&gt;
* Connecteur P5&lt;br /&gt;
* Connecteur P6&lt;br /&gt;
* Connecteur P7&lt;br /&gt;
==== Slot micro-SD ====&lt;br /&gt;
* Slot J1&lt;br /&gt;
==== Jumpers ====&lt;br /&gt;
* Jumper J1&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
==== Micro-contrôlleur LPC1224 ====&lt;br /&gt;
==== RAM interne ====&lt;br /&gt;
==== Mémoire Flash interne ====&lt;br /&gt;
==== Interfaces de communication ====&lt;br /&gt;
==== GPIO ====&lt;br /&gt;
==== ADC ====&lt;br /&gt;
==== Reset et mode ISP ====&lt;br /&gt;
==== Contrôleur RF Sub1GHz CC1101 ====&lt;br /&gt;
==== I²C ====&lt;br /&gt;
* Adresses I²C&lt;br /&gt;
* EEPROM externe&lt;br /&gt;
* Capteur de température&lt;br /&gt;
==== Boutons et Led utilisateur ====&lt;br /&gt;
==== Bridge USB-UART ====&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
==== Récupération des sources ====&lt;br /&gt;
==== Organisation des sources ====&lt;br /&gt;
==== Point d&#039;entrée ====&lt;br /&gt;
==== Exemples ====&lt;br /&gt;
==== Compilation ====&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=165</id>
		<title>Products</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=165"/>
		<updated>2023-01-22T19:29:05Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Liste des produits}}&lt;br /&gt;
== Projet &amp;quot;Scialys&amp;quot; ==&lt;br /&gt;
* [[Products/Module_Scialys|Module Scialys]]&lt;br /&gt;
[[Image:Module_Scialys.jpg|100px|left]]&lt;br /&gt;
: Le module principal du système Scialys (système d&#039;optimisation de l&#039;auto-consommation).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Extensions miniPC ==&lt;br /&gt;
* [[Products/PiSerialPower|Extension &amp;quot;PiSerialPower&amp;quot;]]&lt;br /&gt;
[[Image:PiserialPower.jpg|100px|left]]&lt;br /&gt;
: Extension d&#039;alimentation (mais pas que) pour cartes RaspberryPi (et modèles concurrents compatibles).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules de développement ==&lt;br /&gt;
* [[Products/Module_GPIO_Demo|Module GPIO Démo]]&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|100px|left]]&lt;br /&gt;
: Le module GPIO pour le DomoTab et le [[Products/DTPlug|DTPlug]].&lt;br /&gt;
: Le module GPIO-Démo est un module de développement pour les modules de communication du projet DomoTab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224BO|LPC1224 Break-Out]]&lt;br /&gt;
[[Image:LPC1224-BO.jpg|100px|left]]&lt;br /&gt;
: La carte de développement LPC1224 Break-Out : un module de développement autonome (un port USB suffit) pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224mbed|LPC1224-mbed]]&lt;br /&gt;
[[Image:LPC1224-mbed.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224-mbed : une version &amp;quot;mbed ready du module de développement autonome pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/USB_UART|Adaptateur USB-UART]]&lt;br /&gt;
[[Image:USBtoUART.jpg|100px|left]]&lt;br /&gt;
: Adaptateur USB vers UART, et potentiellement UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules de communication ==&lt;br /&gt;
* [[Products/Module_RFSub1G|Module RF Sub-1GHz]]&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|100px|left]]&lt;br /&gt;
: Le module RF, version Standalone, USB, ou UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_1Wire|Module 1Wire]]&lt;br /&gt;
[[Image:Module_1Wire.jpg|100px|left]]&lt;br /&gt;
: Module 1Wire au format UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RS485|Module RS485]]&lt;br /&gt;
[[Image:Module_RS485.jpg|100px|left]]&lt;br /&gt;
: Module RS485 au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_KNX|Module KNX]]&lt;br /&gt;
[[Image:Module_KNX.jpg|100px|left]]&lt;br /&gt;
: Module KNX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_DMX|Module DMX]]&lt;br /&gt;
[[Image:Module_DMX.jpg|100px|left]]&lt;br /&gt;
: Module DMX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_CPL|Module CPL]]&lt;br /&gt;
[[Image:Module_CPL.jpg|100px|left]]&lt;br /&gt;
: Module CPL (Courant porteur) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Projet &amp;quot;DomoTab&amp;quot; ==&lt;br /&gt;
* [[Products/DTPlug|Le DTPlug]]&lt;br /&gt;
[[Image:DTPlug.png|100px|left]]&lt;br /&gt;
: Passerelle DTPlug : Ethernet ---&amp;gt; 4x UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PSMC|Module PSMC : Power Supply Monitor &amp;amp; Control]]&lt;br /&gt;
[[Image:PSMC.jpg|100px|left]]&lt;br /&gt;
: Module PSMC pour alimentation d&#039;un module de communication, mesure de courant (consommation) et contrôle d&#039;une prise (Nécessite un module de communication pour fonctionner).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Adaptateurs divers ==&lt;br /&gt;
* [[Products/Adaptateur_Thermocouple|Adaptateur Thermocouple]]&lt;br /&gt;
[[Image:Adaptateur_Thermocouple.jpg|100px|left]]&lt;br /&gt;
: Adaptateur Thermocouples pour mesure de température (nécessite un module de communication pour fonctionner).&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=164</id>
		<title>Products/PiSerialPower</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=164"/>
		<updated>2021-09-22T09:53:14Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Extension PiSerialPower}}&lt;br /&gt;
[[Image:PiserialPower.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Intro ==&lt;br /&gt;
La [http://wiki.techno-innov.fr/index.php/Products/PiSerialPower page de l&#039;adaptaeur Pi Serial Power sur le Wiki en Anglais] est à jour. Celle-ci est en attente de traduction.&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
&lt;br /&gt;
=== Électronique ===&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Hat_v02-02.jpg Image en fonctionnement]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower.pdf Documentation technique] (en anglais seulement)&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Schematics.pdf Schéma électronique de la carte]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Board.pdf Routage de la carte électronique]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Schematics.tar.bz2 Sources de la carte électronique au format KiCaD]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/eeprom_settings.txt Fichier eeprom_settings.txt]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/overlay.dts Fichier overlay.dts]&lt;br /&gt;
&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=163</id>
		<title>Products/PiSerialPower</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=163"/>
		<updated>2021-09-22T08:58:12Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Documentation Technique et Schémas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Extension PiSerialPower}}&lt;br /&gt;
[[Image:PiserialPower.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
&lt;br /&gt;
=== Électronique ===&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Hat_v02-02.jpg Image en fonctionnement]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower.pdf Documentation technique] (en anglais seulement)&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Schematics.pdf Schéma électronique de la carte]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Board.pdf Routage de la carte électronique]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Schematics.tar.bz2 Sources de la carte électronique au format KiCaD]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/eeprom_settings.txt Fichier eeprom_settings.txt]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/overlay.dts Fichier overlay.dts]&lt;br /&gt;
&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=162</id>
		<title>Products/PiSerialPower</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=162"/>
		<updated>2021-09-22T08:57:29Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Documentation Technique et Schémas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Extension PiSerialPower}}&lt;br /&gt;
[[Image:PiserialPower.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
&lt;br /&gt;
=== Électronique ===&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Hat_v02-02.jpg Image en fonctionnement]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower.pdf Documentation technique] (en anglais seulement)&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Schematics.pdf Schéma électronique de la carte]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Board.pdf Routage de la carte électronique]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/PiSerialPower_Schematics.tar.bz2 Source de la carte électronique au format KiCaD]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/eeprom_settings.txt Fichier eeprom_settings.txt]&lt;br /&gt;
* [http://techdata.techno-innov.fr/Adapters/PiSerialPower/overlay.dts Fichier overlay.dts]&lt;br /&gt;
&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/USB_UART&amp;diff=161</id>
		<title>Products/USB UART</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/USB_UART&amp;diff=161"/>
		<updated>2021-03-25T00:56:23Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Utilisation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Adaptateur USB-UART}}&lt;br /&gt;
[[Image:USBtoUART.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
L&#039;adaptateur USB-UART est un adaptateur simple et utile donnant accès à une liaison série (UART 3.3V) à partir d&#039;un port USB, incluant un accès aux alimentations 3.3V et 5.0V pour tous vos besoins de prototypage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cet adaptateur utilise le composant FTDI FT230XS et dispose de deux connecteurs USB différents, USB A ou micro-USB (Les deux connecteurs sont montés en même temps, mais un seul peut être utilisé à un moment donné, ne connectez jamais les deux simultanément !)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ce composant devrait aussi supporter l&#039;I2C, le SPI, et d&#039;autres protocoles/bus de données, et nous avons donc mis un connecteur UEXT, cependant cela nécessitera quelques développements logiciels. Nous vous tiendrons au courant des évolutions.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== Connecteurs ==&lt;br /&gt;
=== Connecteur P1 ===&lt;br /&gt;
[[Image:USB_UART_V02_P1.png|300px|right]]&lt;br /&gt;
P1 est un connecteur standard au pas de 2.54mm (0.1 inch), avec 2 colonnes de 5 pins.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot;|Connecteur P1&lt;br /&gt;
|-&lt;br /&gt;
| Pin #&lt;br /&gt;
| Description&lt;br /&gt;
| FT230XS signal&lt;br /&gt;
| Note&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| +3.3V from FT230XS&lt;br /&gt;
| +3.3V Out&lt;br /&gt;
| --&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| GND - Ground&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| UART Tx&lt;br /&gt;
| TxD&lt;br /&gt;
| FT230XS pin 1&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| UART Rx&lt;br /&gt;
| RxD&lt;br /&gt;
| FT230XS pin 4&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| I2C SCL&lt;br /&gt;
| RTS&lt;br /&gt;
| FT230XS pin 2&lt;br /&gt;
|-&lt;br /&gt;
| 6&lt;br /&gt;
| I2C SDA&lt;br /&gt;
| CTS&lt;br /&gt;
| FT230XS pin 6&lt;br /&gt;
|-&lt;br /&gt;
| 7&lt;br /&gt;
| SPI MISO&lt;br /&gt;
| Sleep&lt;br /&gt;
| FT230XS pin 16&lt;br /&gt;
|-&lt;br /&gt;
| 8&lt;br /&gt;
| SPI MOSI&lt;br /&gt;
| TxDEN&lt;br /&gt;
| FT230XS pin 15&lt;br /&gt;
|-&lt;br /&gt;
| 9&lt;br /&gt;
| SPI CLK&lt;br /&gt;
| RxLed&lt;br /&gt;
| FT230XS pin 14&lt;br /&gt;
|-&lt;br /&gt;
| 10&lt;br /&gt;
| SPI CS&lt;br /&gt;
| Tx Led&lt;br /&gt;
| FT230XS pin 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connecteur P2 ===&lt;br /&gt;
[[Image:USB_UART_V02_P2.png|300px|right]]&lt;br /&gt;
P2 est un connecteur standard au pas de 2.54mm (0.1 inch), avec 1 colonne de 2 pins, qui donne accès au 5V de l&#039;USB.&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; : Attention ! ne connectez jamais les deux pins de ce connecteur ensemble (comme pour un jumper) car cela cour-circuiterait l&#039;alimentation USB, provoquant la destruction du filtre présent en entrée (FB1).&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;3&amp;quot;|Connecteur P2&lt;br /&gt;
|-&lt;br /&gt;
| Pin #&lt;br /&gt;
| Description&lt;br /&gt;
| Note&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| +5V&lt;br /&gt;
| +5V from USB&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| GND&lt;br /&gt;
| Ground&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Connecteur P3 : micro USB debug ===&lt;br /&gt;
P3 est un port USB microB.&amp;lt;br /&amp;gt;&lt;br /&gt;
Consultez la page [http://fr.wikipedia.org/wiki/Universal_Serial_Bus Universal Serial Bus (USB)] sur Wikipedia pour plus d&#039;informations sur le BUS USB et les connecteurs USB.&lt;br /&gt;
&lt;br /&gt;
=== Connecteur P4 : USB type A debug ===&lt;br /&gt;
P4 est un port USB type A male.&amp;lt;br /&amp;gt;&lt;br /&gt;
Consultez la page [http://fr.wikipedia.org/wiki/Universal_Serial_Bus Universal Serial Bus (USB)] sur Wikipedia pour plus d&#039;informations sur le BUS USB et les connecteurs USB.&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
* Documentation technique&lt;br /&gt;
* Support des protocoles I2C et SPI via les capacités de &amp;quot;bit-banging&amp;quot; du FTDI (soft PC)&lt;br /&gt;
* Support SWD et/ou JTAG&lt;br /&gt;
* Version avec RS232&lt;br /&gt;
* Version avec alimentation 1.8V (pour l&#039;alimentation de microprocesseurs et le debug SWD/JTAG)&lt;br /&gt;
&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
La documentation technique de ce produit est à rédiger&lt;br /&gt;
&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=MediaWiki:Sidebar&amp;diff=160</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=MediaWiki:Sidebar&amp;diff=160"/>
		<updated>2020-09-03T22:06:24Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* navigation&lt;br /&gt;
** mainpage|Accueil&lt;br /&gt;
* Techno-Innov&lt;br /&gt;
** Products|Produits&lt;br /&gt;
** Technique|Technique&lt;br /&gt;
* Publications&lt;br /&gt;
** Articles|Articles&lt;br /&gt;
* Suivi des modifications&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Politique_de_confidentialit%C3%A9&amp;diff=159</id>
		<title>Wiki Techno-Innov FR:Politique de confidentialité</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Politique_de_confidentialit%C3%A9&amp;diff=159"/>
		<updated>2020-09-03T15:38:53Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Licence ==&lt;br /&gt;
Le contenu de ce Wiki est accessible à tous, et placé sous licence [http://creativecommons.org/licenses/by-sa/4.0/ Creative Commons attribution partage à l&#039;identique].&lt;br /&gt;
&lt;br /&gt;
== Responsabilités ==&lt;br /&gt;
Nous demandons aux auteurs de ne pas se cacher derrière des pseudonymes ou un faux nom. Ce que vous écrivez sur Internet engage votre responsabilité.&lt;br /&gt;
&lt;br /&gt;
Faites attention à ce que vous écrivez, ne publiez pas d&#039;informations sensibles, et en général, n&#039;importunez pas les personnes, qu&#039;il s&#039;agisse d&#039;autres auteurs ou de simples passants.&lt;br /&gt;
&lt;br /&gt;
== Partage ==&lt;br /&gt;
Encore une fois, le contenu de ce Wiki est accessible à tous, et placé sous licence [http://creativecommons.org/licenses/by-sa/4.0/ Creative Commons attribution partage à l&#039;identique].&amp;lt;br /&amp;gt;&lt;br /&gt;
Vous pouvez donc lire son contenu sans limitation, le modifier si vous acceptez cette licence pour vos modifications et publications et que vous en avez la possibilité (contactez nous si vous n&#039;avez pas de compte, voir message en page d&#039;accueil), et même copier tout ou partie de son contenu si vous respectez la licence sous laquelle celui-ci est placé : Vous devez citer vos sources et leur(s) auteur(s), et placer le résultat - &#039;&#039;&#039;la totalité du résultat&#039;&#039;&#039; - sous la même licence.&lt;br /&gt;
&lt;br /&gt;
Sinon, merci de passer votre chemin, et n&#039;importunez pas les personnes présentes.&lt;br /&gt;
&lt;br /&gt;
== Confidentialité et données personnelles ==&lt;br /&gt;
Techno-Innov ne conserve aucune donnée personnelle vous concernant du fait de l&#039;utilisation de ce site.&lt;br /&gt;
&lt;br /&gt;
Seuls les cookies strictement nécessaires au fonctionnement du site sont utilisés. Ils ne contiennent aucune information personnelle et ne permettent pas de vous identifier.&lt;br /&gt;
&lt;br /&gt;
Si cela ne vous convient pas, merci d&#039;aller voir ailleurs.&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Copyrights&amp;diff=158</id>
		<title>Wiki Techno-Innov FR:Copyrights</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Copyrights&amp;diff=158"/>
		<updated>2020-09-03T15:32:39Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « Voir : ici ! »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Voir : [[Wiki_Techno-Innov_FR:Politique_de_confidentialité|ici]] !&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Avertissements_g%C3%A9n%C3%A9raux&amp;diff=157</id>
		<title>Wiki Techno-Innov FR:Avertissements généraux</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Avertissements_g%C3%A9n%C3%A9raux&amp;diff=157"/>
		<updated>2020-09-03T15:17:08Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « Le contenu présent sur ce site est fourni tel quel, sans AUCUNE garantie d&amp;#039;aucune sorte.  Les mises à jour sont faites occasionnellement, quand nous en avons le temps, e... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le contenu présent sur ce site est fourni tel quel, sans AUCUNE garantie d&#039;aucune sorte.&lt;br /&gt;
&lt;br /&gt;
Les mises à jour sont faites occasionnellement, quand nous en avons le temps, et le contenu présent sur ce site peut ne pas être à jour, et être modifié sans préavis (mais c&#039;est un Wiki !)&lt;br /&gt;
&lt;br /&gt;
Bonne lecture !&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Accueil&amp;diff=156</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Accueil&amp;diff=156"/>
		<updated>2020-09-03T15:13:44Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Bienvenue sur le Wiki de la communauté Techno-Innov}}&lt;br /&gt;
&amp;lt;div id=&amp;quot;mainpage_topbox&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mainpage_boxcontents&amp;quot;&amp;gt;&lt;br /&gt;
Ce wiki est destiné à simplifier et organiser la diffusion d&#039;informations autour de nos projets et produits.&lt;br /&gt;
&lt;br /&gt;
Vous retrouverez ici des pages relatives à chacun des produits de Techno-Innov, des pages plus générales sur certains points techniques, et la série d&#039;articles sur le &amp;quot;Making of&amp;quot; du module GPIO-Démo.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| role=&amp;quot;presentation&amp;quot; style=&amp;quot;border:0; margin: 0; width: 100%; border-spacing: 10px;&amp;quot;&lt;br /&gt;
| style=&amp;quot;vertical-align: top;&amp;quot; class=&amp;quot;mainpage_hubbox&amp;quot; |&lt;br /&gt;
&amp;lt;div class=&amp;quot;mainpage_boxcontents&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Products.png|80px|center|link=Products]]&lt;br /&gt;
&amp;lt;div title=&amp;quot;Products&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;strong class=&amp;quot;mainpage_boxcontents_title&amp;quot;&amp;gt;&lt;br /&gt;
[[Products|Documentation des produits]]&lt;br /&gt;
&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
[[Products/Module_Scialys|Module Scialys et extensions]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Le [[Products/PiSerialPower|&amp;quot;RPi Power and Serial Hat&amp;quot;]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Le [[Products/Module_GPIO_Demo|module GPIO Démo]] (et diverses déclinaisons)&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Et [[Products|les autres]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| style=&amp;quot;vertical-align: top;&amp;quot; class=&amp;quot;mainpage_hubbox&amp;quot; |&lt;br /&gt;
&amp;lt;div class=&amp;quot;mainpage_boxcontents&amp;quot;&amp;gt;&lt;br /&gt;
[[File:API.png|80px|center|link=Technique]]&lt;br /&gt;
&amp;lt;div title=&amp;quot;API&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;strong class=&amp;quot;mainpage_boxcontents_title&amp;quot;&amp;gt;&lt;br /&gt;
[[Technique/Logiciel|Documentation Soft]]&lt;br /&gt;
&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
[[Technique/Logiciel/API|Utilisation de l&#039;interface logicielle (API)]] de Techno-Innov pour les microcontrôleur ARM Cortex-M*&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Guide pour [[Technique/Logiciel/API/New_App|créer une nouvelle application avec l&#039;API]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
[[Technique/Logiciel/Compilation|Compiler le code des application utilisant l&#039;API &amp;quot;Techno-Innov&amp;quot; sous Linux]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| role=&amp;quot;presentation&amp;quot; style=&amp;quot;border:0; margin: 0; width: 100%; border-spacing: 10px;&amp;quot;&lt;br /&gt;
| style=&amp;quot;vertical-align: top;&amp;quot; class=&amp;quot;mainpage_hubbox&amp;quot; |&lt;br /&gt;
&amp;lt;div class=&amp;quot;mainpage_boxcontents&amp;quot;&amp;gt;&lt;br /&gt;
[[File:TechData.png|80px|center|link=Technique]]&lt;br /&gt;
&amp;lt;div title=&amp;quot;Infos Techniques&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;strong class=&amp;quot;mainpage_boxcontents_title&amp;quot;&amp;gt;&lt;br /&gt;
[[Technique|Informations techniques]]&lt;br /&gt;
&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
[[Technique/Logiciel/Embedded|Systèmes embarqués]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
[[Technique/Elec/Kicad|Utiliser Kicad]] pour [[Technique/Elec/DIY|créer vos propres cartes électroniques]]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
| style=&amp;quot;vertical-align: top;&amp;quot; class=&amp;quot;mainpage_hubbox&amp;quot; |&lt;br /&gt;
&amp;lt;div class=&amp;quot;mainpage_boxcontents&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Articles.png|x80px|center|link=Articles]]&lt;br /&gt;
&amp;lt;div title=&amp;quot;Articles&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;strong class=&amp;quot;mainpage_boxcontents_title&amp;quot;&amp;gt;&lt;br /&gt;
[[Articles|Articles des utilisateurs]]&lt;br /&gt;
&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Le [[Articles/Nathael|&amp;quot;Making of&amp;quot; du module GPIO-Démo]] paru dans [http://www.opensilicium.com/ Open Silicium]&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
[[Articles/Dindinx|Création de jeux pour micro-contrôleurs ARM Cortex-M0]] (avec écran SSD1036)&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[[Wiki_Techno-Innov_FR:À_propos_de|À propos de ce site]]&#039;&#039;&#039; |&lt;br /&gt;
&#039;&#039;&#039;[[Wiki_Techno-Innov_FR:Politique_de_confidentialité|Licence et partage]]&#039;&#039;&#039; |&lt;br /&gt;
&#039;&#039;&#039;[[Contributeurs|Contributeurs]]&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Techno-Innov_Community_Wiki:Confidentialit%C3%A9&amp;diff=155</id>
		<title>Techno-Innov Community Wiki:Confidentialité</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Techno-Innov_Community_Wiki:Confidentialit%C3%A9&amp;diff=155"/>
		<updated>2020-09-03T15:12:59Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Nathael a déplacé la page Techno-Innov Community Wiki:Confidentialité vers Wiki Techno-Innov FR:Politique de confidentialité&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECTION [[Wiki Techno-Innov FR:Politique de confidentialité]]&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Politique_de_confidentialit%C3%A9&amp;diff=154</id>
		<title>Wiki Techno-Innov FR:Politique de confidentialité</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:Politique_de_confidentialit%C3%A9&amp;diff=154"/>
		<updated>2020-09-03T15:12:59Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Nathael a déplacé la page Techno-Innov Community Wiki:Confidentialité vers Wiki Techno-Innov FR:Politique de confidentialité&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Le contenu de ce Wiki est accessible à tous, et placé sous licence [http://creativecommons.org/licenses/by-sa/3.0/ Creative Commons attribution partage à l&#039;identique].&lt;br /&gt;
&lt;br /&gt;
Nous demandons aux auteurs de ne pas se cacher derrière des pseudonymes ou un faux nom. Ce que vous écrivez sur Internet engage votre responsabilité.&lt;br /&gt;
&lt;br /&gt;
Faites attention à ce que vous écrivez, ne publiez pas d&#039;informations sensibles, et en général, n&#039;importunez pas les personnes, qu&#039;il s&#039;agisse d&#039;autres auteurs ou de simples passants.&lt;br /&gt;
&lt;br /&gt;
Encore une fois, le contenu de ce Wiki est accessible à tous, et placé sous licence [http://creativecommons.org/licenses/by-sa/3.0/ Creative Commons attribution partage à l&#039;identique].&amp;lt;br /&amp;gt;&lt;br /&gt;
Vous pouvez donc lire son contenu sans limitation, le modifier si vous acceptez cette licence pour vos modifications et publications et que vous en avez la possibilité (contactez nous si vous n&#039;avez pas de compte, voir message en page d&#039;accueil), et même copier tout ou partie de son contenu si vous respectez la licence sous laquelle celui-ci est placé : Vous devez citer vos sources et leur(s) auteur(s), et placer le résultat - &#039;&#039;&#039;la totalité du résultat&#039;&#039;&#039; - sous la même licence.&lt;br /&gt;
&lt;br /&gt;
Sinon, merci de passer votre chemin, et n&#039;importunez pas les personnes présentes.&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Techno-Innov_Community_Wiki:%C3%80_propos_de&amp;diff=153</id>
		<title>Techno-Innov Community Wiki:À propos de</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Techno-Innov_Community_Wiki:%C3%80_propos_de&amp;diff=153"/>
		<updated>2020-09-03T15:09:43Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Nathael a déplacé la page Techno-Innov Community Wiki:À propos de vers Wiki Techno-Innov FR:À propos de&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECTION [[Wiki Techno-Innov FR:À propos de]]&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:%C3%80_propos_de&amp;diff=152</id>
		<title>Wiki Techno-Innov FR:À propos de</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:%C3%80_propos_de&amp;diff=152"/>
		<updated>2020-09-03T15:09:42Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Nathael a déplacé la page Techno-Innov Community Wiki:À propos de vers Wiki Techno-Innov FR:À propos de&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ce wiki est destiné à simplifier et organiser la diffusion d&#039;informations autour de nos projets et produits.&lt;br /&gt;
&lt;br /&gt;
== Gestion du Wiki ==&lt;br /&gt;
=== Obtention des droits de modification ===&lt;br /&gt;
Le contenu en est principalement créé et maintenu par les soins de [[Utilisateur:Nathael]]. D&#039;autres personnes auront certainement accès en écriture prochainement, et peut-être tout le monde dans un futur proche, mais toujours sur demande pour limiter les risques de détérioration.&lt;br /&gt;
&lt;br /&gt;
N&#039;hésitez pas à nous contacter par mail pour obtenir un accès en écriture.&lt;br /&gt;
&lt;br /&gt;
Si ce mode de fonctionnement ne vous convient pas, vous pouvez passer votre chemin. De même si le contenu de ce wiki vous dérange ou ne vous intéresse pas.&lt;br /&gt;
&lt;br /&gt;
=== Règles à respecter ===&lt;br /&gt;
Lorsque vous ferez partie des auteurs, merci de respecter certaines règles :&lt;br /&gt;
&lt;br /&gt;
* Respectez les internautes (et les personnes en général). Vos affirmations vous engagent.&lt;br /&gt;
* Respectez l&#039;organisation du Wiki&lt;br /&gt;
* Consultez régulièrement cette page pour voir si de nouvelles consignes ont été ajoutées.&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Techno-Innov_Community_Wiki:%C3%80_propos&amp;diff=151</id>
		<title>Techno-Innov Community Wiki:À propos</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Techno-Innov_Community_Wiki:%C3%80_propos&amp;diff=151"/>
		<updated>2020-09-03T15:08:08Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Nathael a déplacé la page Techno-Innov Community Wiki:À propos vers Techno-Innov Community Wiki:À propos de&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECTION [[Techno-Innov Community Wiki:À propos de]]&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:%C3%80_propos_de&amp;diff=150</id>
		<title>Wiki Techno-Innov FR:À propos de</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Wiki_Techno-Innov_FR:%C3%80_propos_de&amp;diff=150"/>
		<updated>2020-09-03T15:08:08Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Nathael a déplacé la page Techno-Innov Community Wiki:À propos vers Techno-Innov Community Wiki:À propos de&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Ce wiki est destiné à simplifier et organiser la diffusion d&#039;informations autour de nos projets et produits.&lt;br /&gt;
&lt;br /&gt;
== Gestion du Wiki ==&lt;br /&gt;
=== Obtention des droits de modification ===&lt;br /&gt;
Le contenu en est principalement créé et maintenu par les soins de [[Utilisateur:Nathael]]. D&#039;autres personnes auront certainement accès en écriture prochainement, et peut-être tout le monde dans un futur proche, mais toujours sur demande pour limiter les risques de détérioration.&lt;br /&gt;
&lt;br /&gt;
N&#039;hésitez pas à nous contacter par mail pour obtenir un accès en écriture.&lt;br /&gt;
&lt;br /&gt;
Si ce mode de fonctionnement ne vous convient pas, vous pouvez passer votre chemin. De même si le contenu de ce wiki vous dérange ou ne vous intéresse pas.&lt;br /&gt;
&lt;br /&gt;
=== Règles à respecter ===&lt;br /&gt;
Lorsque vous ferez partie des auteurs, merci de respecter certaines règles :&lt;br /&gt;
&lt;br /&gt;
* Respectez les internautes (et les personnes en général). Vos affirmations vous engagent.&lt;br /&gt;
* Respectez l&#039;organisation du Wiki&lt;br /&gt;
* Consultez régulièrement cette page pour voir si de nouvelles consignes ont été ajoutées.&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=149</id>
		<title>Products</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=149"/>
		<updated>2020-09-03T14:09:58Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Extensions miniPC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Liste des produits}}&lt;br /&gt;
== Projet &amp;quot;Scialys&amp;quot; ==&lt;br /&gt;
* [[Products/Module_Scialys|Module Scialys]]&lt;br /&gt;
[[Image:Module_Scialys.jpg|100px|left]]&lt;br /&gt;
: Le module principal du système Scialys : gestion de l&#039;auto-consommation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Extensions miniPC ==&lt;br /&gt;
* [[Products/PiSerialPower|Extension &amp;quot;PiSerialPower&amp;quot;]]&lt;br /&gt;
[[Image:PiserialPower.jpg|100px|left]]&lt;br /&gt;
: Extension d&#039;alimentation (mais pas que) pour cartes RaspberryPi (et modèles concurrents compatibles).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules de développement ==&lt;br /&gt;
* [[Products/Module_GPIO_Demo|Module GPIO Démo]]&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|100px|left]]&lt;br /&gt;
: Le module GPIO pour le DomoTab et le [[Products/DTPlug|DTPlug]].&lt;br /&gt;
: Le module GPIO-Démo est un module de développement pour les modules de communication du projet DomoTab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224BO|LPC1224 Break-Out]]&lt;br /&gt;
[[Image:LPC1224-BO.jpg|100px|left]]&lt;br /&gt;
: La carte de développement LPC1224 Break-Out : un module de développement autonome (un port USB suffit) pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224mbed|LPC1224-mbed]]&lt;br /&gt;
[[Image:LPC1224-mbed.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224-mbed : une version &amp;quot;mbed ready du module de développement autonome pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/USB_UART|Adaptateur USB-UART]]&lt;br /&gt;
[[Image:USBtoUART.jpg|100px|left]]&lt;br /&gt;
: Adaptateur USB vers UART, et potentiellement UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules de communication ==&lt;br /&gt;
* [[Products/Module_RFSub1G|Module RF Sub-1GHz]]&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|100px|left]]&lt;br /&gt;
: Le module RF, version Standalone, USB, ou UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_1Wire|Module 1Wire]]&lt;br /&gt;
[[Image:Module_1Wire.jpg|100px|left]]&lt;br /&gt;
: Module 1Wire au format UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RS485|Module RS485]]&lt;br /&gt;
[[Image:Module_RS485.jpg|100px|left]]&lt;br /&gt;
: Module RS485 au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_KNX|Module KNX]]&lt;br /&gt;
[[Image:Module_KNX.jpg|100px|left]]&lt;br /&gt;
: Module KNX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_DMX|Module DMX]]&lt;br /&gt;
[[Image:Module_DMX.jpg|100px|left]]&lt;br /&gt;
: Module DMX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_CPL|Module CPL]]&lt;br /&gt;
[[Image:Module_CPL.jpg|100px|left]]&lt;br /&gt;
: Module CPL (Courant porteur) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Projet &amp;quot;DomoTab&amp;quot; ==&lt;br /&gt;
* [[Products/DTPlug|Le DTPlug]]&lt;br /&gt;
[[Image:DTPlug.png|100px|left]]&lt;br /&gt;
: Passerelle DTPlug : Ethernet ---&amp;gt; 4x UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PSMC|Module PSMC : Power Supply Monitor &amp;amp; Control]]&lt;br /&gt;
[[Image:PSMC.jpg|100px|left]]&lt;br /&gt;
: Module PSMC pour alimentation d&#039;un module de communication, mesure de courant (consommation) et contrôle d&#039;une prise (Nécessite un module de communication pour fonctionner).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Adaptateurs divers ==&lt;br /&gt;
* [[Products/Adaptateur_Thermocouple|Adaptateur Thermocouple]]&lt;br /&gt;
[[Image:Adaptateur_Thermocouple.jpg|100px|left]]&lt;br /&gt;
: Adaptateur Thermocouples pour mesure de température (nécessite un module de communication pour fonctionner).&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:LPC1224-BO.jpg&amp;diff=148</id>
		<title>Fichier:LPC1224-BO.jpg</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:LPC1224-BO.jpg&amp;diff=148"/>
		<updated>2020-09-03T12:59:23Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Nathael a téléversé une nouvelle version de Fichier:LPC1224-BO.jpg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=147</id>
		<title>Products</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=147"/>
		<updated>2020-09-03T12:57:54Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Modules de développement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Liste des produits}}&lt;br /&gt;
== Projet &amp;quot;Scialys&amp;quot; ==&lt;br /&gt;
* [[Products/Module_Scialys|Module Scialys]]&lt;br /&gt;
[[Image:Module_Scialys.jpg|100px|left]]&lt;br /&gt;
: Le module principal du système Scialys : gestion de l&#039;auto-consommation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Extensions miniPC ==&lt;br /&gt;
* [[Products/PiSerialPower|Extension &amp;quot;PiSerialPower&amp;quot;]]&lt;br /&gt;
[[Image:PiserialPower.jpg|100px|left]]&lt;br /&gt;
: Extension d&#039;alimentation et de debug pour cartes RaspberryPi (et modèles concurrents compatibles).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Modules de développement ==&lt;br /&gt;
* [[Products/Module_GPIO_Demo|Module GPIO Démo]]&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|100px|left]]&lt;br /&gt;
: Le module GPIO pour le DomoTab et le [[Products/DTPlug|DTPlug]].&lt;br /&gt;
: Le module GPIO-Démo est un module de développement pour les modules de communication du projet DomoTab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224BO|LPC1224 Break-Out]]&lt;br /&gt;
[[Image:LPC1224-BO.jpg|100px|left]]&lt;br /&gt;
: La carte de développement LPC1224 Break-Out : un module de développement autonome (un port USB suffit) pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224mbed|LPC1224-mbed]]&lt;br /&gt;
[[Image:LPC1224-mbed.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224-mbed : une version &amp;quot;mbed ready du module de développement autonome pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/USB_UART|Adaptateur USB-UART]]&lt;br /&gt;
[[Image:USBtoUART.jpg|100px|left]]&lt;br /&gt;
: Adaptateur USB vers UART, et potentiellement UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules de communication ==&lt;br /&gt;
* [[Products/Module_RFSub1G|Module RF Sub-1GHz]]&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|100px|left]]&lt;br /&gt;
: Le module RF, version Standalone, USB, ou UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_1Wire|Module 1Wire]]&lt;br /&gt;
[[Image:Module_1Wire.jpg|100px|left]]&lt;br /&gt;
: Module 1Wire au format UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RS485|Module RS485]]&lt;br /&gt;
[[Image:Module_RS485.jpg|100px|left]]&lt;br /&gt;
: Module RS485 au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_KNX|Module KNX]]&lt;br /&gt;
[[Image:Module_KNX.jpg|100px|left]]&lt;br /&gt;
: Module KNX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_DMX|Module DMX]]&lt;br /&gt;
[[Image:Module_DMX.jpg|100px|left]]&lt;br /&gt;
: Module DMX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_CPL|Module CPL]]&lt;br /&gt;
[[Image:Module_CPL.jpg|100px|left]]&lt;br /&gt;
: Module CPL (Courant porteur) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Projet &amp;quot;DomoTab&amp;quot; ==&lt;br /&gt;
* [[Products/DTPlug|Le DTPlug]]&lt;br /&gt;
[[Image:DTPlug.png|100px|left]]&lt;br /&gt;
: Passerelle DTPlug : Ethernet ---&amp;gt; 4x UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PSMC|Module PSMC : Power Supply Monitor &amp;amp; Control]]&lt;br /&gt;
[[Image:PSMC.jpg|100px|left]]&lt;br /&gt;
: Module PSMC pour alimentation d&#039;un module de communication, mesure de courant (consommation) et contrôle d&#039;une prise (Nécessite un module de communication pour fonctionner).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Adaptateurs divers ==&lt;br /&gt;
* [[Products/Adaptateur_Thermocouple|Adaptateur Thermocouple]]&lt;br /&gt;
[[Image:Adaptateur_Thermocouple.jpg|100px|left]]&lt;br /&gt;
: Adaptateur Thermocouples pour mesure de température (nécessite un module de communication pour fonctionner).&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=146</id>
		<title>Products</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=146"/>
		<updated>2020-09-03T03:10:48Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Projet &amp;quot;Scialys&amp;quot; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Liste des produits}}&lt;br /&gt;
== Projet &amp;quot;Scialys&amp;quot; ==&lt;br /&gt;
* [[Products/Module_Scialys|Module Scialys]]&lt;br /&gt;
[[Image:Module_Scialys.jpg|100px|left]]&lt;br /&gt;
: Le module principal du système Scialys : gestion de l&#039;auto-consommation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Extensions miniPC ==&lt;br /&gt;
* [[Products/PiSerialPower|Extension &amp;quot;PiSerialPower&amp;quot;]]&lt;br /&gt;
[[Image:PiserialPower.jpg|100px|left]]&lt;br /&gt;
: Extension d&#039;alimentation et de debug pour cartes RaspberryPi (et modèles concurrents compatibles).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Modules de développement ==&lt;br /&gt;
* [[Products/Module_GPIO_Demo|Module GPIO Démo]]&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|100px|left]]&lt;br /&gt;
: Le module GPIO pour le DomoTab et le [[Products/DTPlug|DTPlug]].&lt;br /&gt;
: Le module GPIO-Démo est un module de développement pour les modules de communication du projet DomoTab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224BO|LPC1224 Break-Out]]&lt;br /&gt;
[[Image:LPC1224-BO.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224 Break-Out : un module de développement autonome (un port USB suffit) pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224mbed|LPC1224-mbed]]&lt;br /&gt;
[[Image:LPC1224-mbed.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224-mbed : une version &amp;quot;mbed ready du module de développement autonome pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/USB_UART|Adaptateur USB-UART]]&lt;br /&gt;
[[Image:USBtoUART.jpg|100px|left]]&lt;br /&gt;
: Adaptateur USB vers UART, et potentiellement UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules de communication ==&lt;br /&gt;
* [[Products/Module_RFSub1G|Module RF Sub-1GHz]]&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|100px|left]]&lt;br /&gt;
: Le module RF, version Standalone, USB, ou UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_1Wire|Module 1Wire]]&lt;br /&gt;
[[Image:Module_1Wire.jpg|100px|left]]&lt;br /&gt;
: Module 1Wire au format UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RS485|Module RS485]]&lt;br /&gt;
[[Image:Module_RS485.jpg|100px|left]]&lt;br /&gt;
: Module RS485 au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_KNX|Module KNX]]&lt;br /&gt;
[[Image:Module_KNX.jpg|100px|left]]&lt;br /&gt;
: Module KNX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_DMX|Module DMX]]&lt;br /&gt;
[[Image:Module_DMX.jpg|100px|left]]&lt;br /&gt;
: Module DMX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_CPL|Module CPL]]&lt;br /&gt;
[[Image:Module_CPL.jpg|100px|left]]&lt;br /&gt;
: Module CPL (Courant porteur) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Projet &amp;quot;DomoTab&amp;quot; ==&lt;br /&gt;
* [[Products/DTPlug|Le DTPlug]]&lt;br /&gt;
[[Image:DTPlug.png|100px|left]]&lt;br /&gt;
: Passerelle DTPlug : Ethernet ---&amp;gt; 4x UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PSMC|Module PSMC : Power Supply Monitor &amp;amp; Control]]&lt;br /&gt;
[[Image:PSMC.jpg|100px|left]]&lt;br /&gt;
: Module PSMC pour alimentation d&#039;un module de communication, mesure de courant (consommation) et contrôle d&#039;une prise (Nécessite un module de communication pour fonctionner).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Adaptateurs divers ==&lt;br /&gt;
* [[Products/Adaptateur_Thermocouple|Adaptateur Thermocouple]]&lt;br /&gt;
[[Image:Adaptateur_Thermocouple.jpg|100px|left]]&lt;br /&gt;
: Adaptateur Thermocouples pour mesure de température (nécessite un module de communication pour fonctionner).&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=145</id>
		<title>Products</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=145"/>
		<updated>2020-09-03T03:09:30Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Modules de développement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Liste des produits}}&lt;br /&gt;
== Projet &amp;quot;Scialys&amp;quot; ==&lt;br /&gt;
* [[Products/Scialys|Module Scialys]]&lt;br /&gt;
[[Image:Module_Scialys.jpg|100px|left]]&lt;br /&gt;
: Le module principal du système Scialys : gestion de l&#039;auto-consommation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Extensions miniPC ==&lt;br /&gt;
* [[Products/PiSerialPower|Extension &amp;quot;PiSerialPower&amp;quot;]]&lt;br /&gt;
[[Image:PiserialPower.jpg|100px|left]]&lt;br /&gt;
: Extension d&#039;alimentation et de debug pour cartes RaspberryPi (et modèles concurrents compatibles).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Modules de développement ==&lt;br /&gt;
* [[Products/Module_GPIO_Demo|Module GPIO Démo]]&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|100px|left]]&lt;br /&gt;
: Le module GPIO pour le DomoTab et le [[Products/DTPlug|DTPlug]].&lt;br /&gt;
: Le module GPIO-Démo est un module de développement pour les modules de communication du projet DomoTab.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224BO|LPC1224 Break-Out]]&lt;br /&gt;
[[Image:LPC1224-BO.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224 Break-Out : un module de développement autonome (un port USB suffit) pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224mbed|LPC1224-mbed]]&lt;br /&gt;
[[Image:LPC1224-mbed.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224-mbed : une version &amp;quot;mbed ready du module de développement autonome pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/USB_UART|Adaptateur USB-UART]]&lt;br /&gt;
[[Image:USBtoUART.jpg|100px|left]]&lt;br /&gt;
: Adaptateur USB vers UART, et potentiellement UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modules de communication ==&lt;br /&gt;
* [[Products/Module_RFSub1G|Module RF Sub-1GHz]]&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|100px|left]]&lt;br /&gt;
: Le module RF, version Standalone, USB, ou UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_1Wire|Module 1Wire]]&lt;br /&gt;
[[Image:Module_1Wire.jpg|100px|left]]&lt;br /&gt;
: Module 1Wire au format UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RS485|Module RS485]]&lt;br /&gt;
[[Image:Module_RS485.jpg|100px|left]]&lt;br /&gt;
: Module RS485 au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_KNX|Module KNX]]&lt;br /&gt;
[[Image:Module_KNX.jpg|100px|left]]&lt;br /&gt;
: Module KNX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_DMX|Module DMX]]&lt;br /&gt;
[[Image:Module_DMX.jpg|100px|left]]&lt;br /&gt;
: Module DMX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_CPL|Module CPL]]&lt;br /&gt;
[[Image:Module_CPL.jpg|100px|left]]&lt;br /&gt;
: Module CPL (Courant porteur) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Projet &amp;quot;DomoTab&amp;quot; ==&lt;br /&gt;
* [[Products/DTPlug|Le DTPlug]]&lt;br /&gt;
[[Image:DTPlug.png|100px|left]]&lt;br /&gt;
: Passerelle DTPlug : Ethernet ---&amp;gt; 4x UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PSMC|Module PSMC : Power Supply Monitor &amp;amp; Control]]&lt;br /&gt;
[[Image:PSMC.jpg|100px|left]]&lt;br /&gt;
: Module PSMC pour alimentation d&#039;un module de communication, mesure de courant (consommation) et contrôle d&#039;une prise (Nécessite un module de communication pour fonctionner).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Adaptateurs divers ==&lt;br /&gt;
* [[Products/Adaptateur_Thermocouple|Adaptateur Thermocouple]]&lt;br /&gt;
[[Image:Adaptateur_Thermocouple.jpg|100px|left]]&lt;br /&gt;
: Adaptateur Thermocouples pour mesure de température (nécessite un module de communication pour fonctionner).&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/Module_Scialys&amp;diff=144</id>
		<title>Products/Module Scialys</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/Module_Scialys&amp;diff=144"/>
		<updated>2020-09-03T03:05:21Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Système Scialys}}&lt;br /&gt;
&lt;br /&gt;
Le module Scialys est la partie centrale d&#039;un système de gestion de l&#039;auto-consommation permettant de rediriger l&#039;excédant de production (et seulement lui) vers une charge comme un chauffe-eau ou un ensemble de radiateurs. Ce principe limite le renvoi vers le réseau et optimise la consommation de l&#039;énergie produite localement, pouvant aller jusqu&#039;à complètement effacer la consommation d&#039;un chauffe-eau électrique. &lt;br /&gt;
&lt;br /&gt;
[[Image:Module_Scialys.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Fonctionnement ==&lt;br /&gt;
=== Principe ===&lt;br /&gt;
Le module Scialys est un système autonome dont le fonctionnement est relativement simple. Les deux capteurs de courant mesurent en continu la production locale (solaire, éolien, ...) et la consommation du logement. Lorsque la production devient supérieure à la consommation le module scialys commence à alimenter sa charge principale (le chauffe-eau) proportionnellement à la différence de production/consommation de façon à équilibrer les deux mesures et utiliser au maximum la production locale.&lt;br /&gt;
&lt;br /&gt;
Si un autre appareil se met en marche, les capteurs le détectent immédiatement et la consommation de la charge est réduite pour rééquilibrer la consommation et la production.&lt;br /&gt;
&lt;br /&gt;
Le système peut ainsi étaler la consommation d&#039;un chauffe-eau électrique sur une partie de la journée, profitant même des journées peu ensoleillées (ou avec peu de vent pour les éloiènnes) pendant lesquelles la production reste très faible.&lt;br /&gt;
&lt;br /&gt;
=== Maintien du confort ===&lt;br /&gt;
Si la production reste trop faible pendant plusieurs jours d&#039;affilé, le capteur de température installé sur le chauffe-eau permet au module Scialys, si la température descend en dessous d&#039;un seuil de température minimale configurable, de déclencher une marche forcée pour faire remonter la température de l&#039;eau (temporisation ou seuil de température à atteindre) et ainsi continuer à fournir le niveau de confort attendu par tous.&lt;br /&gt;
&lt;br /&gt;
=== Modules d&#039;extension ===&lt;br /&gt;
Si la production est suffisante et une fois que l&#039;eau a atteint sa température maximum, des modules d&#039;extension (à venir) permettent de commander d&#039;autres charges, augmentant ainsi l&#039;utilisation de l&#039;énergie excédentaire (batteries, chauffage, véhicule électrique, ...).&lt;br /&gt;
&lt;br /&gt;
Il est aussi possible d&#039;ajouter des modules de communication permettant l&#039;intégration dans un système de domotique existant.&lt;br /&gt;
&lt;br /&gt;
== Description technique ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
&lt;br /&gt;
=== Électronique ===&lt;br /&gt;
==== Système de contrôle ====&lt;br /&gt;
==== Interfaces de communication ====&lt;br /&gt;
==== Reset et mode mise à jour (ISP) ====&lt;br /&gt;
==== Écran, boutons et leds RGB ====&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=143</id>
		<title>Products/PiSerialPower</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/PiSerialPower&amp;diff=143"/>
		<updated>2020-09-03T02:57:36Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « {{DISPLAYTITLE:Extension PiSerialPower}} right  == Description == === Hardware === ==== Dimensions ==== ==== Connecteurs ==== * Connecteu... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Extension PiSerialPower}}&lt;br /&gt;
[[Image:PiserialPower.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
&lt;br /&gt;
=== Électronique ===&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/Module_Scialys&amp;diff=142</id>
		<title>Products/Module Scialys</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/Module_Scialys&amp;diff=142"/>
		<updated>2020-09-03T02:55:48Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « {{DISPLAYTITLE:Système Scialys}} right  == Description == === Hardware === ==== Dimensions ==== ==== Connecteurs ==== * Connecteur P1... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Système Scialys}}&lt;br /&gt;
[[Image:Module_Scialys.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
==== Système de contrôle ====&lt;br /&gt;
==== Interfaces de communication ====&lt;br /&gt;
==== Reset et mode mise à jour (ISP) ====&lt;br /&gt;
==== Écran, boutons et leds RGB ====&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:PiserialPower.jpg&amp;diff=141</id>
		<title>Fichier:PiserialPower.jpg</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:PiserialPower.jpg&amp;diff=141"/>
		<updated>2020-09-03T02:52:02Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=140</id>
		<title>Products</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=140"/>
		<updated>2020-09-03T02:50:10Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Liste des produits}}&lt;br /&gt;
== Projet &amp;quot;Scialys&amp;quot; ==&lt;br /&gt;
* [[Products/Scialys|Module Scialys]]&lt;br /&gt;
[[Image:Module_Scialys.jpg|100px|left]]&lt;br /&gt;
: Le module principal du système Scialys : gestion de l&#039;auto-consommation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Extensions miniPC ==&lt;br /&gt;
* [[Products/PiSerialPower|Extension &amp;quot;PiSerialPower&amp;quot;]]&lt;br /&gt;
[[Image:PiserialPower.jpg|100px|left]]&lt;br /&gt;
: Extension d&#039;alimentation et de debug pour cartes RaspberryPi (et modèles concurrents compatibles).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Modules de développement ==&lt;br /&gt;
* [[Products/Module_GPIO_Demo|Module GPIO Démo]]&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|100px|left]]&lt;br /&gt;
: Le module GPIO pour le DomoTab et le DTPlug.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224BO|LPC1224 Break-Out]]&lt;br /&gt;
[[Image:LPC1224-BO.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224 Break-Out : un module de développement autonome (un port USB suffit) pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224mbed|LPC1224-mbed]]&lt;br /&gt;
[[Image:LPC1224-mbed.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224-mbed : une version &amp;quot;mbed ready du module de développement autonome pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/USB_UART|Adaptateur USB-UART]]&lt;br /&gt;
[[Image:USBtoUART.jpg|100px|left]]&lt;br /&gt;
: Adaptateur USB vers UART, et potentiellement UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Modules de communication ==&lt;br /&gt;
* [[Products/Module_RFSub1G|Module RF Sub-1GHz]]&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|100px|left]]&lt;br /&gt;
: Le module RF, version Standalone, USB, ou UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_1Wire|Module 1Wire]]&lt;br /&gt;
[[Image:Module_1Wire.jpg|100px|left]]&lt;br /&gt;
: Module 1Wire au format UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RS485|Module RS485]]&lt;br /&gt;
[[Image:Module_RS485.jpg|100px|left]]&lt;br /&gt;
: Module RS485 au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_KNX|Module KNX]]&lt;br /&gt;
[[Image:Module_KNX.jpg|100px|left]]&lt;br /&gt;
: Module KNX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_DMX|Module DMX]]&lt;br /&gt;
[[Image:Module_DMX.jpg|100px|left]]&lt;br /&gt;
: Module DMX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_CPL|Module CPL]]&lt;br /&gt;
[[Image:Module_CPL.jpg|100px|left]]&lt;br /&gt;
: Module CPL (Courant porteur) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Projet &amp;quot;DomoTab&amp;quot; ==&lt;br /&gt;
* [[Products/DTPlug|Le DTPlug]]&lt;br /&gt;
[[Image:DTPlug.png|100px|left]]&lt;br /&gt;
: Passerelle DTPlug : Ethernet ---&amp;gt; 4x UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PSMC|Module PSMC : Power Supply Monitor &amp;amp; Control]]&lt;br /&gt;
[[Image:PSMC.jpg|100px|left]]&lt;br /&gt;
: Module PSMC pour alimentation d&#039;un module de communication, mesure de courant (consommation) et contrôle d&#039;une prise (Nécessite un module de communication pour fonctionner).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Adaptateurs divers ==&lt;br /&gt;
* [[Products/Adaptateur_Thermocouple|Adaptateur Thermocouple]]&lt;br /&gt;
[[Image:Adaptateur_Thermocouple.jpg|100px|left]]&lt;br /&gt;
: Adaptateur Thermocouples pour mesure de température (nécessite un module de communication pour fonctionner).&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=139</id>
		<title>Products</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products&amp;diff=139"/>
		<updated>2020-09-03T02:48:13Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Liste des produits}}&lt;br /&gt;
== Projet &amp;quot;Scialys&amp;quot; ==&lt;br /&gt;
* [[Products/Scialys|Module Scialys]]&lt;br /&gt;
[[Image:Module_Scialys.jpg|100px|left]]&lt;br /&gt;
: Le module principal du système Scialys : gestion de l&#039;auto-consommation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
== Modules de développement ==&lt;br /&gt;
* [[Products/Module_GPIO_Demo|Module GPIO Démo]]&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|100px|left]]&lt;br /&gt;
: Le module GPIO pour le DomoTab et le DTPlug.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224BO|LPC1224 Break-Out]]&lt;br /&gt;
[[Image:LPC1224-BO.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224 Break-Out : un module de développement autonome (un port USB suffit) pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/LPC1224mbed|LPC1224-mbed]]&lt;br /&gt;
[[Image:LPC1224-mbed.jpg|60px|left]]&lt;br /&gt;
: La carte de développement LPC1224-mbed : une version &amp;quot;mbed ready du module de développement autonome pour le microcontrôleur LPC1224 de NXP (ARM Cortex-M0).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/USB_UART|Adaptateur USB-UART]]&lt;br /&gt;
[[Image:USBtoUART.jpg|100px|left]]&lt;br /&gt;
: Adaptateur USB vers UART, et potentiellement UEXT.&lt;br /&gt;
&lt;br /&gt;
== Modules de communication ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RFSub1G|Module RF Sub-1GHz]]&lt;br /&gt;
[[Image:Module_RFSub1G.jpg|100px|left]]&lt;br /&gt;
: Le module RF, version Standalone, USB, ou UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_1Wire|Module 1Wire]]&lt;br /&gt;
[[Image:Module_1Wire.jpg|100px|left]]&lt;br /&gt;
: Module 1Wire au format UEXT.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_RS485|Module RS485]]&lt;br /&gt;
[[Image:Module_RS485.jpg|100px|left]]&lt;br /&gt;
: Module RS485 au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_KNX|Module KNX]]&lt;br /&gt;
[[Image:Module_KNX.jpg|100px|left]]&lt;br /&gt;
: Module KNX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_DMX|Module DMX]]&lt;br /&gt;
[[Image:Module_DMX.jpg|100px|left]]&lt;br /&gt;
: Module DMX (filaire) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Module_CPL|Module CPL]]&lt;br /&gt;
[[Image:Module_CPL.jpg|100px|left]]&lt;br /&gt;
: Module CPL (Courant porteur) au format USB, UEXT et Standalone.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Projet &amp;quot;DomoTab&amp;quot; ==&lt;br /&gt;
* [[Products/DTPlug|Le DTPlug]]&lt;br /&gt;
[[Image:DTPlug.png|100px|left]]&lt;br /&gt;
: Passerelle DTPlug : Ethernet ---&amp;gt; 4x UEXT&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PSMC|Module PSMC : Power Supply Monitor &amp;amp; Control]]&lt;br /&gt;
[[Image:PSMC.jpg|100px|left]]&lt;br /&gt;
: Module PSMC pour alimentation d&#039;un module de communication, mesure de courant (consommation) et contrôle d&#039;une prise (Nécessite un module de communication pour fonctionner).&lt;br /&gt;
&lt;br /&gt;
== Adaptateurs divers ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/PiSerialPower|Adaptateur &amp;quot;PiSerialPower&amp;quot;]]&lt;br /&gt;
[[Image:PiserialPower.jpg|100px|left]]&lt;br /&gt;
: Adaptateur d&#039;alimentation et de debug pour cartes RaspberryPi (et modèles concurrents compatibles).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
* [[Products/Adaptateur_Thermocouple|Adaptateur Thermocouple]]&lt;br /&gt;
[[Image:Adaptateur_Thermocouple.jpg|100px|left]]&lt;br /&gt;
: Adaptateur Thermocouples pour mesure de température (nécessite un module de communication pour fonctionner).&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:Module_Scialys.jpg&amp;diff=138</id>
		<title>Fichier:Module Scialys.jpg</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:Module_Scialys.jpg&amp;diff=138"/>
		<updated>2020-09-03T02:47:07Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/LPC1224mbed&amp;diff=137</id>
		<title>Products/LPC1224mbed</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/LPC1224mbed&amp;diff=137"/>
		<updated>2020-09-03T01:06:42Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « {{DISPLAYTITLE:LPC1224-mbed dev board}} right  == Description == The LPC1224-mbed board is a clone of our LPC1224-BO board with the FTDI U... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:LPC1224-mbed dev board}}&lt;br /&gt;
[[Image:LPC1224-mbed.png|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
The LPC1224-mbed board is a clone of our LPC1224-BO board with the FTDI USB-to-UART bridge replaced by an LPC11U35 micro-controller in order to comply with mbed hardware platform requirements.&lt;br /&gt;
&lt;br /&gt;
The LPC11U35 has an USB device interface and is connected to both the UART and the SWD interfaces of the LPC1224 micro-controller.&lt;br /&gt;
&lt;br /&gt;
This allows drag-and-drop programming as the board will enumerate as a mass storage device on a host when the target micro-controller is put in ISP mode.&lt;br /&gt;
&lt;br /&gt;
== How-To ==&lt;br /&gt;
To be written.&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
* Assemble first prototype&lt;br /&gt;
* Tests&lt;br /&gt;
* Submit to mbed&lt;br /&gt;
* Technical Documentation&lt;br /&gt;
&lt;br /&gt;
== Technical documentation ==&lt;br /&gt;
The technical documentation is not yet available.&lt;br /&gt;
&lt;br /&gt;
== History ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:Module_RFSub1G.jpg&amp;diff=136</id>
		<title>Fichier:Module RFSub1G.jpg</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:Module_RFSub1G.jpg&amp;diff=136"/>
		<updated>2020-09-03T01:05:33Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:DTPlug.png&amp;diff=135</id>
		<title>Fichier:DTPlug.png</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:DTPlug.png&amp;diff=135"/>
		<updated>2020-09-03T01:04:59Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:LPC1224-BO.jpg&amp;diff=134</id>
		<title>Fichier:LPC1224-BO.jpg</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:LPC1224-BO.jpg&amp;diff=134"/>
		<updated>2020-09-03T01:04:21Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:Module_GPIO_Demo.jpg&amp;diff=133</id>
		<title>Fichier:Module GPIO Demo.jpg</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:Module_GPIO_Demo.jpg&amp;diff=133"/>
		<updated>2020-09-03T01:03:03Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:USBtoUART.jpg&amp;diff=132</id>
		<title>Fichier:USBtoUART.jpg</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:USBtoUART.jpg&amp;diff=132"/>
		<updated>2020-09-03T01:02:00Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/USB_UART&amp;diff=131</id>
		<title>Products/USB UART</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/USB_UART&amp;diff=131"/>
		<updated>2020-09-03T00:59:55Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « {{DISPLAYTITLE:Adaptateur USB-UART}} right  == Description == L&amp;#039;adaptateur USB-UART est un adaptateur simple et utile donnant accès à une l... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Adaptateur USB-UART}}&lt;br /&gt;
[[Image:USBtoUART.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
L&#039;adaptateur USB-UART est un adaptateur simple et utile donnant accès à une liaison série (UART 3.3V) à partir d&#039;un port USB, incluant un accès aux alimentations 3.3V et 5.0V pour tous vos besoins de prototypage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Cet adaptateur utilise le composant FTDI FT230XS et dispose de deux connecteurs USB différents, USB A ou micro-USB (Les deux connecteurs sont montés en même temps, mais un seul peut être utilisé à un moment donné, ne connectez jamais les deux simultanément !)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ce composant devrait aussi supporter l&#039;I2C, le SPI, et d&#039;autres protocoles/bus de données, et nous avons donc mis un connecteur UEXT, cependant cela nécessitera quelques développements logiciels. Nous vous tiendrons au courant des évolutions.&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
&lt;br /&gt;
== TODO List ==&lt;br /&gt;
* Documentation technique&lt;br /&gt;
* Support des protocoles I2C et SPI via les capacités de &amp;quot;bit-banging&amp;quot; du FTDI (soft PC)&lt;br /&gt;
* Support SWD et/ou JTAG&lt;br /&gt;
* Version avec RS232&lt;br /&gt;
* Version avec alimentation 1.8V (pour l&#039;alimentation de microprocesseurs et le debug SWD/JTAG)&lt;br /&gt;
&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
La documentation technique de ce produit est à rédiger&lt;br /&gt;
&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Products/Module_GPIO_Demo&amp;diff=130</id>
		<title>Products/Module GPIO Demo</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Products/Module_GPIO_Demo&amp;diff=130"/>
		<updated>2020-09-03T00:58:59Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « {{DISPLAYTITLE:Module GPIO Démo}} right  == Description == === Hardware === ==== Dimensions ==== ==== Connecteurs ==== * Connecteur P... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Module GPIO Démo}}&lt;br /&gt;
[[Image:Module_GPIO_Demo.jpg|300px|right]]&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
==== Dimensions ====&lt;br /&gt;
==== Connecteurs ====&lt;br /&gt;
* Connecteur P1&lt;br /&gt;
* Connecteur P2&lt;br /&gt;
* Connecteur P3&lt;br /&gt;
* Connecteur P4&lt;br /&gt;
* Connecteur P5&lt;br /&gt;
* Connecteur P6 et P7&lt;br /&gt;
* Connecteur P8&lt;br /&gt;
==== Jumpers ====&lt;br /&gt;
* Jumper J1&lt;br /&gt;
* Jumper J2&lt;br /&gt;
* Jumper J3 et J4&lt;br /&gt;
=== Electronique ===&lt;br /&gt;
==== Micro-contrôlleur LPC1224 ====&lt;br /&gt;
==== RAM interne ====&lt;br /&gt;
==== Mémoire Flash interne ====&lt;br /&gt;
==== Interfaces de communication ====&lt;br /&gt;
==== GPIO ====&lt;br /&gt;
==== ADC ====&lt;br /&gt;
==== Reset et mode ISP ====&lt;br /&gt;
==== I²C ====&lt;br /&gt;
* Adresses I²C&lt;br /&gt;
* EEPROM externe&lt;br /&gt;
* Capteur de température&lt;br /&gt;
==== Boutons et Led utilisateur ====&lt;br /&gt;
==== Bridge USB-UART ====&lt;br /&gt;
=== Logiciel ===&lt;br /&gt;
==== Récupération des sources ====&lt;br /&gt;
==== Organisation des sources ====&lt;br /&gt;
==== Point d&#039;entrée ====&lt;br /&gt;
==== Exemples ====&lt;br /&gt;
==== Compilation ====&lt;br /&gt;
&lt;br /&gt;
== Utilisation ==&lt;br /&gt;
== TODO List ==&lt;br /&gt;
== Documentation Technique et Schémas ==&lt;br /&gt;
== Historique ==&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael&amp;diff=129</id>
		<title>Articles/Nathael</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael&amp;diff=129"/>
		<updated>2020-09-03T00:56:48Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « * Electronique libre et DomoTab : conception d&amp;#039;un module électronique avec Kicad ** Kicad Reference Card ** Articles/... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Electronique libre et DomoTab : conception d&#039;un module électronique avec Kicad&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_RefCard|Kicad Reference Card]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie1|Partie 1: Module de développement - Schéma]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie2|Partie 2: Module de développement - Schéma - Interfaces pour la programmation et l&#039;identification]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie3|Partie 3: Du schéma au PCB]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie4|Partie 4: Un module en vrai, FabLab et fabrication maison]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie5|Partie 5: Programmation : premiers signes de vie]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie6|Partie 6: Programmation : échanges de données]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie7|Partie 7: Modification : station météo]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie8|Partie 8: Modification : commande d&#039;une lampe]]&lt;br /&gt;
** [[Articles/Nathael/Domotab_et_elec_Libre_partie9|Partie 9: Debug]]&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Dindinx&amp;diff=128</id>
		<title>Articles/Dindinx</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Dindinx&amp;diff=128"/>
		<updated>2020-09-03T00:56:30Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « * Réalisation de jeux sur LPC1224/SSD1306 (ARM Cortex-M0) * Pacman * Tetris »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* Réalisation de jeux sur LPC1224/SSD1306 (ARM Cortex-M0)&lt;br /&gt;
* [[Articles/Dindinx/Pacman|Pacman]]&lt;br /&gt;
* [[Articles/Dindinx/Tetris|Tetris]]&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Utilisateur:Nathael&amp;diff=113</id>
		<title>Utilisateur:Nathael</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Utilisateur:Nathael&amp;diff=113"/>
		<updated>2020-09-02T23:23:49Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page créée avec « Test »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Test&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Utilisateur:Cyprien&amp;diff=112</id>
		<title>Utilisateur:Cyprien</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Utilisateur:Cyprien&amp;diff=112"/>
		<updated>2020-09-02T23:22:14Z</updated>

		<summary type="html">&lt;p&gt;Nathael : Page vide créée&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=111</id>
		<title>Articles/Nathael/Domotab et elec Libre partie5</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=111"/>
		<updated>2020-09-02T22:08:24Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Un peu de place pour la pile */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Électronique et domotique libre - partie 5 : Programmation, Premiers signes de vie}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; margin-right: 2.5em;&amp;quot;&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DomoTab.png|200px|right]]&lt;br /&gt;
Programmation du module !&lt;br /&gt;
&lt;br /&gt;
Nous avons vu dans le quatrième article comment fabriquer le module GPIO-Démo (ou toute version modifiée), nous allons désormais nous atteler à lui donner vie.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1&#039;&#039;&#039; : La programmation sera faite en C, bien que d&#039;autres langages puissent être utilisés, à la seule condition qu&#039;il existe un compilateur qui puisse générer du code binaire pour ARM à partir de ce langage.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2&#039;&#039;&#039; : Les tailles indiquées dans cet article dépendent de la version de GCC utilisée, et il est presque certain que vous obtiendrez des tailles différentes, comme par exemple une taille de 256Mo, un cas que j&#039;ai eu fréquement en TP quand le compilateur créé la section data pour le bloc de données placé en RAM, à l&#039;adresse 0x10000000, soit 256Mo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;par Nathael Pajani&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:right&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
Paru dans le [http://boutique.ed-diamond.com/home/851-open-silicium-14.html numéro 14] du magazine Open Silicium.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Les documentations techniques ==&lt;br /&gt;
&lt;br /&gt;
La première étape lorsqu&#039;on veut écrire du code pour un système embarqué qui utilise un micro-contrôleur, c&#039;est d&#039;en trouver la documentation technique.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès aux documentations techniques est à mon avis un des critères principaux dans le choix des composants pour un projet, aussi bien pour les concepteurs que pour les utilisateurs.&lt;br /&gt;
&lt;br /&gt;
Si vous avez réalisé la conception du circuit, vous aurez normalement déjà eu besoin de ces documentations, dans le cas contraire, c&#039;est le moment de les récupérer.&lt;br /&gt;
Pour le module GPIO-Démo, il y a plusieurs documentations techniques nécessaires pour utiliser la totalité des fonctionnalités du module.&lt;br /&gt;
La première et la plus importante est celle du micro-contrôleur [7], mais vous aurez aussi besoin de celle du module, disponible sur le site de Techno-Innov [4], et de celles de l&#039;EEPROM I2C, et du capteur de température I2C.&lt;br /&gt;
&lt;br /&gt;
Encart : Pour ce qui est du bridge USB-UART, la documentation n&#039;est pas nécessaire pour la programmation du micro-contrôleur et du module, mais elle le devient si vous voulez modifier la façon dont le composant s&#039;identifie lorsque vous le connectez, par exemple pour pouvoir lui donner un nom spécifique ou simplifier l&#039;identification. Cela ne sera cependant pas le sujet de cet article.&lt;br /&gt;
&lt;br /&gt;
Pour récupérer les documentations techniques, vous avez le choix entre le site du fabriquant et celui du distributeur chez qui vous avec acheté les composants. Pour la majorité des composants j&#039;utilise le site du distributeur (possible uniquement si il fourni les bonnes documentations), mais pour les micro-contrôleurs je consulte le site du fabriquant car il fourni aussi les &amp;quot;errata&amp;quot; (notes d&#039;informations contenant les corrections sur la documentation) et le plus souvent des notes d&#039;application qui indiquent comment utiliser le composant pour telle ou telle application (avec parfois des exemples de code).&lt;br /&gt;
&lt;br /&gt;
== Outils de programmation ==&lt;br /&gt;
&lt;br /&gt;
La deuxième étape ne concerne toujours pas le code que vous voulez écrire.&lt;br /&gt;
&lt;br /&gt;
En effet, pour écrire du code vous n&#039;avez pas besoin de la &amp;quot;cible&amp;quot; (target en anglais) qui est le matériel sur lequel vous allez exécuter la version compilée du code, mais uniquement d&#039;un poste de développement, couramment appelé hôte (host en anglais).&lt;br /&gt;
&lt;br /&gt;
Cependant, la cible en question n&#039;a que faire des fichiers sources qui se trouvent sur votre poste de développement, et il vous faudra un certain nombre d&#039;outils pour passer des fichiers source (quelque soit le langage) au code exécutable par votre carte électronique.&lt;br /&gt;
&lt;br /&gt;
C&#039;est aussi un point très important à mon sens dans le choix d&#039;un système embarqué ou d&#039;un micro-contrôleur : quels sont les outils dont j&#039;aurais besoin pour passer de mon code source à un système fonctionnant avec ?&lt;br /&gt;
&lt;br /&gt;
Dans le cas des micro-contrôleurs de la gamme LPC de NXP il existe de nombreuses solutions pour passer de l&#039;un à l&#039;autre, mais ce qui est intéressant à mon sens c&#039;est qu&#039;il est possible de le faire avec un minimum de matériel et de logiciel : une liaison série &amp;quot;TTL 3.3V&amp;quot;, une chaîne de compilation croisée et un utilitaire pour &amp;quot;uploader&amp;quot; le code binaire.&lt;br /&gt;
&lt;br /&gt;
=== Matériel : un port USB (et le PC qui va avec) ===&lt;br /&gt;
&lt;br /&gt;
[[Image:14-Module sur USB.png|300px|right]]&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la liaison série &amp;quot;TTL 3.3V&amp;quot;, il existe plein d&#039;adaptateurs USB-UART fonctionnant en 3.3V, et pour le cas du module GPIO-Démo cet adaptateur est intégré sur le module, un port USB suffit donc.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès à cette liaison série se fera via un fichier spécial dont le nom sera devrait ressembler à &amp;quot;/dev/ttyUSB0&amp;quot;, le &amp;quot;USB0&amp;quot; pouvant différer selon votre système (&amp;quot;USB1&amp;quot;, USB2&amp;quot;, ... ou même &amp;quot;ACM0&amp;quot; avec d&#039;autres adaptateurs).&lt;br /&gt;
&lt;br /&gt;
=== Compilation : GNU ===&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la chaîne de compilation croisée, les micro-contrôleurs LPC de NXP utilisent des cœurs ARM Cortex-M*, très bien supportés par gcc, bien connu de tous les lecteurs de ce magazine (du moins je le pense), et parfaitement adapté à la cross-compilation.&lt;br /&gt;
&lt;br /&gt;
Dit comme ça, c&#039;est simple ... mais en fait, pas tant que ça.&lt;br /&gt;
Cette problématique pourrait faire l&#039;objet d&#039;un (petit ?) article, je ne l&#039;inclurai donc pas ici, je vous donne juste quelques pistes et suppose que vous saurez trouver les informations sur le net. De mon côté je dois les intégrer à la documentation technique du module GPIO-Démo, mais ce n&#039;est pas encore fait à l&#039;heure où j&#039;écris ces lignes :( [4].&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;avez pas déjà une chaîne de cross-compilation installée pour ARM vous avez globalement trois solutions : Debian/EmDebian (celle que j&#039;utilise), Launchpad, et Crosstools-ng.&lt;br /&gt;
&lt;br /&gt;
Le projet EmDebian fournit des paquets debian pour différentes chaînes de cross-compilation (ARM parmi tant d&#039;autres), qui sont entrain d&#039;être intégrées à Debian. Cela devrait simplifier les problèmes de dépôts et de dépendances dont souffrait les dépôts EmDebian, même si seule la version &amp;quot;arm-none-eabi&amp;quot; (qui nous suffit, nous n&#039;avons pas besoin de libC) est actuellement intégrée dans SID sans problèmes de dépendances (j&#039;ai bien dit &amp;quot;devrait&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Le site de Launchpad fourni aussi des versions binaires de la chaîne de cross-compilation GCC ARM.&lt;br /&gt;
&lt;br /&gt;
La solution CrossTools-ng : recompilation de sa propre chaîne de compilation croisée : la solution du dernier recours, si votre distribution ne fournit pas de solution packagée et que les versions binaires non signées ne vous conviennent pas.&lt;br /&gt;
&lt;br /&gt;
=== Programmation : lpctools (ou autre) ===&lt;br /&gt;
&lt;br /&gt;
Enfin, pour ce qui est de l&#039;utilitaire permettant de charger (uploader) le code binaire sur le micro-contrôleur (flasher le micro-contrôleur), je n&#039;avais pas trouvé d&#039;outil libre permettant de réaliser cette étape au moment où j&#039;ai étudié la possibilité d&#039;utiliser les micro-contrôleurs de NXP, mais le protocole série permettant de réaliser cette opération était documenté dans la documentation technique des micro-contrôleurs, il ne devait donc pas y avoir de problème de ce côté là.&lt;br /&gt;
&lt;br /&gt;
La seule solution &amp;quot;gratuite&amp;quot; que j&#039;avais trouvé à l&#039;époque ne fonctionnait que sur un seul système (pas le miens), ne fournissait pas ses sources, et interdisait une utilisation commerciale sans payer une licence, hors je voulais justement en faire une utilisation commerciale.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai donc pris quelques heures de mon temps pour coder un utilitaire permettant de programmer les micro-contrôleurs LPC, et placé le tout sous licence GPL v3 [5].&lt;br /&gt;
Le tout est désormais disponible sur le site de Techno-Innov, et est intégré depuis peu à la distribution Debian GNU/Linux (Sid et Jessie à l&#039;heure de l&#039;écriture de ces lignes).&lt;br /&gt;
&lt;br /&gt;
J&#039;ai entre-temps découvert d&#039;autres projets permettant de programmer des micro-contrôleurs LPC, mais je ne les ai pas testés (nxpprog - licence MIT, mxli - GPLv3, pyLPCTools - GPLv2) et constaté qu&#039;un autre paquet Debian fournit les outils permetant de programmer les micro-contrôleurs LPC de NXP : lpc21isp (qui dispose d&#039;ailleurs d&#039;une interface graphique : GLPC, qui elle n&#039;est pas dans les dépôts). Voir liens [6] en fin d&#039;article.&lt;br /&gt;
&lt;br /&gt;
== Makefile - particularités pour la compilation croisée ==&lt;br /&gt;
&lt;br /&gt;
Une dernière petite étape avant d&#039;écrire notre code, bien que l&#039;on se rapproche de la programmation, puisqu&#039;il s&#039;agit d&#039;un élément essentiel de tout projet : la création du Makefile.&lt;br /&gt;
&lt;br /&gt;
Dans le cas de la compilation pour une cible comme le module GPIO-Démo le Makefile doit inclure quelques éléments supplémentaires que l&#039;on ne retrouve habituellement pas dans un Makefile classique.&lt;br /&gt;
&lt;br /&gt;
Le premier élément concerne la définition du compilateur à utiliser. Nous utiliserons la variable &amp;quot;CROSS_COMPILE&amp;quot; à laquelle nous affecterons une valeur par défaut correspondant au préfixe du compilateur. Si vous voulez utiliser un compilateur correctement installé sur le système, il suffit d&#039;utiliser le préfixe, sinon, il faudra ajouter devant la totalité du chemin donnant accès au compilateur.&lt;br /&gt;
&lt;br /&gt;
Par exemple pour le compilateur EmDebian :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
ou avec un chemin complet pour un autre compilateur :&lt;br /&gt;
: CROSS_COMPILE ?= /usr/local/mon/compilateur/bin/arm-none-eabi-&lt;br /&gt;
&lt;br /&gt;
Le &amp;quot;?=&amp;quot; permet de ne modifier la variable que si elle n&#039;existe pas, notamment si elle n&#039;est pas déjà présente dans la ligne de commande.&lt;br /&gt;
&lt;br /&gt;
Cette variable est ensuite utilisée pour modifier la variable &amp;quot;CC&amp;quot; utilisée par &amp;quot;make&amp;quot; pour compiler les fichiers de code source C. Si vous utilisez un autre langage, modifiez la variable correspondante.&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
Il est aussi possible d&#039;en profiter pour spécifier une version du compilateur installé :&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc-4.7&lt;br /&gt;
Nous allons en profiter pour définir la variable &amp;quot;LD&amp;quot; qui correspond à l&#039;éditeur de liens (linker en anglais) :&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
&lt;br /&gt;
Il nous faut ensuite définir la cible pour laquelle nous voulons compiler. Dans notre cas il s&#039;agit d&#039;un cœur ARM Cortex-M0, qui utilise le jeu d&#039;instructions &amp;quot;thumb&amp;quot; (instructions sur 16bits permettant d&#039;obtenir un code plus compact), nous allons donc utiliser les options -mcpu et -mthumb de gcc pour lui indiquer notre besoin :&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: CFLAGS = -Wall -mthumb -mcpu=$(CPU)&lt;br /&gt;
&lt;br /&gt;
En plus de cela, nous allons demander au compilateur de ne pas reconnaître les fonctions pour lesquelles il a une définition interne (builtin) tout simplement parce que la majorité de ces fonctions dépendent d&#039;un environnement très différent de celui de notre micro-contrôleur, soit par la présence d&#039;une bibliothèque C, d&#039;un système d&#039;exploitation respectant la norme POSIX, ou d&#039;une unité de calcul flottant.&lt;br /&gt;
Rien de tout ceci n&#039;est vrai dans notre cas, et il est donc préférable que le compilateur nous informe si nous tentons d&#039;utiliser ces fonctions sans l&#039;avoir explicitement demandé en utilisant le préfixe &amp;quot;__builtin__&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous demanderons aussi au compilateur de bien placer les données et les fonctions dans leurs sections respectives. Malgré ce que dit la documentation de GCC, cela permet (au moins dans notre cas) de produire un binaire plus petit. Cela se fait à l&#039;aide des directives d&#039;optimisation &amp;quot;-ffunction-sections&amp;quot; et &amp;quot;-fdata-sections&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous ajouterons ces directives dans une variable dédiée :&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Nous obtenons donc les lignes suivantes à ajouter à votre Makefile :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
: CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
&lt;br /&gt;
Notre Makefile ressemblerait alors à ceci :&lt;br /&gt;
 NAME = mod_gpio&lt;br /&gt;
 CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
 CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
 LD = $(CROSS_COMPILE)ld&lt;br /&gt;
 CPU = cortex-m0&lt;br /&gt;
 FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
 CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
 &lt;br /&gt;
 .PHONY: all&lt;br /&gt;
 all: $(NAME)&lt;br /&gt;
 &lt;br /&gt;
 SRC = $(wildcard *.c)&lt;br /&gt;
 OBJS = $(SRC:.c=.o)&lt;br /&gt;
 &lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ -o $@&lt;br /&gt;
Ce Makefile est encore incomplet et ne permet pas d&#039;obtenir le binaire pour notre micro-contrôleur, mais nous ajouterons les parties manquantes plus tard.&lt;br /&gt;
&lt;br /&gt;
En attendant, ce Makefile nous permettra de compiler le code que nous allons écrire, passons donc aux parties intéressantes, et le reste du Makefile sera bien plus simple à comprendre.&lt;br /&gt;
&lt;br /&gt;
== Commençons simple ==&lt;br /&gt;
&lt;br /&gt;
Pour ne pas trop compliquer les choses dès le début, nous allons tenter de faire clignoter la led bicolore présente sur le module GPIO-Démo.&lt;br /&gt;
&lt;br /&gt;
Notre squelette de code ressemblera à s&#039;y méprendre à ce que l&#039;on pourrait avoir pour un programme plus commun :&lt;br /&gt;
 /*&lt;br /&gt;
  * Notre exemple simple pour Open Silicium&lt;br /&gt;
  */&lt;br /&gt;
 void system_init(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* System init ? */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* Micro-controller init */&lt;br /&gt;
 	system_init();&lt;br /&gt;
 	&lt;br /&gt;
 	while (1) {&lt;br /&gt;
 		/* Change the led state */&lt;br /&gt;
 		/* Wait some time */&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 }&lt;br /&gt;
Si vous compilez ce petit morceau de code avec notre Makefile, vous obtiendrez un binaire qui globalement ne fait rien, mais a déjà une taille de 5.7 Ko.&lt;br /&gt;
C&#039;est gros pour ne rien faire, d&#039;autant que la mémoire Flash de notre micro-contrôleur ne fait que 32 Ko.&lt;br /&gt;
&lt;br /&gt;
Si on regarde plus loin, par exemple avec l&#039;utilitaire &#039;&#039;file&#039;&#039;, on obtient quelques informations supplémentaires :&lt;br /&gt;
 $ file mod_gpio&lt;br /&gt;
 mod_gpio: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), [....], not stripped&lt;br /&gt;
&lt;br /&gt;
Arghhh, notre binaire est un exécutable dynamique au format ELF, qui utilise des bibliothèques partagées !&lt;br /&gt;
&lt;br /&gt;
Nous l&#039;avons déjà évoqué, notre micro-contrôleur n&#039;a pas de libC ni de système d&#039;exploitation, notre binaire ne peut donc pas être dynamique (lié dynamiquement à des bibliothèques) !&lt;br /&gt;
Il nous faut donc faire l&#039;édition de lien en &amp;quot;static&amp;quot;, en apportant quelques modification à notre Makefile. Nous allons introduire une variable &amp;quot;LDFLAGS&amp;quot;, que l&#039;on ajoutera à la règle de compilation utilisée pour l&#039;édition de liens.&lt;br /&gt;
 LDFLAGS = -static&lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ $(LDFLAGS) -o $@&lt;br /&gt;
Recompilons notre projet ... 608 Ko !!! Re-Argh !&lt;br /&gt;
&lt;br /&gt;
Visiblement quelqu&#039;un ajoute du code dont nous n&#039;avons pas besoin. Il faut du moins l&#039;espérer, sinon il ne sera jamais possible de faire rentrer un programme dans la flash de notre micro-contrôleur, qui fait toujours 32Ko.&lt;br /&gt;
&lt;br /&gt;
L&#039;option &amp;quot;static&amp;quot; demande à l&#039;éditeur de lien de créer un binaire statique, mais résultat il nous ajoute tout ce qui est utile de la libC pour un exécutable ... pour un système Linux.&lt;br /&gt;
D&#039;ailleurs, &#039;&#039;file&#039;&#039; nous dit bien que notre exécutable est au format ELF.&lt;br /&gt;
&lt;br /&gt;
Pour commencer nous allons demander à l&#039;éditeur de liens (ld) de ne pas inclure les éléments de démarrage dans notre binaire, car ils sont inutiles sur notre micro-contrôleur. Pour cela nous ajoutons l&#039;option &amp;quot;-nostartfiles&amp;quot; à nos directives pour l&#039;édition de liens.&lt;br /&gt;
&lt;br /&gt;
Et hop, une recompilation plus tard, notre binaire ne fait plus que 1 Ko :)&lt;br /&gt;
Mais pour &#039;&#039;file&#039;&#039;, ce binaire est toujours au format ELF, et gcc nous informe qu&#039;il n&#039;a pas trouvé de symbole d&#039;entrée &amp;quot;_start&amp;quot; et qu&#039;il utilise une adresse par défaut (nous l&#039;avons cherché, cela fait partie de ce que nous avons demandé à l&#039;éditeur de liens en ajoutant l&#039;option &amp;quot;-nostartfiles&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
En effet, le &amp;quot;main&amp;quot; de nos programmes en C n&#039;est que le point de départ de l&#039;exécution de notre code, mais pas celui du programme. Il est précédé par un certain nombre de routines (fonctions) d&#039;initialisation, dont le point d&#039;entrée est la routine &amp;quot;_start&amp;quot;, qui appellera le main &amp;quot;classique&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Mais notre but n&#039;est pas de créer un exécutable pour un système Linux, nous devons créer un binaire pour notre micro-contrôleur. Il est désormais temps de nous plonger dans la documentation du micro-contrôleur pour comprendre comment il démarre, pour pouvoir adapter notre code au démarrage du micro-contrôleur et fournir l&#039;équivalent de cette routine &amp;quot;_start&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bootstrap == &lt;br /&gt;
&lt;br /&gt;
=== Table des vecteurs d&#039;interruption ===&lt;br /&gt;
&lt;br /&gt;
Pour avoir des informations sur le démarrage du micro-contrôleur LPC1224 dans sa documentation technique [7] il y a deux chapitres intéressants.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons nous référer au chapitre 4 (LPC122x System control) qui inclut une section sur le reset du micro-contrôleur (4.6 : Reset), dans laquelle on apprend qu&#039;une fois que la condition de reset disparait et que les procédures internes se sont exécutées, le processeur commence l&#039;exécution à l&#039;adresse contenue dans le vecteur &amp;quot;Reset&amp;quot; du &amp;quot;boot block&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous avons ainsi quelques informations, mais qu&#039;est-ce que le vecteur &amp;quot;Reset&amp;quot; et le &amp;quot;boot block&amp;quot; ? Cela nous mène au deuxième chapitre intéressant, le chapitre 25 sur le cœur ARM Cortex-M0. On y trouve une section sur le processeur (25.3 : Processor) avec une sous section concernant les exeptions (25.3.3 : Exception model). &lt;br /&gt;
&lt;br /&gt;
Dans les informations sur les exceptions (25.3.3.2), et plus particulièrement l&#039;exception &amp;quot;Reset&amp;quot;, il est indiqué qu&#039;après un &amp;quot;Reset&amp;quot; l&#039;exécution reprend à l&#039;adresse indiquée dans le vecteur &amp;quot;Reset&amp;quot; dans la table des vecteurs d&#039;interruption.&lt;br /&gt;
&lt;br /&gt;
Bien, cela confirme ce qui se trouvait dans le chapitre 4. Mais cette fois, nous avons une sous-section &amp;quot;25.3.3.4 Vector table&amp;quot;, qui décrit cette fameuse table des vecteurs d&#039;exception, précisant qu&#039;elle contient l&#039;addresse de toutes les routines de gestion des exceptions (les fameux &amp;quot;vecteurs&amp;quot; d&#039;exception, dont le vecteur &amp;quot;Reset&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Remarquez au passage que les interruptions sont gérées de la même façon, l&#039;addresse d&#039;entrée des routines de gestion des interruptions se trouve dans cette même table.&lt;br /&gt;
&lt;br /&gt;
Et en dessous de cette table, nous avons une autre information très intéressante : &amp;quot;The vector table is fixed at address 0x00000000&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Si l&#039;on se réfère à la table 65 de la section &amp;quot;25.3.2 Memory model&amp;quot;, et à la figure 2 de la section &amp;quot;2.3 Memory allocation&amp;quot;, on découvre que cette adresse est en fait le début de la mémoire flash du micro-contrôleur, qui devra contenir notre code binaire.&lt;br /&gt;
&lt;br /&gt;
Reste à créer cette table, et à la placer au bon endroit dans le code binaire compilé...&lt;br /&gt;
&lt;br /&gt;
=== Les &amp;quot;handlers&amp;quot; et les &amp;quot;dummy handlers&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
Nous allons commencer par la partie code.&lt;br /&gt;
Ce code peut être placé dans le même fichier que celui ou ce trouve notre fonction main, ou dans un autre fichier, cela n&#039;a pas d&#039;importance. Si vous vous référez au code du module GPIO-Démo disponible dans les dépôts git de Techno-Innov, vous trouverez ce code dans le fichier &amp;quot;core/bootstrap.c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Vecteurs_interruption.png|350px|right]]&lt;br /&gt;
&lt;br /&gt;
 /* Cortex M0 core interrupt handlers */&lt;br /&gt;
 void Reset_Handler(void);&lt;br /&gt;
 void NMI_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 void HardFault_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void);&lt;br /&gt;
 &lt;br /&gt;
 void *vector_table[] = {&lt;br /&gt;
 	0,&lt;br /&gt;
 	Reset_Handler,&lt;br /&gt;
 	NMI_Handler,&lt;br /&gt;
 	HardFault_Handler,&lt;br /&gt;
 	0,&lt;br /&gt;
 	/* [......] */&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void) {&lt;br /&gt;
     while (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Voici un petit morceau de code relativement court qui définit notre table de vecteur ainsi que les routines de gestion correspondantes.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, faisons un petit point sur certains éléments : les attributs utilisés pour la déclaration de deux de nos routines de gestion des exceptions : &amp;quot;__attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ces attributs permettent de définir un alias &amp;quot;faible&amp;quot; pour une fonction, ce qui veut dire que si le compilateur ne trouve pas de définition pour cette fonction, il pourra utiliser son alias, que nous avons défini plus bas. Au contraire, si dans un autre fichier (ou celui-ci) vous définissez l&#039;une de ces fonctions, c&#039;est votre définition qui sera utilisée.&lt;br /&gt;
&lt;br /&gt;
Note : je n&#039;ai pas mis la totalité de la table des vecteurs, cela n&#039;a pas d&#039;intérêt pour les explications, et notre programme fonctionnera sans, mais il faudrait la compléter pour un vrai programme, en faisant attention à l&#039;ordre, à partir des informations de la figure 68 déjà évoquée, et de la table 4 du chapitre 3 concernant le gestionnaire d&#039;interruptions (vous noterez la typo, il s&#039;agit des numéros d&#039;IRQ et non pas des numéros des vecteurs d&#039;exception).&lt;br /&gt;
&lt;br /&gt;
=== Appeler notre main() ===&lt;br /&gt;
Ce petit bout de code compile donc, puisque tout est défini, mais nous avons toujours l&#039;avertissement concernant le symbole d&#039;entrée &amp;quot;_start&amp;quot; qui n&#039;a pas été trouvé. Nous ne sommes pas plus avancé.&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, nous avons déjà indiqué que le point d&#039;entrée de notre code est la fonction main() (qui pourrait avoir n&#039;importe quel nom), mais pour notre micro-controlleur la fonction d&#039;entrée du programme est la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
La solution pour faire le lien est toute simple : il suffit d&#039;appeler la fonction main() depuis la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
 int main(void);&lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 	main();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Tisser des liens, c&#039;est important ===&lt;br /&gt;
Cela ne résout cependant aucun de nos problèmes, nous allons donc devoir donner plus d&#039;indications à l&#039;éditeur de liens, en créant un script pour l&#039;édition de lien (lpc_link_lpc1224.ld). Nous donnerons le nom de ce script à l&#039;éditeur de liens en utilisant l&#039;otion &amp;quot;-T&#039;&#039;lpc_link_lpc1224.ld&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ce script d&#039;édition de lien (&amp;quot;linker script&amp;quot; en anglais) est en fait un fichier qui décrit la mémoire de notre micro-contrôleur, ainsi que l&#039;organisation que devra respecter notre binaire.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc commencer, toujours à partir des mêmes informations en provenance de la documentation technique, par définir quelle est la mémoire disponible, aussi bien la mémoire &amp;quot;vive&amp;quot; (SRAM) que la mémoire &amp;quot;morte&amp;quot; (FLASH).&lt;br /&gt;
&lt;br /&gt;
 MEMORY&lt;br /&gt;
 {&lt;br /&gt;
 	sram (rwx) : ORIGIN = 0x10000000, LENGTH = 4k&lt;br /&gt;
 	flash (rx) : ORIGIN = 0x00000000, LENGTH = 32k&lt;br /&gt;
 }&lt;br /&gt;
Nous définissons ainsi l&#039;adresse et la taille (et les droits d&#039;accès) de la sram et de la flash, qui deviennent deux blocs de mémoire disponibles pour l&#039;éditeur de liens, qui pourra donc y placer du code et des données.&lt;br /&gt;
&lt;br /&gt;
Il nous faut maintenant expliquer à l&#039;éditeur de liens comment organiser le code et les données dans ces blocs de mémoire, et tout particulièrement notre tableau de vecteurs d&#039;interruptions&lt;br /&gt;
&lt;br /&gt;
Le code d&#039;un programme est composé de &amp;quot;sections&amp;quot;, dans lesquelles le compilateur place chaque fonction et chaque variable en fonction de différents critères, que l&#039;on peut contrôler soit à partir de directives de compilation, soit d&#039;attributs ajoutés dans notre code C&lt;br /&gt;
&lt;br /&gt;
Nous allons donc modifier notre tableau de vecteurs d&#039;interruptions pour lui ajouter un attribut &amp;quot;section&amp;quot; qui forcera l&#039;éditeur de liens à le placer dans la section que nous avons défini.&lt;br /&gt;
: void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
&lt;br /&gt;
Et en parallèle, nous allons définir dans notre script quelles sont les sections que nous voulons trouver dans notre binaire, et dans quel ordre.&lt;br /&gt;
Commençons simple (si si, je vous assure), nous compliquerons plus tard :&lt;br /&gt;
 SECTIONS {&lt;br /&gt;
 	. = ORIGIN(flash);&lt;br /&gt;
 	.text :&lt;br /&gt;
 	{&lt;br /&gt;
 		KEEP(*(.vectors))&lt;br /&gt;
 		*(.text*)&lt;br /&gt;
 		*(.rodata*)&lt;br /&gt;
 	} &amp;gt;flash&lt;br /&gt;
 	.data :&lt;br /&gt;
 	{&lt;br /&gt;
 		*(.data*)&lt;br /&gt;
 		*(.bss*)&lt;br /&gt;
 	} &amp;gt;sram&lt;br /&gt;
 }&lt;br /&gt;
Pour commencer, nous définissons l&#039;adresse courante (.) comme étant l&#039;origine de du bloc de mémoire &amp;quot;flash&amp;quot; (le bloc de mémoire défini précédemment et auquel nous avons donné ce nom, bien qu&#039;un autre nom aurait pu faire l&#039;affaire).&lt;br /&gt;
Ceci est important pour que l&#039;éditeur de liens puisse définir les adresses des fonctions pour l&#039;exécution de notre code.&lt;br /&gt;
À partir de ce point nous définissons une section &amp;quot;text&amp;quot;, dans laquelle nous allons demander à l&#039;éditeur de lien de mettre plusieurs éléments, à commencer par notre fameuse table de vecteurs, en lui interdisant d&#039;en changer la position !&lt;br /&gt;
Après quoi, nous lui demandons de placer l&#039;ensemble du code, que le compilateur a placé dans des section &amp;quot;.text.*&amp;quot;, puis les données en lecture seule (Read-Only data = rodata), et de placer le tout dans le bloc de mémoire &amp;quot;flash&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
À la suite, nous créons une section &amp;quot;data&amp;quot;, dans laquelle nous lui demandons de placer les données initialisées à des valeurs non nulles (data), puis les données initialement nulles (bss [8]), et de placer cette section en RAM.&lt;br /&gt;
&lt;br /&gt;
Ne reste plus qu&#039;une information à donner à l&#039;éditeur de liens (pour l&#039;instant): le point d&#039;entrée de notre programme.&lt;br /&gt;
Ceci est relativement simple et explicite :&lt;br /&gt;
: ENTRY(Reset_Handler)&lt;br /&gt;
&lt;br /&gt;
Dans notre Makefile la variable LDFLAGS devient :&lt;br /&gt;
: LDFLAGS = -static -nostartfiles -Tlpc_link_lpc1224.ld&lt;br /&gt;
&lt;br /&gt;
Une compilation plus tard, sans avertissements cette fois, nous avons un binaire ... beaucoup trop gros : notre binaire fait maintenant plus de 66 Ko !&lt;br /&gt;
&lt;br /&gt;
Soyons un peu curieux et allons donc voir ce qu&#039;il contient, mais pas à la main, rassurez vous, utilisons un utilitaire fait exprès pour cela : &#039;&#039;objdump&#039;&#039;. attention, il faut bien entendu utiliser la version &amp;quot;ARM&amp;quot; de objdump, donc avec le préfixe &amp;quot;CROSS_COMPILE&amp;quot;, soit dans mon cas &#039;&#039;arm-linux-gnueabi-objdump&#039;&#039;, avec l&#039;option &#039;&#039;--disassemble-all&#039;&#039; (-D) :&lt;br /&gt;
: arm-linux-gnueabi-objdump -D mod_gpio &amp;gt; dump&lt;br /&gt;
Et là, surprise, la version &amp;quot;désassemblée&amp;quot; de notre binaire est plus petite que la version binaire (le fichier &amp;quot;dump&amp;quot; fait 2.2 Ko).&lt;br /&gt;
&lt;br /&gt;
Regardons tout de même son contenu.&lt;br /&gt;
La première ligne nous informe que le format du fichier est &amp;quot;elf32-littlearm&amp;quot; ... pas grand chose à voir avec ce que nous voulions, un &amp;quot;simple&amp;quot; binaire (Notre micro-contrôleur n&#039;a toujours pas appris à lire les exécutables au format ELF). Premier problème.&lt;br /&gt;
&lt;br /&gt;
Quelqu&#039;un est venu glisser une section &amp;quot;.note.gnu.build-id&amp;quot; avant notre section &amp;quot;.text&amp;quot;, que l&#039;éditeur de liens aimerait placer en début de RAM (&amp;quot;10000000 &amp;lt;_sram_base&amp;gt;&amp;quot;), ce qui n&#039;a pas d&#039;intérêt pour nous.&lt;br /&gt;
&lt;br /&gt;
S&#039;en suit tout de même notre section &amp;quot;.text&amp;quot;, qui commence bien par notre table (enfin ! on nous écoute un peu !), suivie de nos quelques maigres fonctions. Notez les adresses des fonctions dans la table des vecteurs, qui sont toutes impaires. Ceci indique que notre processeur exécutera ces fonctions en mode &amp;quot;thumb&amp;quot; qui est bien le mode que nous avions demandé (-mthumb).&lt;br /&gt;
&lt;br /&gt;
Et encore une fois, notre section &amp;quot;.text&amp;quot; n&#039;est pas suivie de nos données, mais d&#039;autres sections que nous n&#039;avions pas demandées !&lt;br /&gt;
Certes, nous n&#039;avons pas de variables, et l&#039;éditeur de lien n&#039;ayant rien à mettre dans notre section &amp;quot;.data&amp;quot;, il ne l&#039;a pas créée, mais au final nous sommes relativement loin de ce que nous voulions.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc demander à l&#039;éditeur de liens de générer un petit peu moins de choses en ajoutant l&#039;option &#039;&#039;-Wl,--build-id=none&#039;&#039; à nos directives de compilation (variable LDFLAGS de notre Makefile), ce qui nous donne un binaire moitié plus petit mais toujours trop gros.&lt;br /&gt;
&lt;br /&gt;
=== Un binaire vraiment binaire ===&lt;br /&gt;
Mais nous ne pouvons pas en demander bien plus à l&#039;éditeur de liens, dont le travail est de créer des exécutables au format ELF.&lt;br /&gt;
Pour créer d&#039;autres types de binaire, nous devrons utiliser l&#039;utilitaire &#039;&#039;objcopy&#039;&#039; (toujours la version ARM, donc en fait &#039;&#039;arm-linux-gnueabi-objcopy&#039;&#039;).&lt;br /&gt;
Le travail de cet utilitaire est de créer des binaires à partir des exécutables ELF, en ne conservant que les sections qui nous intéressent (du moins, c&#039;est l&#039;usage que nous en ferons).&lt;br /&gt;
&lt;br /&gt;
Nous allons demander à cet utilitaire de nous générer une image binaire à partir du résultat de notre compilation en ajoutant dans notre Makefile une cible &amp;quot;$(NAME).bin&amp;quot; qui deviendra notre cible par défaut et dépendra de la génération du fichier au format ELF :&lt;br /&gt;
&lt;br /&gt;
 all: $(NAME).bin&lt;br /&gt;
 &lt;br /&gt;
 $(NAME).bin: $(NAME)&lt;br /&gt;
 	$(CROSS_COMPILE)objcopy -O binary $^ $@&lt;br /&gt;
&lt;br /&gt;
Et notre objectif est enfin atteint, avec un binaire de ... 36 octets !&amp;lt;br /&amp;gt;&lt;br /&gt;
Rappelez vous, je n&#039;ai mis que 5 entrées dans ma table de vecteurs, soit 20 octets, suivis de quelques fonctions vides. Tout va bien.&lt;br /&gt;
&lt;br /&gt;
== Un programme un peu plus utile ==&lt;br /&gt;
&lt;br /&gt;
Nous allons désormais pouvoir nous occuper d&#039;allumer nos Leds, en quelque sorte le &amp;quot;Hello world&amp;quot; de l&#039;électronique.&lt;br /&gt;
&lt;br /&gt;
=== Entrées et sorties ===&lt;br /&gt;
Du point de vue de notre micro-contrôleur, allumer ou éteindre une Led revient à changer l&#039;état de la sortie correspondante.&lt;br /&gt;
&lt;br /&gt;
Les entrées/sorties du microcontrôleur peuvent avoir plusieurs fonctions, mais hormis quelques exceptions elles sont par défaut configurées en entrées/sorties (GPIO (general Purpose Input Output) en anglais) avec la résistance de pull-up interne activée. Pour simplifier, nous laisserons donc cette étape de la configuration de côté pour l&#039;instant, et reviendrons dessus lorsque nous attaquerons la programmation d&#039;interfaces plus complexes.&lt;br /&gt;
&lt;br /&gt;
: Note : Les exceptions sont les GPIO 13, 25 et 26 du port 0 (respectivement Reset, SWDIO et SWDCLK), qui permettent le reset et le debug, ainsi que quatre GPIO sur lesquelles la fonction &amp;quot;0&amp;quot; est réservée : les GPIO 30 et 31 du port 0 et les GPIO 0 et 1 du port 1.&lt;br /&gt;
&lt;br /&gt;
=== Les registres ===&lt;br /&gt;
Pour changer l&#039;état d&#039;une de ces entrées/sorties, il faut commencer par la configurer en sortie, puis définir sont état.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, il est important de comprendre que le processeur de notre micro-contrôleur ne voit que de la mémoire autour de lui. Il n&#039;a pas accès directement aux signaux électriques.&lt;br /&gt;
Pour accéder aux fonctions spéciales comme l&#039;état électrique d&#039;une sortie le processeur doit donc modifier des données dans une zone mémoire spécifique, dédiée à cette sortie, que l&#039;on appelle un registre.&lt;br /&gt;
&lt;br /&gt;
Notre micro-contrôleur dispose d&#039;un grand nombre de registres qui ont tous une taille de 32 bits, même si souvent certains bits ne sont pas utilisés (ils sont alors &amp;quot;réservés&amp;quot;).&lt;br /&gt;
Ces registres particuliers, qui nous donnent accès aux fonctions spéciales du micro-contrôleur, comme la configuration et l&#039;état des entrées sorties, sont accessibles chacun à une adresse fixe dans l&#039;espace d&#039;adressage du micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Nous avons déjà eu besoin d&#039;informations sur cet espace d&#039;adressage lorsque nous avons cherché des informations sur le démarrage du micro-contrôleur, il se trouve représenté sur la figure 2 dans la section &amp;quot;2.3 Memory allocation&amp;quot; du chapitre 2 (LPC122x Memory map).&lt;br /&gt;
&lt;br /&gt;
L&#039;adresse qui nous intéresse dépend du port sur lequel les leds sont connectées.&lt;br /&gt;
La led bicolore étant connectée sur le port 1 ce sont les registres présents à l&#039;adresse 0x50010000 que nous devrons utiliser.&lt;br /&gt;
Cette adresse est aussi rappelée avec la description des registres dans le chapitre 8 (LPC122x General Purpose I/O (GPIO))&lt;br /&gt;
&lt;br /&gt;
À partir de cette adresse se trouvent une série de registres permettant de contrôler les entrées/sorties du port 1. La modification du contenu de la mémoire accessible ainsi modifiera donc le comportement des entrées/sorties correspondantes ou leur état lorsqu&#039;elles sont configurées en sortie.&lt;br /&gt;
&lt;br /&gt;
Très (trop) souvent, pour accéder à ces registres, les programmeurs utilisent des définitions selon le principe suivant:&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 #define PORT1_MASK  (LPC_GPIO_1_BASE + 0x00)&lt;br /&gt;
 #define PORT1_PIN   (LPC_GPIO_1_BASE + 0x04)&lt;br /&gt;
 #define PORT1_OUT   (LPC_GPIO_1_BASE + 0x08)&lt;br /&gt;
 /* [.....] */&lt;br /&gt;
Personnellement je trouve cette façon de faire très inefficace, et peu lisible (voire complètement illisible), et je préfère l&#039;utilisation de structures.&lt;br /&gt;
Cela me semble beaucoup plus lisible, plus adapté pour accéder à de la mémoire qui est structurée, et apporte aussi un très net avantage lorsqu&#039;il existe plusieurs ensembles de registres utilisant la même organisation, par exemple quand il y a plusieurs liaisons séries sur le micro-contrôleur, ou dans le cas qui nous intéresse pour l&#039;instant, plusieurs ports d&#039;entrées/sorties.&lt;br /&gt;
La définition se passe alors ainsi :&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_0_BASE  (LPC_AHB_BASE + 0x00000)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 /* General Purpose Input/Output (GPIO) */&lt;br /&gt;
 struct lpc_gpio&lt;br /&gt;
 {&lt;br /&gt;
    volatile uint32_t mask;       /* 0x00 : Pin mask, affects data, out, set, clear and invert */&lt;br /&gt;
    volatile uint32_t in;         /* 0x04 : Port data Register (R/-) */&lt;br /&gt;
    volatile uint32_t out;        /* 0x08 : Port output Register (R/W) */&lt;br /&gt;
    volatile uint32_t set;        /* 0x0C : Port output set Register (-/W) */&lt;br /&gt;
    volatile uint32_t clear;      /* 0x10 : Port output clear Register (-/W) */&lt;br /&gt;
    volatile uint32_t toggle;     /* 0x14 : Port output invert Register (-/W) */&lt;br /&gt;
    uint32_t reserved[2];&lt;br /&gt;
    volatile uint32_t data_dir;   /* 0x20 : Data direction Register (R/W) */&lt;br /&gt;
    /* [.....] */&lt;br /&gt;
 };&lt;br /&gt;
 #define LPC_GPIO_0      ((struct lpc_gpio *) LPC_GPIO_0_BASE)&lt;br /&gt;
 #define LPC_GPIO_1      ((struct lpc_gpio *) LPC_GPIO_1_BASE)&lt;br /&gt;
À noter, l&#039;utilisation du mot clé &amp;quot;volatile&amp;quot; qui interdira au compilateur d&#039;optimiser les accès à ces registres en gardant des copies intermédiaires, forçant la lecture ou l&#039;écriture immédiate.&lt;br /&gt;
&lt;br /&gt;
Cette notation nous donne aussi l&#039;information de la taille des données présentes à ces adresses, dans ce cas là, des valeurs sur 32 bits.&lt;br /&gt;
&lt;br /&gt;
Pour l&#039;utilisation dans le code, c&#039;est ensuite très simple, il suffit de déclarer un pointeur vers cette structure, puis d&#039;accéder au champ qui nous intéresse :&lt;br /&gt;
 struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
 gpio1-&amp;gt;out = 0;&lt;br /&gt;
&lt;br /&gt;
=== Allumer les leds ===&lt;br /&gt;
&lt;br /&gt;
Reste à déterminer quels sont les champs qui nous intéressent et quelles valeurs nous devons écrire dedans.&lt;br /&gt;
Pour configurer les pins reliées à nos Leds en sortie nous devons modifier le registre &amp;quot;DIR&amp;quot; (appelé &amp;quot;data_dir&amp;quot; dans la structure), et mettre les bits 4 et 5 à &amp;quot;1&amp;quot; puisque chaque bit de ce registre permet de configurer une des pins du port correspondant, le bit 0 pour la pin 0, le bit 1 pour la pin 1, et ainsi de suite (attention, ici les numéros de pins ne sont pas les numéros des pattes du composant).&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc modifier notre main() pour obtenir le code suivant qui réalise cette opération de façon lisible, et positionne la Led verte à l&#039;état &amp;quot;allumée&amp;quot;, sans modifier l&#039;état des autres sorties du port 1 :&lt;br /&gt;
 /* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */&lt;br /&gt;
 #define LED_RED    5&lt;br /&gt;
 #define LED_GREEN  4&lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
    /* Micro-controller init */&lt;br /&gt;
    system_init();&lt;br /&gt;
    /* Configure the Status Led pins */&lt;br /&gt;
    gpio1-&amp;gt;data_dir |= (1 &amp;lt;&amp;lt; LED_GREEN) | (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    /* Turn Green Led ON */&lt;br /&gt;
    gpio1-&amp;gt;set = (1 &amp;lt;&amp;lt; LED_GREEN);&lt;br /&gt;
    gpio1-&amp;gt;clear = (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    while (1) {&lt;br /&gt;
        /* Change the led state */&lt;br /&gt;
        /* Wait some time */&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[Encart : Décalages de bits] :&lt;br /&gt;
: La notation &amp;quot;&amp;lt;&amp;lt;&amp;quot; correspond à l&#039;opérateur logique &amp;quot;décalage de bits vers la gauche&amp;quot; (&amp;quot;&amp;gt;&amp;gt;&amp;quot; pour le décalage à droite). Voir l&#039;article wikipedia sur le sujet, en Anglais, la version Française étant catastrophiquement incomplète [9].&lt;br /&gt;
&lt;br /&gt;
== Mettre le code sur le micro-contrôleur : lpctools ==&lt;br /&gt;
&lt;br /&gt;
Je sais que vous êtes de plus en plus impatients et que vous voulez voir le résultat de tout ceci en vrai, nous allons donc passer à la mise en flash sur le micro-contrôleur pour tester tout cela.&lt;br /&gt;
&lt;br /&gt;
Je ne traiterais ici que le cas de la version 48 broches du micro-contrôleur LPC1224 (package LQFP48). A vous d&#039;adapter si vous utilisez un autre micro-contrôleur, le principe étant très similaire pour tous les LPC de NXP. Pour les autres gammes de micro-contrôleurs, référez vous à leurs docs techniques et aux informations sur Internet.&lt;br /&gt;
&lt;br /&gt;
=== Connexion ===&lt;br /&gt;
Si vous avez mis l&#039;adaptateur USB-UART sur votre module comme proposé dans les articles précédents, l&#039;étape de connexion au PC est simple, connectez votre module sur un port USB, directement ou via un câble en fonction du connecteur USB que vous avez choisi.&lt;br /&gt;
&lt;br /&gt;
Sinon, il vous faudra un adaptateur USB-UART (souvent vendus comme adaptateurs USB-série) fonctionnant en 3.3V, et relier les signaux Rx et Tx aux signaux TXD0 et RXD0 correspondant à l&#039;UART 0 du micro-contrôleur LPC1224 qui se trouvent sur le port 0, pins 1 et 2 (broches 16 et 17 du composant). Il est alors préférable d&#039;avoir rendu ces signaux accesssibles sur un connecteur de votre choix, sans quoi il vous faudra souder des fils directement sur les pattes du micro-contrôleur ... possible, mais pas conseillé du tout).&lt;br /&gt;
&lt;br /&gt;
=== Mode ISP ===&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite mettre le micro-contrôleur en mode programmation (ISP : &amp;quot;In System Programming&amp;quot; en anglais). Le chapitre 20 (LPC122x Flash ISP/IAP) indique qu&#039;il faut maintenir la pin 12 du port 0 (broche 27) à l&#039;état bas (0V) pendant au moins 3ms après avoir relaché le signal &amp;quot;Reset&amp;quot; (pin 13 du port 0, broche 28). La suite du chapitre décrit le protocole de programmation, uniquement utile si vous voulez créer votre propre utilitaire pour programmer le micro-contrôleur, ou si vous voulez réaliser des opérations très spécifiques.&lt;br /&gt;
&lt;br /&gt;
Puisque nous avons placé des boutons poussoir reliant ces signaux à la masse, avec des résistance de &amp;quot;pull-up&amp;quot;, cette opération est très simple : il faut appuyer sur les deux boutons en même temps, puis relacher le bouton reset avant de relacher le bouton ISP.&lt;br /&gt;
Lorsque tout c&#039;est bien passé, la led bicolore doit avoir deux petits points lumineux à peine visibles dans l&#039;obscurité (un rouge et un vert).&lt;br /&gt;
&lt;br /&gt;
=== Dialogue avec le micro-contrôleur ===&lt;br /&gt;
&lt;br /&gt;
La suite se passe sur le PC. Le paquet lpctools contient deux binaires : lpcisp et lpcprog.&lt;br /&gt;
Le premier donne accès aux opérations élémentaires du protocole de programmation, et ne nous sera pas utile. Le second permet de programmer le micro-contrôleur en utilisant une unique commande, bien que d&#039;autres commandes permettent d&#039;effectuer quelques opérations intéressantes.&lt;br /&gt;
&lt;br /&gt;
Nous allons d&#039;ailleurs commencer par une de ces autres opération : demander les identifiants de notre micro-contrôleur avec la commande &amp;quot;id&amp;quot;.&lt;br /&gt;
La syntaxe des commandes lpcprog est simple, il suffit de lui passer un nom de device, que l&#039;on passe comme argument de l&#039;option &amp;quot;-d&amp;quot;, une commande (argument de l&#039;option &amp;quot;-c&amp;quot;), et si besoin le nom du fichier à utiliser.&lt;br /&gt;
Dans l&#039;exemple suivant le module GPIO-Démo est identifié sur le poste de développement comme périphérique &amp;quot;ttyUSB0&amp;quot;, nous utiliserons donc le &#039;&#039;device&#039;&#039; &amp;quot;/dev/ttyUSB0&amp;quot;.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c id&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Part ID is 0x3640c02b&lt;br /&gt;
 UID: 0x2c0cf5f5 - 0x4b32430e - 0x02333834 - 0x4d7c501a&lt;br /&gt;
 Boot code version is 6.1&lt;br /&gt;
La première ligne nous indique que lpcprog a reconnu le micro-contrôleur et qu&#039;il sera donc possible de le programmer. (Si ce n&#039;est pas le cas, vous devrez compléter le fichier de description des micro-contrôleurs).&lt;br /&gt;
Ensuite, lpcprog nous donne les informations propres au micro-contrôleur, à savoir son identifiant unique et la version du &amp;quot;boot code&amp;quot; qui se trouve en rom sur le micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Si vous avez un affichage similaire, tout va bien.&lt;br /&gt;
Sinon, vérifiez la connexion et que le micro-contrôleur est bien en mode ISP.&lt;br /&gt;
&lt;br /&gt;
La programmation se fait ensuite très simplement avec la commande &amp;quot;flash&amp;quot;, en ajoutant le nom du fichier binaire à envoyer.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c flash mod_gpio.bin&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Flash now all blank.&lt;br /&gt;
 Checksum check OK&lt;br /&gt;
 Flash size : 32768, trying to flash 1 blocks of 1024 bytes : 1024&lt;br /&gt;
 Writing started, 1 blocks of 1024 bytes ...&lt;br /&gt;
lpcprog se charge d&#039;effacer la flash, de générer la somme de contrôle de l&#039;entête et de la placer au bon endroit dans le binaire, et d&#039;envoyer le tout au micro-contrôleur pour mise en flash.&lt;br /&gt;
&lt;br /&gt;
Pour tester, il suffit d&#039;appuyer sur le bouton Reset, et de constater qu&#039;il ne se passe rien, ce qui n&#039;est pas ce que nous attendions.&lt;br /&gt;
&lt;br /&gt;
Il y a plusieurs problèmes.&lt;br /&gt;
&lt;br /&gt;
=== Votre code s&#039;il vous plait ! ===&lt;br /&gt;
&lt;br /&gt;
Le premier vient de la génération de la somme de contrôle, ou plutôt de sa position dans notre binaire.&lt;br /&gt;
Tous les LPC de NXP utilisent (à ce jour de ce que j&#039;ai pu voir) le même mécanisme pour déterminer si la flash contient une image valide avant d&#039;essayer d&#039;exécuter son contenu : la vérification du checksum des 8 premiers vecteurs d&#039;interruption, qui doit être nulle.&lt;br /&gt;
&lt;br /&gt;
Pour que ceci soit possible, conformément à la documentation technique des micro-contrôleurs, lpcprog calcule le complément à 2 des 7 premiers vecteurs, et le place dans le huitième.&lt;br /&gt;
&lt;br /&gt;
Sauf que notre tableau ne fait pour l&#039;instant que 5 &amp;quot;cases&amp;quot; et que la huitième case contenait en fait notre code exécutable, qui a été écrasé.&lt;br /&gt;
&lt;br /&gt;
La première modification est donc de remplir au moins 8 cases de ce tableau, au pire avec des valeurs nulles, sinon, avec des valeurs correspondant à ce qui est attendu dans la documentation : les adresses des routines de gestion, ou au moins celle de notre routine &amp;quot;de remplacement&amp;quot; (Dummy_Handler()) lorsque la documentation indique que l&#039;emplacement est utilisé (table 363 et figure 68 pour les exceptions, et table 4 pour les interruption).&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    0, /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
    NMI_Handler,&lt;br /&gt;
    HardFault_Handler,&lt;br /&gt;
    0,&lt;br /&gt;
    0, /* 5 */&lt;br /&gt;
    0,&lt;br /&gt;
    /* Entry 7 (8th entry) must contain the 2’s complement of the check-sum&lt;br /&gt;
       of table entries 0 through 6. This causes the checksum of the first 8&lt;br /&gt;
       table entries to be 0 */&lt;br /&gt;
    (void *)0xDEADBEEF, /* Actually, this is done using an external tool. */&lt;br /&gt;
    0,&lt;br /&gt;
    /* [.....] voir le code du module GPIO-Demo pour la suite */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Cependant ceci n&#039;est pas suffisant (vous pouvez désormais le tester très simplement, je vous laisse faire).&lt;br /&gt;
&lt;br /&gt;
=== Un peu de place pour la pile ===&lt;br /&gt;
&lt;br /&gt;
Le dernier point un petit peu particulier est encore sur cette fameuse table des vecteurs, et concerne la première entrée.&lt;br /&gt;
Si vous regardez attentivement la figure 68, le vecteur &amp;quot;Reset&amp;quot; n&#039;est que la deuxième entrée de la table.&lt;br /&gt;
La première est la valeur initiale du pointeur de la pile (Stack pointer), qui correspond en fait à son sommet puisque cette pile est remplie en faisant décroître les adresses (cette information se trouve dans le chapitre 25, mais cette fois je vous laisse chercher un petit peu).&lt;br /&gt;
&lt;br /&gt;
Nous avons initialisé cette valeur à 0, ce qui forcément pose un soucis.&lt;br /&gt;
&lt;br /&gt;
Pour obtenir la bonne valeur, nous pourrions coder en dur l&#039;adresse du haut de notre sram, mais ce n&#039;est pas propre.&lt;br /&gt;
Pour que tout soit fait correctement et automatiquement, nous allons modifier le script de l&#039;édition de liens, et demander à &#039;&#039;&#039;ld&#039;&#039;&#039; de remplir cette adresse à notre place, en fonction de l&#039;adresse de la sram et de sa taille.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc créer des variables dans notre script, juste après la définition de la mémoire disponible, et chose très importante, ces variables seront des variables externes utilisables dans notre code C !&lt;br /&gt;
: _sram_size = LENGTH(sram);&lt;br /&gt;
: _sram_base = ORIGIN(sram);&lt;br /&gt;
: _end_stack = (_sram_base + _sram_size);&lt;br /&gt;
Nous appelons le bas de la pile (la &amp;quot;fin&amp;quot; de la pile) &#039;&#039;&#039;_end_stack&#039;&#039;&#039;, et plaçons cette fin de pile tout en haut de la mémoire vive.&lt;br /&gt;
&lt;br /&gt;
Et pour l&#039;utilisation dans notre code C, tout simplement :&lt;br /&gt;
 extern unsigned int _end_stack;&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    &amp;amp;_end_stack, /* Initial SP value */ /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Si vous compilez votre code avec ces modifications, vous obtenez enfin un binaire qui allume la Led !&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; : Avec certaines versions de GCC la section data est créée et notre script d&#039;édition de lien demande au compilateur de la placer au début de la RAM, ce qui créé un binaire de 256Mo. Il faut alors modifier le script d&#039;édition de lien pour lui indiquer de placer les données en flash (tout en conservant les adresses en RAM). Pour ce faire, il faut ajouter &amp;quot;AT &amp;gt;flash&amp;quot; derrière le &amp;quot;&amp;gt;sram&amp;quot; après la section data.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Nous avons enfin notre &amp;quot;Hello World !&amp;quot; version électronique, mais la route est encore longue.&lt;br /&gt;
&lt;br /&gt;
Vous pourrez voir dans le prochain article que cette première étape n&#039;était qu&#039;une étape, et qu&#039;il reste encore plusieurs étapes importantes avant de pouvoir vraiment commencer à écrire du code &amp;quot;fonctionnel&amp;quot;, comme la gestion du &amp;quot;watchdog&amp;quot;, la configuration de l&#039;horloge interne, l&#039;initialisation de la mémoire, et l&#039;écriture des drivers pour chaque bloc fonctionnel (liaison série, I2C, SPI, ADC, ....).&lt;br /&gt;
&lt;br /&gt;
Rendez-vous donc pour le second article dédié à la programmation de notre micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Merci pour votre lecture attentive !&lt;br /&gt;
&lt;br /&gt;
== Les fichiers créés ==&lt;br /&gt;
Vous trouverez sur notre serveur le [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/Makefile Makefile], le fichier C [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/main.c main.c], et le script de lien [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/lpc_link_lpc1224.ld lpc_link_lpc1224.ld]&lt;br /&gt;
&lt;br /&gt;
== Liens - Bibliographie ==&lt;br /&gt;
* [1] https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Option-Summary.html&lt;br /&gt;
* [2] https://sourceware.org/binutils/docs/binutils/objdump.html&lt;br /&gt;
* [3] https://sourceware.org/binutils/docs/binutils/readelf.html&lt;br /&gt;
* [4] Page du module et Manuel utilisateur : http://www.techno-innov.fr/technique-module-gpio-demo/ - http://techdata.techno-innov.fr/Modules/GPIO_Demo/System_Reference_Manual_Module_GPIO_Demo_v03.pdf&lt;br /&gt;
* [5] Dépôt GIT lpctools : http://git.techno-innov.fr/?p=lpctools&lt;br /&gt;
* [6] Lien vers d&#039;autres outils pour programmer les LPC :&lt;br /&gt;
** mxli : http://www.windscooting.com/softy/mxli.html&lt;br /&gt;
** lpc21isp : http://sourceforge.net/projects/lpc21isp/&lt;br /&gt;
** nxpprog : http://sourceforge.net/projects/nxpprog/&lt;br /&gt;
** GLPC (GUI pour lpc21isp) : http://sourceforge.net/projects/glpc/&lt;br /&gt;
* [7] Manuel utilisateur du LPC1224 : http://www.nxp.com/documents/user_manual/UM10441.pdf&lt;br /&gt;
* [8] http://fr.wikipedia.org/wiki/Segment_BSS&lt;br /&gt;
* [9] http://en.wikipedia.org/wiki/Bitwise_operation&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=110</id>
		<title>Articles/Nathael/Domotab et elec Libre partie5</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=110"/>
		<updated>2020-09-02T21:28:42Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Électronique et domotique libre - partie 5 : Programmation, Premiers signes de vie}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; margin-right: 2.5em;&amp;quot;&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DomoTab.png|200px|right]]&lt;br /&gt;
Programmation du module !&lt;br /&gt;
&lt;br /&gt;
Nous avons vu dans le quatrième article comment fabriquer le module GPIO-Démo (ou toute version modifiée), nous allons désormais nous atteler à lui donner vie.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1&#039;&#039;&#039; : La programmation sera faite en C, bien que d&#039;autres langages puissent être utilisés, à la seule condition qu&#039;il existe un compilateur qui puisse générer du code binaire pour ARM à partir de ce langage.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2&#039;&#039;&#039; : Les tailles indiquées dans cet article dépendent de la version de GCC utilisée, et il est presque certain que vous obtiendrez des tailles différentes, comme par exemple une taille de 256Mo, un cas que j&#039;ai eu fréquement en TP quand le compilateur créé la section data pour le bloc de données placé en RAM, à l&#039;adresse 0x10000000, soit 256Mo.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;par Nathael Pajani&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:right&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
Paru dans le [http://boutique.ed-diamond.com/home/851-open-silicium-14.html numéro 14] du magazine Open Silicium.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Les documentations techniques ==&lt;br /&gt;
&lt;br /&gt;
La première étape lorsqu&#039;on veut écrire du code pour un système embarqué qui utilise un micro-contrôleur, c&#039;est d&#039;en trouver la documentation technique.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès aux documentations techniques est à mon avis un des critères principaux dans le choix des composants pour un projet, aussi bien pour les concepteurs que pour les utilisateurs.&lt;br /&gt;
&lt;br /&gt;
Si vous avez réalisé la conception du circuit, vous aurez normalement déjà eu besoin de ces documentations, dans le cas contraire, c&#039;est le moment de les récupérer.&lt;br /&gt;
Pour le module GPIO-Démo, il y a plusieurs documentations techniques nécessaires pour utiliser la totalité des fonctionnalités du module.&lt;br /&gt;
La première et la plus importante est celle du micro-contrôleur [7], mais vous aurez aussi besoin de celle du module, disponible sur le site de Techno-Innov [4], et de celles de l&#039;EEPROM I2C, et du capteur de température I2C.&lt;br /&gt;
&lt;br /&gt;
Encart : Pour ce qui est du bridge USB-UART, la documentation n&#039;est pas nécessaire pour la programmation du micro-contrôleur et du module, mais elle le devient si vous voulez modifier la façon dont le composant s&#039;identifie lorsque vous le connectez, par exemple pour pouvoir lui donner un nom spécifique ou simplifier l&#039;identification. Cela ne sera cependant pas le sujet de cet article.&lt;br /&gt;
&lt;br /&gt;
Pour récupérer les documentations techniques, vous avez le choix entre le site du fabriquant et celui du distributeur chez qui vous avec acheté les composants. Pour la majorité des composants j&#039;utilise le site du distributeur (possible uniquement si il fourni les bonnes documentations), mais pour les micro-contrôleurs je consulte le site du fabriquant car il fourni aussi les &amp;quot;errata&amp;quot; (notes d&#039;informations contenant les corrections sur la documentation) et le plus souvent des notes d&#039;application qui indiquent comment utiliser le composant pour telle ou telle application (avec parfois des exemples de code).&lt;br /&gt;
&lt;br /&gt;
== Outils de programmation ==&lt;br /&gt;
&lt;br /&gt;
La deuxième étape ne concerne toujours pas le code que vous voulez écrire.&lt;br /&gt;
&lt;br /&gt;
En effet, pour écrire du code vous n&#039;avez pas besoin de la &amp;quot;cible&amp;quot; (target en anglais) qui est le matériel sur lequel vous allez exécuter la version compilée du code, mais uniquement d&#039;un poste de développement, couramment appelé hôte (host en anglais).&lt;br /&gt;
&lt;br /&gt;
Cependant, la cible en question n&#039;a que faire des fichiers sources qui se trouvent sur votre poste de développement, et il vous faudra un certain nombre d&#039;outils pour passer des fichiers source (quelque soit le langage) au code exécutable par votre carte électronique.&lt;br /&gt;
&lt;br /&gt;
C&#039;est aussi un point très important à mon sens dans le choix d&#039;un système embarqué ou d&#039;un micro-contrôleur : quels sont les outils dont j&#039;aurais besoin pour passer de mon code source à un système fonctionnant avec ?&lt;br /&gt;
&lt;br /&gt;
Dans le cas des micro-contrôleurs de la gamme LPC de NXP il existe de nombreuses solutions pour passer de l&#039;un à l&#039;autre, mais ce qui est intéressant à mon sens c&#039;est qu&#039;il est possible de le faire avec un minimum de matériel et de logiciel : une liaison série &amp;quot;TTL 3.3V&amp;quot;, une chaîne de compilation croisée et un utilitaire pour &amp;quot;uploader&amp;quot; le code binaire.&lt;br /&gt;
&lt;br /&gt;
=== Matériel : un port USB (et le PC qui va avec) ===&lt;br /&gt;
&lt;br /&gt;
[[Image:14-Module sur USB.png|300px|right]]&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la liaison série &amp;quot;TTL 3.3V&amp;quot;, il existe plein d&#039;adaptateurs USB-UART fonctionnant en 3.3V, et pour le cas du module GPIO-Démo cet adaptateur est intégré sur le module, un port USB suffit donc.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès à cette liaison série se fera via un fichier spécial dont le nom sera devrait ressembler à &amp;quot;/dev/ttyUSB0&amp;quot;, le &amp;quot;USB0&amp;quot; pouvant différer selon votre système (&amp;quot;USB1&amp;quot;, USB2&amp;quot;, ... ou même &amp;quot;ACM0&amp;quot; avec d&#039;autres adaptateurs).&lt;br /&gt;
&lt;br /&gt;
=== Compilation : GNU ===&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la chaîne de compilation croisée, les micro-contrôleurs LPC de NXP utilisent des cœurs ARM Cortex-M*, très bien supportés par gcc, bien connu de tous les lecteurs de ce magazine (du moins je le pense), et parfaitement adapté à la cross-compilation.&lt;br /&gt;
&lt;br /&gt;
Dit comme ça, c&#039;est simple ... mais en fait, pas tant que ça.&lt;br /&gt;
Cette problématique pourrait faire l&#039;objet d&#039;un (petit ?) article, je ne l&#039;inclurai donc pas ici, je vous donne juste quelques pistes et suppose que vous saurez trouver les informations sur le net. De mon côté je dois les intégrer à la documentation technique du module GPIO-Démo, mais ce n&#039;est pas encore fait à l&#039;heure où j&#039;écris ces lignes :( [4].&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;avez pas déjà une chaîne de cross-compilation installée pour ARM vous avez globalement trois solutions : Debian/EmDebian (celle que j&#039;utilise), Launchpad, et Crosstools-ng.&lt;br /&gt;
&lt;br /&gt;
Le projet EmDebian fournit des paquets debian pour différentes chaînes de cross-compilation (ARM parmi tant d&#039;autres), qui sont entrain d&#039;être intégrées à Debian. Cela devrait simplifier les problèmes de dépôts et de dépendances dont souffrait les dépôts EmDebian, même si seule la version &amp;quot;arm-none-eabi&amp;quot; (qui nous suffit, nous n&#039;avons pas besoin de libC) est actuellement intégrée dans SID sans problèmes de dépendances (j&#039;ai bien dit &amp;quot;devrait&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Le site de Launchpad fourni aussi des versions binaires de la chaîne de cross-compilation GCC ARM.&lt;br /&gt;
&lt;br /&gt;
La solution CrossTools-ng : recompilation de sa propre chaîne de compilation croisée : la solution du dernier recours, si votre distribution ne fournit pas de solution packagée et que les versions binaires non signées ne vous conviennent pas.&lt;br /&gt;
&lt;br /&gt;
=== Programmation : lpctools (ou autre) ===&lt;br /&gt;
&lt;br /&gt;
Enfin, pour ce qui est de l&#039;utilitaire permettant de charger (uploader) le code binaire sur le micro-contrôleur (flasher le micro-contrôleur), je n&#039;avais pas trouvé d&#039;outil libre permettant de réaliser cette étape au moment où j&#039;ai étudié la possibilité d&#039;utiliser les micro-contrôleurs de NXP, mais le protocole série permettant de réaliser cette opération était documenté dans la documentation technique des micro-contrôleurs, il ne devait donc pas y avoir de problème de ce côté là.&lt;br /&gt;
&lt;br /&gt;
La seule solution &amp;quot;gratuite&amp;quot; que j&#039;avais trouvé à l&#039;époque ne fonctionnait que sur un seul système (pas le miens), ne fournissait pas ses sources, et interdisait une utilisation commerciale sans payer une licence, hors je voulais justement en faire une utilisation commerciale.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai donc pris quelques heures de mon temps pour coder un utilitaire permettant de programmer les micro-contrôleurs LPC, et placé le tout sous licence GPL v3 [5].&lt;br /&gt;
Le tout est désormais disponible sur le site de Techno-Innov, et est intégré depuis peu à la distribution Debian GNU/Linux (Sid et Jessie à l&#039;heure de l&#039;écriture de ces lignes).&lt;br /&gt;
&lt;br /&gt;
J&#039;ai entre-temps découvert d&#039;autres projets permettant de programmer des micro-contrôleurs LPC, mais je ne les ai pas testés (nxpprog - licence MIT, mxli - GPLv3, pyLPCTools - GPLv2) et constaté qu&#039;un autre paquet Debian fournit les outils permetant de programmer les micro-contrôleurs LPC de NXP : lpc21isp (qui dispose d&#039;ailleurs d&#039;une interface graphique : GLPC, qui elle n&#039;est pas dans les dépôts). Voir liens [6] en fin d&#039;article.&lt;br /&gt;
&lt;br /&gt;
== Makefile - particularités pour la compilation croisée ==&lt;br /&gt;
&lt;br /&gt;
Une dernière petite étape avant d&#039;écrire notre code, bien que l&#039;on se rapproche de la programmation, puisqu&#039;il s&#039;agit d&#039;un élément essentiel de tout projet : la création du Makefile.&lt;br /&gt;
&lt;br /&gt;
Dans le cas de la compilation pour une cible comme le module GPIO-Démo le Makefile doit inclure quelques éléments supplémentaires que l&#039;on ne retrouve habituellement pas dans un Makefile classique.&lt;br /&gt;
&lt;br /&gt;
Le premier élément concerne la définition du compilateur à utiliser. Nous utiliserons la variable &amp;quot;CROSS_COMPILE&amp;quot; à laquelle nous affecterons une valeur par défaut correspondant au préfixe du compilateur. Si vous voulez utiliser un compilateur correctement installé sur le système, il suffit d&#039;utiliser le préfixe, sinon, il faudra ajouter devant la totalité du chemin donnant accès au compilateur.&lt;br /&gt;
&lt;br /&gt;
Par exemple pour le compilateur EmDebian :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
ou avec un chemin complet pour un autre compilateur :&lt;br /&gt;
: CROSS_COMPILE ?= /usr/local/mon/compilateur/bin/arm-none-eabi-&lt;br /&gt;
&lt;br /&gt;
Le &amp;quot;?=&amp;quot; permet de ne modifier la variable que si elle n&#039;existe pas, notamment si elle n&#039;est pas déjà présente dans la ligne de commande.&lt;br /&gt;
&lt;br /&gt;
Cette variable est ensuite utilisée pour modifier la variable &amp;quot;CC&amp;quot; utilisée par &amp;quot;make&amp;quot; pour compiler les fichiers de code source C. Si vous utilisez un autre langage, modifiez la variable correspondante.&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
Il est aussi possible d&#039;en profiter pour spécifier une version du compilateur installé :&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc-4.7&lt;br /&gt;
Nous allons en profiter pour définir la variable &amp;quot;LD&amp;quot; qui correspond à l&#039;éditeur de liens (linker en anglais) :&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
&lt;br /&gt;
Il nous faut ensuite définir la cible pour laquelle nous voulons compiler. Dans notre cas il s&#039;agit d&#039;un cœur ARM Cortex-M0, qui utilise le jeu d&#039;instructions &amp;quot;thumb&amp;quot; (instructions sur 16bits permettant d&#039;obtenir un code plus compact), nous allons donc utiliser les options -mcpu et -mthumb de gcc pour lui indiquer notre besoin :&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: CFLAGS = -Wall -mthumb -mcpu=$(CPU)&lt;br /&gt;
&lt;br /&gt;
En plus de cela, nous allons demander au compilateur de ne pas reconnaître les fonctions pour lesquelles il a une définition interne (builtin) tout simplement parce que la majorité de ces fonctions dépendent d&#039;un environnement très différent de celui de notre micro-contrôleur, soit par la présence d&#039;une bibliothèque C, d&#039;un système d&#039;exploitation respectant la norme POSIX, ou d&#039;une unité de calcul flottant.&lt;br /&gt;
Rien de tout ceci n&#039;est vrai dans notre cas, et il est donc préférable que le compilateur nous informe si nous tentons d&#039;utiliser ces fonctions sans l&#039;avoir explicitement demandé en utilisant le préfixe &amp;quot;__builtin__&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous demanderons aussi au compilateur de bien placer les données et les fonctions dans leurs sections respectives. Malgré ce que dit la documentation de GCC, cela permet (au moins dans notre cas) de produire un binaire plus petit. Cela se fait à l&#039;aide des directives d&#039;optimisation &amp;quot;-ffunction-sections&amp;quot; et &amp;quot;-fdata-sections&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous ajouterons ces directives dans une variable dédiée :&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Nous obtenons donc les lignes suivantes à ajouter à votre Makefile :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
: CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
&lt;br /&gt;
Notre Makefile ressemblerait alors à ceci :&lt;br /&gt;
 NAME = mod_gpio&lt;br /&gt;
 CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
 CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
 LD = $(CROSS_COMPILE)ld&lt;br /&gt;
 CPU = cortex-m0&lt;br /&gt;
 FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
 CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
 &lt;br /&gt;
 .PHONY: all&lt;br /&gt;
 all: $(NAME)&lt;br /&gt;
 &lt;br /&gt;
 SRC = $(wildcard *.c)&lt;br /&gt;
 OBJS = $(SRC:.c=.o)&lt;br /&gt;
 &lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ -o $@&lt;br /&gt;
Ce Makefile est encore incomplet et ne permet pas d&#039;obtenir le binaire pour notre micro-contrôleur, mais nous ajouterons les parties manquantes plus tard.&lt;br /&gt;
&lt;br /&gt;
En attendant, ce Makefile nous permettra de compiler le code que nous allons écrire, passons donc aux parties intéressantes, et le reste du Makefile sera bien plus simple à comprendre.&lt;br /&gt;
&lt;br /&gt;
== Commençons simple ==&lt;br /&gt;
&lt;br /&gt;
Pour ne pas trop compliquer les choses dès le début, nous allons tenter de faire clignoter la led bicolore présente sur le module GPIO-Démo.&lt;br /&gt;
&lt;br /&gt;
Notre squelette de code ressemblera à s&#039;y méprendre à ce que l&#039;on pourrait avoir pour un programme plus commun :&lt;br /&gt;
 /*&lt;br /&gt;
  * Notre exemple simple pour Open Silicium&lt;br /&gt;
  */&lt;br /&gt;
 void system_init(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* System init ? */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* Micro-controller init */&lt;br /&gt;
 	system_init();&lt;br /&gt;
 	&lt;br /&gt;
 	while (1) {&lt;br /&gt;
 		/* Change the led state */&lt;br /&gt;
 		/* Wait some time */&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 }&lt;br /&gt;
Si vous compilez ce petit morceau de code avec notre Makefile, vous obtiendrez un binaire qui globalement ne fait rien, mais a déjà une taille de 5.7 Ko.&lt;br /&gt;
C&#039;est gros pour ne rien faire, d&#039;autant que la mémoire Flash de notre micro-contrôleur ne fait que 32 Ko.&lt;br /&gt;
&lt;br /&gt;
Si on regarde plus loin, par exemple avec l&#039;utilitaire &#039;&#039;file&#039;&#039;, on obtient quelques informations supplémentaires :&lt;br /&gt;
 $ file mod_gpio&lt;br /&gt;
 mod_gpio: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), [....], not stripped&lt;br /&gt;
&lt;br /&gt;
Arghhh, notre binaire est un exécutable dynamique au format ELF, qui utilise des bibliothèques partagées !&lt;br /&gt;
&lt;br /&gt;
Nous l&#039;avons déjà évoqué, notre micro-contrôleur n&#039;a pas de libC ni de système d&#039;exploitation, notre binaire ne peut donc pas être dynamique (lié dynamiquement à des bibliothèques) !&lt;br /&gt;
Il nous faut donc faire l&#039;édition de lien en &amp;quot;static&amp;quot;, en apportant quelques modification à notre Makefile. Nous allons introduire une variable &amp;quot;LDFLAGS&amp;quot;, que l&#039;on ajoutera à la règle de compilation utilisée pour l&#039;édition de liens.&lt;br /&gt;
 LDFLAGS = -static&lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ $(LDFLAGS) -o $@&lt;br /&gt;
Recompilons notre projet ... 608 Ko !!! Re-Argh !&lt;br /&gt;
&lt;br /&gt;
Visiblement quelqu&#039;un ajoute du code dont nous n&#039;avons pas besoin. Il faut du moins l&#039;espérer, sinon il ne sera jamais possible de faire rentrer un programme dans la flash de notre micro-contrôleur, qui fait toujours 32Ko.&lt;br /&gt;
&lt;br /&gt;
L&#039;option &amp;quot;static&amp;quot; demande à l&#039;éditeur de lien de créer un binaire statique, mais résultat il nous ajoute tout ce qui est utile de la libC pour un exécutable ... pour un système Linux.&lt;br /&gt;
D&#039;ailleurs, &#039;&#039;file&#039;&#039; nous dit bien que notre exécutable est au format ELF.&lt;br /&gt;
&lt;br /&gt;
Pour commencer nous allons demander à l&#039;éditeur de liens (ld) de ne pas inclure les éléments de démarrage dans notre binaire, car ils sont inutiles sur notre micro-contrôleur. Pour cela nous ajoutons l&#039;option &amp;quot;-nostartfiles&amp;quot; à nos directives pour l&#039;édition de liens.&lt;br /&gt;
&lt;br /&gt;
Et hop, une recompilation plus tard, notre binaire ne fait plus que 1 Ko :)&lt;br /&gt;
Mais pour &#039;&#039;file&#039;&#039;, ce binaire est toujours au format ELF, et gcc nous informe qu&#039;il n&#039;a pas trouvé de symbole d&#039;entrée &amp;quot;_start&amp;quot; et qu&#039;il utilise une adresse par défaut (nous l&#039;avons cherché, cela fait partie de ce que nous avons demandé à l&#039;éditeur de liens en ajoutant l&#039;option &amp;quot;-nostartfiles&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
En effet, le &amp;quot;main&amp;quot; de nos programmes en C n&#039;est que le point de départ de l&#039;exécution de notre code, mais pas celui du programme. Il est précédé par un certain nombre de routines (fonctions) d&#039;initialisation, dont le point d&#039;entrée est la routine &amp;quot;_start&amp;quot;, qui appellera le main &amp;quot;classique&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Mais notre but n&#039;est pas de créer un exécutable pour un système Linux, nous devons créer un binaire pour notre micro-contrôleur. Il est désormais temps de nous plonger dans la documentation du micro-contrôleur pour comprendre comment il démarre, pour pouvoir adapter notre code au démarrage du micro-contrôleur et fournir l&#039;équivalent de cette routine &amp;quot;_start&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bootstrap == &lt;br /&gt;
&lt;br /&gt;
=== Table des vecteurs d&#039;interruption ===&lt;br /&gt;
&lt;br /&gt;
Pour avoir des informations sur le démarrage du micro-contrôleur LPC1224 dans sa documentation technique [7] il y a deux chapitres intéressants.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons nous référer au chapitre 4 (LPC122x System control) qui inclut une section sur le reset du micro-contrôleur (4.6 : Reset), dans laquelle on apprend qu&#039;une fois que la condition de reset disparait et que les procédures internes se sont exécutées, le processeur commence l&#039;exécution à l&#039;adresse contenue dans le vecteur &amp;quot;Reset&amp;quot; du &amp;quot;boot block&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous avons ainsi quelques informations, mais qu&#039;est-ce que le vecteur &amp;quot;Reset&amp;quot; et le &amp;quot;boot block&amp;quot; ? Cela nous mène au deuxième chapitre intéressant, le chapitre 25 sur le cœur ARM Cortex-M0. On y trouve une section sur le processeur (25.3 : Processor) avec une sous section concernant les exeptions (25.3.3 : Exception model). &lt;br /&gt;
&lt;br /&gt;
Dans les informations sur les exceptions (25.3.3.2), et plus particulièrement l&#039;exception &amp;quot;Reset&amp;quot;, il est indiqué qu&#039;après un &amp;quot;Reset&amp;quot; l&#039;exécution reprend à l&#039;adresse indiquée dans le vecteur &amp;quot;Reset&amp;quot; dans la table des vecteurs d&#039;interruption.&lt;br /&gt;
&lt;br /&gt;
Bien, cela confirme ce qui se trouvait dans le chapitre 4. Mais cette fois, nous avons une sous-section &amp;quot;25.3.3.4 Vector table&amp;quot;, qui décrit cette fameuse table des vecteurs d&#039;exception, précisant qu&#039;elle contient l&#039;addresse de toutes les routines de gestion des exceptions (les fameux &amp;quot;vecteurs&amp;quot; d&#039;exception, dont le vecteur &amp;quot;Reset&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Remarquez au passage que les interruptions sont gérées de la même façon, l&#039;addresse d&#039;entrée des routines de gestion des interruptions se trouve dans cette même table.&lt;br /&gt;
&lt;br /&gt;
Et en dessous de cette table, nous avons une autre information très intéressante : &amp;quot;The vector table is fixed at address 0x00000000&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Si l&#039;on se réfère à la table 65 de la section &amp;quot;25.3.2 Memory model&amp;quot;, et à la figure 2 de la section &amp;quot;2.3 Memory allocation&amp;quot;, on découvre que cette adresse est en fait le début de la mémoire flash du micro-contrôleur, qui devra contenir notre code binaire.&lt;br /&gt;
&lt;br /&gt;
Reste à créer cette table, et à la placer au bon endroit dans le code binaire compilé...&lt;br /&gt;
&lt;br /&gt;
=== Les &amp;quot;handlers&amp;quot; et les &amp;quot;dummy handlers&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
Nous allons commencer par la partie code.&lt;br /&gt;
Ce code peut être placé dans le même fichier que celui ou ce trouve notre fonction main, ou dans un autre fichier, cela n&#039;a pas d&#039;importance. Si vous vous référez au code du module GPIO-Démo disponible dans les dépôts git de Techno-Innov, vous trouverez ce code dans le fichier &amp;quot;core/bootstrap.c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Vecteurs_interruption.png|350px|right]]&lt;br /&gt;
&lt;br /&gt;
 /* Cortex M0 core interrupt handlers */&lt;br /&gt;
 void Reset_Handler(void);&lt;br /&gt;
 void NMI_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 void HardFault_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void);&lt;br /&gt;
 &lt;br /&gt;
 void *vector_table[] = {&lt;br /&gt;
 	0,&lt;br /&gt;
 	Reset_Handler,&lt;br /&gt;
 	NMI_Handler,&lt;br /&gt;
 	HardFault_Handler,&lt;br /&gt;
 	0,&lt;br /&gt;
 	/* [......] */&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void) {&lt;br /&gt;
     while (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Voici un petit morceau de code relativement court qui définit notre table de vecteur ainsi que les routines de gestion correspondantes.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, faisons un petit point sur certains éléments : les attributs utilisés pour la déclaration de deux de nos routines de gestion des exceptions : &amp;quot;__attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ces attributs permettent de définir un alias &amp;quot;faible&amp;quot; pour une fonction, ce qui veut dire que si le compilateur ne trouve pas de définition pour cette fonction, il pourra utiliser son alias, que nous avons défini plus bas. Au contraire, si dans un autre fichier (ou celui-ci) vous définissez l&#039;une de ces fonctions, c&#039;est votre définition qui sera utilisée.&lt;br /&gt;
&lt;br /&gt;
Note : je n&#039;ai pas mis la totalité de la table des vecteurs, cela n&#039;a pas d&#039;intérêt pour les explications, et notre programme fonctionnera sans, mais il faudrait la compléter pour un vrai programme, en faisant attention à l&#039;ordre, à partir des informations de la figure 68 déjà évoquée, et de la table 4 du chapitre 3 concernant le gestionnaire d&#039;interruptions (vous noterez la typo, il s&#039;agit des numéros d&#039;IRQ et non pas des numéros des vecteurs d&#039;exception).&lt;br /&gt;
&lt;br /&gt;
=== Appeler notre main() ===&lt;br /&gt;
Ce petit bout de code compile donc, puisque tout est défini, mais nous avons toujours l&#039;avertissement concernant le symbole d&#039;entrée &amp;quot;_start&amp;quot; qui n&#039;a pas été trouvé. Nous ne sommes pas plus avancé.&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, nous avons déjà indiqué que le point d&#039;entrée de notre code est la fonction main() (qui pourrait avoir n&#039;importe quel nom), mais pour notre micro-controlleur la fonction d&#039;entrée du programme est la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
La solution pour faire le lien est toute simple : il suffit d&#039;appeler la fonction main() depuis la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
 int main(void);&lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 	main();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Tisser des liens, c&#039;est important ===&lt;br /&gt;
Cela ne résout cependant aucun de nos problèmes, nous allons donc devoir donner plus d&#039;indications à l&#039;éditeur de liens, en créant un script pour l&#039;édition de lien (lpc_link_lpc1224.ld). Nous donnerons le nom de ce script à l&#039;éditeur de liens en utilisant l&#039;otion &amp;quot;-T&#039;&#039;lpc_link_lpc1224.ld&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ce script d&#039;édition de lien (&amp;quot;linker script&amp;quot; en anglais) est en fait un fichier qui décrit la mémoire de notre micro-contrôleur, ainsi que l&#039;organisation que devra respecter notre binaire.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc commencer, toujours à partir des mêmes informations en provenance de la documentation technique, par définir quelle est la mémoire disponible, aussi bien la mémoire &amp;quot;vive&amp;quot; (SRAM) que la mémoire &amp;quot;morte&amp;quot; (FLASH).&lt;br /&gt;
&lt;br /&gt;
 MEMORY&lt;br /&gt;
 {&lt;br /&gt;
 	sram (rwx) : ORIGIN = 0x10000000, LENGTH = 4k&lt;br /&gt;
 	flash (rx) : ORIGIN = 0x00000000, LENGTH = 32k&lt;br /&gt;
 }&lt;br /&gt;
Nous définissons ainsi l&#039;adresse et la taille (et les droits d&#039;accès) de la sram et de la flash, qui deviennent deux blocs de mémoire disponibles pour l&#039;éditeur de liens, qui pourra donc y placer du code et des données.&lt;br /&gt;
&lt;br /&gt;
Il nous faut maintenant expliquer à l&#039;éditeur de liens comment organiser le code et les données dans ces blocs de mémoire, et tout particulièrement notre tableau de vecteurs d&#039;interruptions&lt;br /&gt;
&lt;br /&gt;
Le code d&#039;un programme est composé de &amp;quot;sections&amp;quot;, dans lesquelles le compilateur place chaque fonction et chaque variable en fonction de différents critères, que l&#039;on peut contrôler soit à partir de directives de compilation, soit d&#039;attributs ajoutés dans notre code C&lt;br /&gt;
&lt;br /&gt;
Nous allons donc modifier notre tableau de vecteurs d&#039;interruptions pour lui ajouter un attribut &amp;quot;section&amp;quot; qui forcera l&#039;éditeur de liens à le placer dans la section que nous avons défini.&lt;br /&gt;
: void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
&lt;br /&gt;
Et en parallèle, nous allons définir dans notre script quelles sont les sections que nous voulons trouver dans notre binaire, et dans quel ordre.&lt;br /&gt;
Commençons simple (si si, je vous assure), nous compliquerons plus tard :&lt;br /&gt;
 SECTIONS {&lt;br /&gt;
 	. = ORIGIN(flash);&lt;br /&gt;
 	.text :&lt;br /&gt;
 	{&lt;br /&gt;
 		KEEP(*(.vectors))&lt;br /&gt;
 		*(.text*)&lt;br /&gt;
 		*(.rodata*)&lt;br /&gt;
 	} &amp;gt;flash&lt;br /&gt;
 	.data :&lt;br /&gt;
 	{&lt;br /&gt;
 		*(.data*)&lt;br /&gt;
 		*(.bss*)&lt;br /&gt;
 	} &amp;gt;sram&lt;br /&gt;
 }&lt;br /&gt;
Pour commencer, nous définissons l&#039;adresse courante (.) comme étant l&#039;origine de du bloc de mémoire &amp;quot;flash&amp;quot; (le bloc de mémoire défini précédemment et auquel nous avons donné ce nom, bien qu&#039;un autre nom aurait pu faire l&#039;affaire).&lt;br /&gt;
Ceci est important pour que l&#039;éditeur de liens puisse définir les adresses des fonctions pour l&#039;exécution de notre code.&lt;br /&gt;
À partir de ce point nous définissons une section &amp;quot;text&amp;quot;, dans laquelle nous allons demander à l&#039;éditeur de lien de mettre plusieurs éléments, à commencer par notre fameuse table de vecteurs, en lui interdisant d&#039;en changer la position !&lt;br /&gt;
Après quoi, nous lui demandons de placer l&#039;ensemble du code, que le compilateur a placé dans des section &amp;quot;.text.*&amp;quot;, puis les données en lecture seule (Read-Only data = rodata), et de placer le tout dans le bloc de mémoire &amp;quot;flash&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
À la suite, nous créons une section &amp;quot;data&amp;quot;, dans laquelle nous lui demandons de placer les données initialisées à des valeurs non nulles (data), puis les données initialement nulles (bss [8]), et de placer cette section en RAM.&lt;br /&gt;
&lt;br /&gt;
Ne reste plus qu&#039;une information à donner à l&#039;éditeur de liens (pour l&#039;instant): le point d&#039;entrée de notre programme.&lt;br /&gt;
Ceci est relativement simple et explicite :&lt;br /&gt;
: ENTRY(Reset_Handler)&lt;br /&gt;
&lt;br /&gt;
Dans notre Makefile la variable LDFLAGS devient :&lt;br /&gt;
: LDFLAGS = -static -nostartfiles -Tlpc_link_lpc1224.ld&lt;br /&gt;
&lt;br /&gt;
Une compilation plus tard, sans avertissements cette fois, nous avons un binaire ... beaucoup trop gros : notre binaire fait maintenant plus de 66 Ko !&lt;br /&gt;
&lt;br /&gt;
Soyons un peu curieux et allons donc voir ce qu&#039;il contient, mais pas à la main, rassurez vous, utilisons un utilitaire fait exprès pour cela : &#039;&#039;objdump&#039;&#039;. attention, il faut bien entendu utiliser la version &amp;quot;ARM&amp;quot; de objdump, donc avec le préfixe &amp;quot;CROSS_COMPILE&amp;quot;, soit dans mon cas &#039;&#039;arm-linux-gnueabi-objdump&#039;&#039;, avec l&#039;option &#039;&#039;--disassemble-all&#039;&#039; (-D) :&lt;br /&gt;
: arm-linux-gnueabi-objdump -D mod_gpio &amp;gt; dump&lt;br /&gt;
Et là, surprise, la version &amp;quot;désassemblée&amp;quot; de notre binaire est plus petite que la version binaire (le fichier &amp;quot;dump&amp;quot; fait 2.2 Ko).&lt;br /&gt;
&lt;br /&gt;
Regardons tout de même son contenu.&lt;br /&gt;
La première ligne nous informe que le format du fichier est &amp;quot;elf32-littlearm&amp;quot; ... pas grand chose à voir avec ce que nous voulions, un &amp;quot;simple&amp;quot; binaire (Notre micro-contrôleur n&#039;a toujours pas appris à lire les exécutables au format ELF). Premier problème.&lt;br /&gt;
&lt;br /&gt;
Quelqu&#039;un est venu glisser une section &amp;quot;.note.gnu.build-id&amp;quot; avant notre section &amp;quot;.text&amp;quot;, que l&#039;éditeur de liens aimerait placer en début de RAM (&amp;quot;10000000 &amp;lt;_sram_base&amp;gt;&amp;quot;), ce qui n&#039;a pas d&#039;intérêt pour nous.&lt;br /&gt;
&lt;br /&gt;
S&#039;en suit tout de même notre section &amp;quot;.text&amp;quot;, qui commence bien par notre table (enfin ! on nous écoute un peu !), suivie de nos quelques maigres fonctions. Notez les adresses des fonctions dans la table des vecteurs, qui sont toutes impaires. Ceci indique que notre processeur exécutera ces fonctions en mode &amp;quot;thumb&amp;quot; qui est bien le mode que nous avions demandé (-mthumb).&lt;br /&gt;
&lt;br /&gt;
Et encore une fois, notre section &amp;quot;.text&amp;quot; n&#039;est pas suivie de nos données, mais d&#039;autres sections que nous n&#039;avions pas demandées !&lt;br /&gt;
Certes, nous n&#039;avons pas de variables, et l&#039;éditeur de lien n&#039;ayant rien à mettre dans notre section &amp;quot;.data&amp;quot;, il ne l&#039;a pas créée, mais au final nous sommes relativement loin de ce que nous voulions.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc demander à l&#039;éditeur de liens de générer un petit peu moins de choses en ajoutant l&#039;option &#039;&#039;-Wl,--build-id=none&#039;&#039; à nos directives de compilation (variable LDFLAGS de notre Makefile), ce qui nous donne un binaire moitié plus petit mais toujours trop gros.&lt;br /&gt;
&lt;br /&gt;
=== Un binaire vraiment binaire ===&lt;br /&gt;
Mais nous ne pouvons pas en demander bien plus à l&#039;éditeur de liens, dont le travail est de créer des exécutables au format ELF.&lt;br /&gt;
Pour créer d&#039;autres types de binaire, nous devrons utiliser l&#039;utilitaire &#039;&#039;objcopy&#039;&#039; (toujours la version ARM, donc en fait &#039;&#039;arm-linux-gnueabi-objcopy&#039;&#039;).&lt;br /&gt;
Le travail de cet utilitaire est de créer des binaires à partir des exécutables ELF, en ne conservant que les sections qui nous intéressent (du moins, c&#039;est l&#039;usage que nous en ferons).&lt;br /&gt;
&lt;br /&gt;
Nous allons demander à cet utilitaire de nous générer une image binaire à partir du résultat de notre compilation en ajoutant dans notre Makefile une cible &amp;quot;$(NAME).bin&amp;quot; qui deviendra notre cible par défaut et dépendra de la génération du fichier au format ELF :&lt;br /&gt;
&lt;br /&gt;
 all: $(NAME).bin&lt;br /&gt;
 &lt;br /&gt;
 $(NAME).bin: $(NAME)&lt;br /&gt;
 	$(CROSS_COMPILE)objcopy -O binary $^ $@&lt;br /&gt;
&lt;br /&gt;
Et notre objectif est enfin atteint, avec un binaire de ... 36 octets !&amp;lt;br /&amp;gt;&lt;br /&gt;
Rappelez vous, je n&#039;ai mis que 5 entrées dans ma table de vecteurs, soit 20 octets, suivis de quelques fonctions vides. Tout va bien.&lt;br /&gt;
&lt;br /&gt;
== Un programme un peu plus utile ==&lt;br /&gt;
&lt;br /&gt;
Nous allons désormais pouvoir nous occuper d&#039;allumer nos Leds, en quelque sorte le &amp;quot;Hello world&amp;quot; de l&#039;électronique.&lt;br /&gt;
&lt;br /&gt;
=== Entrées et sorties ===&lt;br /&gt;
Du point de vue de notre micro-contrôleur, allumer ou éteindre une Led revient à changer l&#039;état de la sortie correspondante.&lt;br /&gt;
&lt;br /&gt;
Les entrées/sorties du microcontrôleur peuvent avoir plusieurs fonctions, mais hormis quelques exceptions elles sont par défaut configurées en entrées/sorties (GPIO (general Purpose Input Output) en anglais) avec la résistance de pull-up interne activée. Pour simplifier, nous laisserons donc cette étape de la configuration de côté pour l&#039;instant, et reviendrons dessus lorsque nous attaquerons la programmation d&#039;interfaces plus complexes.&lt;br /&gt;
&lt;br /&gt;
: Note : Les exceptions sont les GPIO 13, 25 et 26 du port 0 (respectivement Reset, SWDIO et SWDCLK), qui permettent le reset et le debug, ainsi que quatre GPIO sur lesquelles la fonction &amp;quot;0&amp;quot; est réservée : les GPIO 30 et 31 du port 0 et les GPIO 0 et 1 du port 1.&lt;br /&gt;
&lt;br /&gt;
=== Les registres ===&lt;br /&gt;
Pour changer l&#039;état d&#039;une de ces entrées/sorties, il faut commencer par la configurer en sortie, puis définir sont état.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, il est important de comprendre que le processeur de notre micro-contrôleur ne voit que de la mémoire autour de lui. Il n&#039;a pas accès directement aux signaux électriques.&lt;br /&gt;
Pour accéder aux fonctions spéciales comme l&#039;état électrique d&#039;une sortie le processeur doit donc modifier des données dans une zone mémoire spécifique, dédiée à cette sortie, que l&#039;on appelle un registre.&lt;br /&gt;
&lt;br /&gt;
Notre micro-contrôleur dispose d&#039;un grand nombre de registres qui ont tous une taille de 32 bits, même si souvent certains bits ne sont pas utilisés (ils sont alors &amp;quot;réservés&amp;quot;).&lt;br /&gt;
Ces registres particuliers, qui nous donnent accès aux fonctions spéciales du micro-contrôleur, comme la configuration et l&#039;état des entrées sorties, sont accessibles chacun à une adresse fixe dans l&#039;espace d&#039;adressage du micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Nous avons déjà eu besoin d&#039;informations sur cet espace d&#039;adressage lorsque nous avons cherché des informations sur le démarrage du micro-contrôleur, il se trouve représenté sur la figure 2 dans la section &amp;quot;2.3 Memory allocation&amp;quot; du chapitre 2 (LPC122x Memory map).&lt;br /&gt;
&lt;br /&gt;
L&#039;adresse qui nous intéresse dépend du port sur lequel les leds sont connectées.&lt;br /&gt;
La led bicolore étant connectée sur le port 1 ce sont les registres présents à l&#039;adresse 0x50010000 que nous devrons utiliser.&lt;br /&gt;
Cette adresse est aussi rappelée avec la description des registres dans le chapitre 8 (LPC122x General Purpose I/O (GPIO))&lt;br /&gt;
&lt;br /&gt;
À partir de cette adresse se trouvent une série de registres permettant de contrôler les entrées/sorties du port 1. La modification du contenu de la mémoire accessible ainsi modifiera donc le comportement des entrées/sorties correspondantes ou leur état lorsqu&#039;elles sont configurées en sortie.&lt;br /&gt;
&lt;br /&gt;
Très (trop) souvent, pour accéder à ces registres, les programmeurs utilisent des définitions selon le principe suivant:&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 #define PORT1_MASK  (LPC_GPIO_1_BASE + 0x00)&lt;br /&gt;
 #define PORT1_PIN   (LPC_GPIO_1_BASE + 0x04)&lt;br /&gt;
 #define PORT1_OUT   (LPC_GPIO_1_BASE + 0x08)&lt;br /&gt;
 /* [.....] */&lt;br /&gt;
Personnellement je trouve cette façon de faire très inefficace, et peu lisible (voire complètement illisible), et je préfère l&#039;utilisation de structures.&lt;br /&gt;
Cela me semble beaucoup plus lisible, plus adapté pour accéder à de la mémoire qui est structurée, et apporte aussi un très net avantage lorsqu&#039;il existe plusieurs ensembles de registres utilisant la même organisation, par exemple quand il y a plusieurs liaisons séries sur le micro-contrôleur, ou dans le cas qui nous intéresse pour l&#039;instant, plusieurs ports d&#039;entrées/sorties.&lt;br /&gt;
La définition se passe alors ainsi :&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_0_BASE  (LPC_AHB_BASE + 0x00000)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 /* General Purpose Input/Output (GPIO) */&lt;br /&gt;
 struct lpc_gpio&lt;br /&gt;
 {&lt;br /&gt;
    volatile uint32_t mask;       /* 0x00 : Pin mask, affects data, out, set, clear and invert */&lt;br /&gt;
    volatile uint32_t in;         /* 0x04 : Port data Register (R/-) */&lt;br /&gt;
    volatile uint32_t out;        /* 0x08 : Port output Register (R/W) */&lt;br /&gt;
    volatile uint32_t set;        /* 0x0C : Port output set Register (-/W) */&lt;br /&gt;
    volatile uint32_t clear;      /* 0x10 : Port output clear Register (-/W) */&lt;br /&gt;
    volatile uint32_t toggle;     /* 0x14 : Port output invert Register (-/W) */&lt;br /&gt;
    uint32_t reserved[2];&lt;br /&gt;
    volatile uint32_t data_dir;   /* 0x20 : Data direction Register (R/W) */&lt;br /&gt;
    /* [.....] */&lt;br /&gt;
 };&lt;br /&gt;
 #define LPC_GPIO_0      ((struct lpc_gpio *) LPC_GPIO_0_BASE)&lt;br /&gt;
 #define LPC_GPIO_1      ((struct lpc_gpio *) LPC_GPIO_1_BASE)&lt;br /&gt;
À noter, l&#039;utilisation du mot clé &amp;quot;volatile&amp;quot; qui interdira au compilateur d&#039;optimiser les accès à ces registres en gardant des copies intermédiaires, forçant la lecture ou l&#039;écriture immédiate.&lt;br /&gt;
&lt;br /&gt;
Cette notation nous donne aussi l&#039;information de la taille des données présentes à ces adresses, dans ce cas là, des valeurs sur 32 bits.&lt;br /&gt;
&lt;br /&gt;
Pour l&#039;utilisation dans le code, c&#039;est ensuite très simple, il suffit de déclarer un pointeur vers cette structure, puis d&#039;accéder au champ qui nous intéresse :&lt;br /&gt;
 struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
 gpio1-&amp;gt;out = 0;&lt;br /&gt;
&lt;br /&gt;
=== Allumer les leds ===&lt;br /&gt;
&lt;br /&gt;
Reste à déterminer quels sont les champs qui nous intéressent et quelles valeurs nous devons écrire dedans.&lt;br /&gt;
Pour configurer les pins reliées à nos Leds en sortie nous devons modifier le registre &amp;quot;DIR&amp;quot; (appelé &amp;quot;data_dir&amp;quot; dans la structure), et mettre les bits 4 et 5 à &amp;quot;1&amp;quot; puisque chaque bit de ce registre permet de configurer une des pins du port correspondant, le bit 0 pour la pin 0, le bit 1 pour la pin 1, et ainsi de suite (attention, ici les numéros de pins ne sont pas les numéros des pattes du composant).&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc modifier notre main() pour obtenir le code suivant qui réalise cette opération de façon lisible, et positionne la Led verte à l&#039;état &amp;quot;allumée&amp;quot;, sans modifier l&#039;état des autres sorties du port 1 :&lt;br /&gt;
 /* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */&lt;br /&gt;
 #define LED_RED    5&lt;br /&gt;
 #define LED_GREEN  4&lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
    /* Micro-controller init */&lt;br /&gt;
    system_init();&lt;br /&gt;
    /* Configure the Status Led pins */&lt;br /&gt;
    gpio1-&amp;gt;data_dir |= (1 &amp;lt;&amp;lt; LED_GREEN) | (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    /* Turn Green Led ON */&lt;br /&gt;
    gpio1-&amp;gt;set = (1 &amp;lt;&amp;lt; LED_GREEN);&lt;br /&gt;
    gpio1-&amp;gt;clear = (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    while (1) {&lt;br /&gt;
        /* Change the led state */&lt;br /&gt;
        /* Wait some time */&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[Encart : Décalages de bits] :&lt;br /&gt;
: La notation &amp;quot;&amp;lt;&amp;lt;&amp;quot; correspond à l&#039;opérateur logique &amp;quot;décalage de bits vers la gauche&amp;quot; (&amp;quot;&amp;gt;&amp;gt;&amp;quot; pour le décalage à droite). Voir l&#039;article wikipedia sur le sujet, en Anglais, la version Française étant catastrophiquement incomplète [9].&lt;br /&gt;
&lt;br /&gt;
== Mettre le code sur le micro-contrôleur : lpctools ==&lt;br /&gt;
&lt;br /&gt;
Je sais que vous êtes de plus en plus impatients et que vous voulez voir le résultat de tout ceci en vrai, nous allons donc passer à la mise en flash sur le micro-contrôleur pour tester tout cela.&lt;br /&gt;
&lt;br /&gt;
Je ne traiterais ici que le cas de la version 48 broches du micro-contrôleur LPC1224 (package LQFP48). A vous d&#039;adapter si vous utilisez un autre micro-contrôleur, le principe étant très similaire pour tous les LPC de NXP. Pour les autres gammes de micro-contrôleurs, référez vous à leurs docs techniques et aux informations sur Internet.&lt;br /&gt;
&lt;br /&gt;
=== Connexion ===&lt;br /&gt;
Si vous avez mis l&#039;adaptateur USB-UART sur votre module comme proposé dans les articles précédents, l&#039;étape de connexion au PC est simple, connectez votre module sur un port USB, directement ou via un câble en fonction du connecteur USB que vous avez choisi.&lt;br /&gt;
&lt;br /&gt;
Sinon, il vous faudra un adaptateur USB-UART (souvent vendus comme adaptateurs USB-série) fonctionnant en 3.3V, et relier les signaux Rx et Tx aux signaux TXD0 et RXD0 correspondant à l&#039;UART 0 du micro-contrôleur LPC1224 qui se trouvent sur le port 0, pins 1 et 2 (broches 16 et 17 du composant). Il est alors préférable d&#039;avoir rendu ces signaux accesssibles sur un connecteur de votre choix, sans quoi il vous faudra souder des fils directement sur les pattes du micro-contrôleur ... possible, mais pas conseillé du tout).&lt;br /&gt;
&lt;br /&gt;
=== Mode ISP ===&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite mettre le micro-contrôleur en mode programmation (ISP : &amp;quot;In System Programming&amp;quot; en anglais). Le chapitre 20 (LPC122x Flash ISP/IAP) indique qu&#039;il faut maintenir la pin 12 du port 0 (broche 27) à l&#039;état bas (0V) pendant au moins 3ms après avoir relaché le signal &amp;quot;Reset&amp;quot; (pin 13 du port 0, broche 28). La suite du chapitre décrit le protocole de programmation, uniquement utile si vous voulez créer votre propre utilitaire pour programmer le micro-contrôleur, ou si vous voulez réaliser des opérations très spécifiques.&lt;br /&gt;
&lt;br /&gt;
Puisque nous avons placé des boutons poussoir reliant ces signaux à la masse, avec des résistance de &amp;quot;pull-up&amp;quot;, cette opération est très simple : il faut appuyer sur les deux boutons en même temps, puis relacher le bouton reset avant de relacher le bouton ISP.&lt;br /&gt;
Lorsque tout c&#039;est bien passé, la led bicolore doit avoir deux petits points lumineux à peine visibles dans l&#039;obscurité (un rouge et un vert).&lt;br /&gt;
&lt;br /&gt;
=== Dialogue avec le micro-contrôleur ===&lt;br /&gt;
&lt;br /&gt;
La suite se passe sur le PC. Le paquet lpctools contient deux binaires : lpcisp et lpcprog.&lt;br /&gt;
Le premier donne accès aux opérations élémentaires du protocole de programmation, et ne nous sera pas utile. Le second permet de programmer le micro-contrôleur en utilisant une unique commande, bien que d&#039;autres commandes permettent d&#039;effectuer quelques opérations intéressantes.&lt;br /&gt;
&lt;br /&gt;
Nous allons d&#039;ailleurs commencer par une de ces autres opération : demander les identifiants de notre micro-contrôleur avec la commande &amp;quot;id&amp;quot;.&lt;br /&gt;
La syntaxe des commandes lpcprog est simple, il suffit de lui passer un nom de device, que l&#039;on passe comme argument de l&#039;option &amp;quot;-d&amp;quot;, une commande (argument de l&#039;option &amp;quot;-c&amp;quot;), et si besoin le nom du fichier à utiliser.&lt;br /&gt;
Dans l&#039;exemple suivant le module GPIO-Démo est identifié sur le poste de développement comme périphérique &amp;quot;ttyUSB0&amp;quot;, nous utiliserons donc le &#039;&#039;device&#039;&#039; &amp;quot;/dev/ttyUSB0&amp;quot;.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c id&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Part ID is 0x3640c02b&lt;br /&gt;
 UID: 0x2c0cf5f5 - 0x4b32430e - 0x02333834 - 0x4d7c501a&lt;br /&gt;
 Boot code version is 6.1&lt;br /&gt;
La première ligne nous indique que lpcprog a reconnu le micro-contrôleur et qu&#039;il sera donc possible de le programmer. (Si ce n&#039;est pas le cas, vous devrez compléter le fichier de description des micro-contrôleurs).&lt;br /&gt;
Ensuite, lpcprog nous donne les informations propres au micro-contrôleur, à savoir son identifiant unique et la version du &amp;quot;boot code&amp;quot; qui se trouve en rom sur le micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Si vous avez un affichage similaire, tout va bien.&lt;br /&gt;
Sinon, vérifiez la connexion et que le micro-contrôleur est bien en mode ISP.&lt;br /&gt;
&lt;br /&gt;
La programmation se fait ensuite très simplement avec la commande &amp;quot;flash&amp;quot;, en ajoutant le nom du fichier binaire à envoyer.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c flash mod_gpio.bin&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Flash now all blank.&lt;br /&gt;
 Checksum check OK&lt;br /&gt;
 Flash size : 32768, trying to flash 1 blocks of 1024 bytes : 1024&lt;br /&gt;
 Writing started, 1 blocks of 1024 bytes ...&lt;br /&gt;
lpcprog se charge d&#039;effacer la flash, de générer la somme de contrôle de l&#039;entête et de la placer au bon endroit dans le binaire, et d&#039;envoyer le tout au micro-contrôleur pour mise en flash.&lt;br /&gt;
&lt;br /&gt;
Pour tester, il suffit d&#039;appuyer sur le bouton Reset, et de constater qu&#039;il ne se passe rien, ce qui n&#039;est pas ce que nous attendions.&lt;br /&gt;
&lt;br /&gt;
Il y a plusieurs problèmes.&lt;br /&gt;
&lt;br /&gt;
=== Votre code s&#039;il vous plait ! ===&lt;br /&gt;
&lt;br /&gt;
Le premier vient de la génération de la somme de contrôle, ou plutôt de sa position dans notre binaire.&lt;br /&gt;
Tous les LPC de NXP utilisent (à ce jour de ce que j&#039;ai pu voir) le même mécanisme pour déterminer si la flash contient une image valide avant d&#039;essayer d&#039;exécuter son contenu : la vérification du checksum des 8 premiers vecteurs d&#039;interruption, qui doit être nulle.&lt;br /&gt;
&lt;br /&gt;
Pour que ceci soit possible, conformément à la documentation technique des micro-contrôleurs, lpcprog calcule le complément à 2 des 7 premiers vecteurs, et le place dans le huitième.&lt;br /&gt;
&lt;br /&gt;
Sauf que notre tableau ne fait pour l&#039;instant que 5 &amp;quot;cases&amp;quot; et que la huitième case contenait en fait notre code exécutable, qui a été écrasé.&lt;br /&gt;
&lt;br /&gt;
La première modification est donc de remplir au moins 8 cases de ce tableau, au pire avec des valeurs nulles, sinon, avec des valeurs correspondant à ce qui est attendu dans la documentation : les adresses des routines de gestion, ou au moins celle de notre routine &amp;quot;de remplacement&amp;quot; (Dummy_Handler()) lorsque la documentation indique que l&#039;emplacement est utilisé (table 363 et figure 68 pour les exceptions, et table 4 pour les interruption).&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    0, /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
    NMI_Handler,&lt;br /&gt;
    HardFault_Handler,&lt;br /&gt;
    0,&lt;br /&gt;
    0, /* 5 */&lt;br /&gt;
    0,&lt;br /&gt;
    /* Entry 7 (8th entry) must contain the 2’s complement of the check-sum&lt;br /&gt;
       of table entries 0 through 6. This causes the checksum of the first 8&lt;br /&gt;
       table entries to be 0 */&lt;br /&gt;
    (void *)0xDEADBEEF, /* Actually, this is done using an external tool. */&lt;br /&gt;
    0,&lt;br /&gt;
    /* [.....] voir le code du module GPIO-Demo pour la suite */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Cependant ceci n&#039;est pas suffisant (vous pouvez désormais le tester très simplement, je vous laisse faire).&lt;br /&gt;
&lt;br /&gt;
=== Un peu de place pour la pile ===&lt;br /&gt;
&lt;br /&gt;
Le dernier point un petit peu particulier est encore sur cette fameuse table des vecteurs, et concerne la première entrée.&lt;br /&gt;
Si vous regardez attentivement la figure 68, le vecteur &amp;quot;Reset&amp;quot; n&#039;est que la deuxième entrée de la table.&lt;br /&gt;
La première est la valeur initiale du pointeur de la pile (Stack pointer), qui correspond en fait à son sommet puisque cette pile est remplie en faisant décroître les adresses (cette information se trouve dans le chapitre 25, mais cette fois je vous laisse chercher un petit peu).&lt;br /&gt;
&lt;br /&gt;
Nous avons initialisé cette valeur à 0, ce qui forcément pose un soucis.&lt;br /&gt;
&lt;br /&gt;
Pour obtenir la bonne valeur, nous pourrions coder en dur l&#039;adresse du haut de notre sram, mais ce n&#039;est pas propre.&lt;br /&gt;
Pour que tout soit fait correctement et automatiquement, nous allons modifier le script de l&#039;édition de liens, et demander à &#039;&#039;&#039;ld&#039;&#039;&#039; de remplir cette adresse à notre place, en fonction de l&#039;adresse de la sram et de sa taille.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc créer des variables dans notre script, juste après la définition de la mémoire disponible, et chose très importante, ces variables seront des variables externes utilisables dans notre code C !&lt;br /&gt;
: _sram_size = LENGTH(sram);&lt;br /&gt;
: _sram_base = ORIGIN(sram);&lt;br /&gt;
: _end_stack = (_sram_base + _sram_size);&lt;br /&gt;
Nous appelons le bas de la pile (la &amp;quot;fin&amp;quot; de la pile) &#039;&#039;&#039;_end_stack&#039;&#039;&#039;, et plaçons cette fin de pile tout en haut de la mémoire vive.&lt;br /&gt;
&lt;br /&gt;
Et pour l&#039;utilisation dans notre code C, tout simplement :&lt;br /&gt;
 extern unsigned int _end_stack;&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    &amp;amp;_end_stack, /* Initial SP value */ /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Si vous compilez votre code avec ces modifications, vous obtenez enfin un binaire qui allume la Led !&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Nous avons enfin notre &amp;quot;Hello World !&amp;quot; version électronique, mais la route est encore longue.&lt;br /&gt;
&lt;br /&gt;
Vous pourrez voir dans le prochain article que cette première étape n&#039;était qu&#039;une étape, et qu&#039;il reste encore plusieurs étapes importantes avant de pouvoir vraiment commencer à écrire du code &amp;quot;fonctionnel&amp;quot;, comme la gestion du &amp;quot;watchdog&amp;quot;, la configuration de l&#039;horloge interne, l&#039;initialisation de la mémoire, et l&#039;écriture des drivers pour chaque bloc fonctionnel (liaison série, I2C, SPI, ADC, ....).&lt;br /&gt;
&lt;br /&gt;
Rendez-vous donc pour le second article dédié à la programmation de notre micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Merci pour votre lecture attentive !&lt;br /&gt;
&lt;br /&gt;
== Les fichiers créés ==&lt;br /&gt;
Vous trouverez sur notre serveur le [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/Makefile Makefile], le fichier C [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/main.c main.c], et le script de lien [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/lpc_link_lpc1224.ld lpc_link_lpc1224.ld]&lt;br /&gt;
&lt;br /&gt;
== Liens - Bibliographie ==&lt;br /&gt;
* [1] https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Option-Summary.html&lt;br /&gt;
* [2] https://sourceware.org/binutils/docs/binutils/objdump.html&lt;br /&gt;
* [3] https://sourceware.org/binutils/docs/binutils/readelf.html&lt;br /&gt;
* [4] Page du module et Manuel utilisateur : http://www.techno-innov.fr/technique-module-gpio-demo/ - http://techdata.techno-innov.fr/Modules/GPIO_Demo/System_Reference_Manual_Module_GPIO_Demo_v03.pdf&lt;br /&gt;
* [5] Dépôt GIT lpctools : http://git.techno-innov.fr/?p=lpctools&lt;br /&gt;
* [6] Lien vers d&#039;autres outils pour programmer les LPC :&lt;br /&gt;
** mxli : http://www.windscooting.com/softy/mxli.html&lt;br /&gt;
** lpc21isp : http://sourceforge.net/projects/lpc21isp/&lt;br /&gt;
** nxpprog : http://sourceforge.net/projects/nxpprog/&lt;br /&gt;
** GLPC (GUI pour lpc21isp) : http://sourceforge.net/projects/glpc/&lt;br /&gt;
* [7] Manuel utilisateur du LPC1224 : http://www.nxp.com/documents/user_manual/UM10441.pdf&lt;br /&gt;
* [8] http://fr.wikipedia.org/wiki/Segment_BSS&lt;br /&gt;
* [9] http://en.wikipedia.org/wiki/Bitwise_operation&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=109</id>
		<title>Articles/Nathael/Domotab et elec Libre partie5</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=109"/>
		<updated>2020-09-02T21:22:33Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Tisser des liens, c&amp;#039;est important */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Électronique et domotique libre - partie 5 : Programmation, Premiers signes de vie}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; margin-right: 2.5em;&amp;quot;&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DomoTab.png|200px|right]]&lt;br /&gt;
Programmation du module !&lt;br /&gt;
&lt;br /&gt;
Nous avons vu dans le quatrième article comment fabriquer le module GPIO-Démo (ou toute version modifiée), nous allons désormais nous atteler à lui donner vie.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1&#039;&#039;&#039; : La programmation sera faite en C, bien que d&#039;autres langages puissent être utilisés, à la seule condition qu&#039;il existe un compilateur qui puisse générer du code binaire pour ARM à partir de ce langage.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2&#039;&#039;&#039; : Les tailles indiquées dans cet article dépendent de la version de GCC utilisé, et il est presque certain que vous obtiendrez des tailles différentes. Si il y a de trop gros écarts, c&#039;est que vous avez fait une erreur, par exemple un cas que j&#039;ai eu fréquement en TP : l&#039;oubli du &amp;quot;AT &amp;gt;flash&amp;quot; pour le bloc de données placé en RAM, à l&#039;adresse 0x10000000, soit 256Mo ... et produit un binaire de ... 256Mo :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;par Nathael Pajani&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:right&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
Paru dans le [http://boutique.ed-diamond.com/home/851-open-silicium-14.html numéro 14] du magazine Open Silicium.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Les documentations techniques ==&lt;br /&gt;
&lt;br /&gt;
La première étape lorsqu&#039;on veut écrire du code pour un système embarqué qui utilise un micro-contrôleur, c&#039;est d&#039;en trouver la documentation technique.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès aux documentations techniques est à mon avis un des critères principaux dans le choix des composants pour un projet, aussi bien pour les concepteurs que pour les utilisateurs.&lt;br /&gt;
&lt;br /&gt;
Si vous avez réalisé la conception du circuit, vous aurez normalement déjà eu besoin de ces documentations, dans le cas contraire, c&#039;est le moment de les récupérer.&lt;br /&gt;
Pour le module GPIO-Démo, il y a plusieurs documentations techniques nécessaires pour utiliser la totalité des fonctionnalités du module.&lt;br /&gt;
La première et la plus importante est celle du micro-contrôleur [7], mais vous aurez aussi besoin de celle du module, disponible sur le site de Techno-Innov [4], et de celles de l&#039;EEPROM I2C, et du capteur de température I2C.&lt;br /&gt;
&lt;br /&gt;
Encart : Pour ce qui est du bridge USB-UART, la documentation n&#039;est pas nécessaire pour la programmation du micro-contrôleur et du module, mais elle le devient si vous voulez modifier la façon dont le composant s&#039;identifie lorsque vous le connectez, par exemple pour pouvoir lui donner un nom spécifique ou simplifier l&#039;identification. Cela ne sera cependant pas le sujet de cet article.&lt;br /&gt;
&lt;br /&gt;
Pour récupérer les documentations techniques, vous avez le choix entre le site du fabriquant et celui du distributeur chez qui vous avec acheté les composants. Pour la majorité des composants j&#039;utilise le site du distributeur (possible uniquement si il fourni les bonnes documentations), mais pour les micro-contrôleurs je consulte le site du fabriquant car il fourni aussi les &amp;quot;errata&amp;quot; (notes d&#039;informations contenant les corrections sur la documentation) et le plus souvent des notes d&#039;application qui indiquent comment utiliser le composant pour telle ou telle application (avec parfois des exemples de code).&lt;br /&gt;
&lt;br /&gt;
== Outils de programmation ==&lt;br /&gt;
&lt;br /&gt;
La deuxième étape ne concerne toujours pas le code que vous voulez écrire.&lt;br /&gt;
&lt;br /&gt;
En effet, pour écrire du code vous n&#039;avez pas besoin de la &amp;quot;cible&amp;quot; (target en anglais) qui est le matériel sur lequel vous allez exécuter la version compilée du code, mais uniquement d&#039;un poste de développement, couramment appelé hôte (host en anglais).&lt;br /&gt;
&lt;br /&gt;
Cependant, la cible en question n&#039;a que faire des fichiers sources qui se trouvent sur votre poste de développement, et il vous faudra un certain nombre d&#039;outils pour passer des fichiers source (quelque soit le langage) au code exécutable par votre carte électronique.&lt;br /&gt;
&lt;br /&gt;
C&#039;est aussi un point très important à mon sens dans le choix d&#039;un système embarqué ou d&#039;un micro-contrôleur : quels sont les outils dont j&#039;aurais besoin pour passer de mon code source à un système fonctionnant avec ?&lt;br /&gt;
&lt;br /&gt;
Dans le cas des micro-contrôleurs de la gamme LPC de NXP il existe de nombreuses solutions pour passer de l&#039;un à l&#039;autre, mais ce qui est intéressant à mon sens c&#039;est qu&#039;il est possible de le faire avec un minimum de matériel et de logiciel : une liaison série &amp;quot;TTL 3.3V&amp;quot;, une chaîne de compilation croisée et un utilitaire pour &amp;quot;uploader&amp;quot; le code binaire.&lt;br /&gt;
&lt;br /&gt;
=== Matériel : un port USB (et le PC qui va avec) ===&lt;br /&gt;
&lt;br /&gt;
[[Image:14-Module sur USB.png|300px|right]]&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la liaison série &amp;quot;TTL 3.3V&amp;quot;, il existe plein d&#039;adaptateurs USB-UART fonctionnant en 3.3V, et pour le cas du module GPIO-Démo cet adaptateur est intégré sur le module, un port USB suffit donc.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès à cette liaison série se fera via un fichier spécial dont le nom sera devrait ressembler à &amp;quot;/dev/ttyUSB0&amp;quot;, le &amp;quot;USB0&amp;quot; pouvant différer selon votre système (&amp;quot;USB1&amp;quot;, USB2&amp;quot;, ... ou même &amp;quot;ACM0&amp;quot; avec d&#039;autres adaptateurs).&lt;br /&gt;
&lt;br /&gt;
=== Compilation : GNU ===&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la chaîne de compilation croisée, les micro-contrôleurs LPC de NXP utilisent des cœurs ARM Cortex-M*, très bien supportés par gcc, bien connu de tous les lecteurs de ce magazine (du moins je le pense), et parfaitement adapté à la cross-compilation.&lt;br /&gt;
&lt;br /&gt;
Dit comme ça, c&#039;est simple ... mais en fait, pas tant que ça.&lt;br /&gt;
Cette problématique pourrait faire l&#039;objet d&#039;un (petit ?) article, je ne l&#039;inclurai donc pas ici, je vous donne juste quelques pistes et suppose que vous saurez trouver les informations sur le net. De mon côté je dois les intégrer à la documentation technique du module GPIO-Démo, mais ce n&#039;est pas encore fait à l&#039;heure où j&#039;écris ces lignes :( [4].&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;avez pas déjà une chaîne de cross-compilation installée pour ARM vous avez globalement trois solutions : Debian/EmDebian (celle que j&#039;utilise), Launchpad, et Crosstools-ng.&lt;br /&gt;
&lt;br /&gt;
Le projet EmDebian fournit des paquets debian pour différentes chaînes de cross-compilation (ARM parmi tant d&#039;autres), qui sont entrain d&#039;être intégrées à Debian. Cela devrait simplifier les problèmes de dépôts et de dépendances dont souffrait les dépôts EmDebian, même si seule la version &amp;quot;arm-none-eabi&amp;quot; (qui nous suffit, nous n&#039;avons pas besoin de libC) est actuellement intégrée dans SID sans problèmes de dépendances (j&#039;ai bien dit &amp;quot;devrait&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Le site de Launchpad fourni aussi des versions binaires de la chaîne de cross-compilation GCC ARM.&lt;br /&gt;
&lt;br /&gt;
La solution CrossTools-ng : recompilation de sa propre chaîne de compilation croisée : la solution du dernier recours, si votre distribution ne fournit pas de solution packagée et que les versions binaires non signées ne vous conviennent pas.&lt;br /&gt;
&lt;br /&gt;
=== Programmation : lpctools (ou autre) ===&lt;br /&gt;
&lt;br /&gt;
Enfin, pour ce qui est de l&#039;utilitaire permettant de charger (uploader) le code binaire sur le micro-contrôleur (flasher le micro-contrôleur), je n&#039;avais pas trouvé d&#039;outil libre permettant de réaliser cette étape au moment où j&#039;ai étudié la possibilité d&#039;utiliser les micro-contrôleurs de NXP, mais le protocole série permettant de réaliser cette opération était documenté dans la documentation technique des micro-contrôleurs, il ne devait donc pas y avoir de problème de ce côté là.&lt;br /&gt;
&lt;br /&gt;
La seule solution &amp;quot;gratuite&amp;quot; que j&#039;avais trouvé à l&#039;époque ne fonctionnait que sur un seul système (pas le miens), ne fournissait pas ses sources, et interdisait une utilisation commerciale sans payer une licence, hors je voulais justement en faire une utilisation commerciale.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai donc pris quelques heures de mon temps pour coder un utilitaire permettant de programmer les micro-contrôleurs LPC, et placé le tout sous licence GPL v3 [5].&lt;br /&gt;
Le tout est désormais disponible sur le site de Techno-Innov, et est intégré depuis peu à la distribution Debian GNU/Linux (Sid et Jessie à l&#039;heure de l&#039;écriture de ces lignes).&lt;br /&gt;
&lt;br /&gt;
J&#039;ai entre-temps découvert d&#039;autres projets permettant de programmer des micro-contrôleurs LPC, mais je ne les ai pas testés (nxpprog - licence MIT, mxli - GPLv3, pyLPCTools - GPLv2) et constaté qu&#039;un autre paquet Debian fournit les outils permetant de programmer les micro-contrôleurs LPC de NXP : lpc21isp (qui dispose d&#039;ailleurs d&#039;une interface graphique : GLPC, qui elle n&#039;est pas dans les dépôts). Voir liens [6] en fin d&#039;article.&lt;br /&gt;
&lt;br /&gt;
== Makefile - particularités pour la compilation croisée ==&lt;br /&gt;
&lt;br /&gt;
Une dernière petite étape avant d&#039;écrire notre code, bien que l&#039;on se rapproche de la programmation, puisqu&#039;il s&#039;agit d&#039;un élément essentiel de tout projet : la création du Makefile.&lt;br /&gt;
&lt;br /&gt;
Dans le cas de la compilation pour une cible comme le module GPIO-Démo le Makefile doit inclure quelques éléments supplémentaires que l&#039;on ne retrouve habituellement pas dans un Makefile classique.&lt;br /&gt;
&lt;br /&gt;
Le premier élément concerne la définition du compilateur à utiliser. Nous utiliserons la variable &amp;quot;CROSS_COMPILE&amp;quot; à laquelle nous affecterons une valeur par défaut correspondant au préfixe du compilateur. Si vous voulez utiliser un compilateur correctement installé sur le système, il suffit d&#039;utiliser le préfixe, sinon, il faudra ajouter devant la totalité du chemin donnant accès au compilateur.&lt;br /&gt;
&lt;br /&gt;
Par exemple pour le compilateur EmDebian :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
ou avec un chemin complet pour un autre compilateur :&lt;br /&gt;
: CROSS_COMPILE ?= /usr/local/mon/compilateur/bin/arm-none-eabi-&lt;br /&gt;
&lt;br /&gt;
Le &amp;quot;?=&amp;quot; permet de ne modifier la variable que si elle n&#039;existe pas, notamment si elle n&#039;est pas déjà présente dans la ligne de commande.&lt;br /&gt;
&lt;br /&gt;
Cette variable est ensuite utilisée pour modifier la variable &amp;quot;CC&amp;quot; utilisée par &amp;quot;make&amp;quot; pour compiler les fichiers de code source C. Si vous utilisez un autre langage, modifiez la variable correspondante.&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
Il est aussi possible d&#039;en profiter pour spécifier une version du compilateur installé :&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc-4.7&lt;br /&gt;
Nous allons en profiter pour définir la variable &amp;quot;LD&amp;quot; qui correspond à l&#039;éditeur de liens (linker en anglais) :&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
&lt;br /&gt;
Il nous faut ensuite définir la cible pour laquelle nous voulons compiler. Dans notre cas il s&#039;agit d&#039;un cœur ARM Cortex-M0, qui utilise le jeu d&#039;instructions &amp;quot;thumb&amp;quot; (instructions sur 16bits permettant d&#039;obtenir un code plus compact), nous allons donc utiliser les options -mcpu et -mthumb de gcc pour lui indiquer notre besoin :&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: CFLAGS = -Wall -mthumb -mcpu=$(CPU)&lt;br /&gt;
&lt;br /&gt;
En plus de cela, nous allons demander au compilateur de ne pas reconnaître les fonctions pour lesquelles il a une définition interne (builtin) tout simplement parce que la majorité de ces fonctions dépendent d&#039;un environnement très différent de celui de notre micro-contrôleur, soit par la présence d&#039;une bibliothèque C, d&#039;un système d&#039;exploitation respectant la norme POSIX, ou d&#039;une unité de calcul flottant.&lt;br /&gt;
Rien de tout ceci n&#039;est vrai dans notre cas, et il est donc préférable que le compilateur nous informe si nous tentons d&#039;utiliser ces fonctions sans l&#039;avoir explicitement demandé en utilisant le préfixe &amp;quot;__builtin__&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous demanderons aussi au compilateur de bien placer les données et les fonctions dans leurs sections respectives. Malgré ce que dit la documentation de GCC, cela permet (au moins dans notre cas) de produire un binaire plus petit. Cela se fait à l&#039;aide des directives d&#039;optimisation &amp;quot;-ffunction-sections&amp;quot; et &amp;quot;-fdata-sections&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous ajouterons ces directives dans une variable dédiée :&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Nous obtenons donc les lignes suivantes à ajouter à votre Makefile :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
: CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
&lt;br /&gt;
Notre Makefile ressemblerait alors à ceci :&lt;br /&gt;
 NAME = mod_gpio&lt;br /&gt;
 CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
 CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
 LD = $(CROSS_COMPILE)ld&lt;br /&gt;
 CPU = cortex-m0&lt;br /&gt;
 FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
 CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
 &lt;br /&gt;
 .PHONY: all&lt;br /&gt;
 all: $(NAME)&lt;br /&gt;
 &lt;br /&gt;
 SRC = $(wildcard *.c)&lt;br /&gt;
 OBJS = $(SRC:.c=.o)&lt;br /&gt;
 &lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ -o $@&lt;br /&gt;
Ce Makefile est encore incomplet et ne permet pas d&#039;obtenir le binaire pour notre micro-contrôleur, mais nous ajouterons les parties manquantes plus tard.&lt;br /&gt;
&lt;br /&gt;
En attendant, ce Makefile nous permettra de compiler le code que nous allons écrire, passons donc aux parties intéressantes, et le reste du Makefile sera bien plus simple à comprendre.&lt;br /&gt;
&lt;br /&gt;
== Commençons simple ==&lt;br /&gt;
&lt;br /&gt;
Pour ne pas trop compliquer les choses dès le début, nous allons tenter de faire clignoter la led bicolore présente sur le module GPIO-Démo.&lt;br /&gt;
&lt;br /&gt;
Notre squelette de code ressemblera à s&#039;y méprendre à ce que l&#039;on pourrait avoir pour un programme plus commun :&lt;br /&gt;
 /*&lt;br /&gt;
  * Notre exemple simple pour Open Silicium&lt;br /&gt;
  */&lt;br /&gt;
 void system_init(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* System init ? */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* Micro-controller init */&lt;br /&gt;
 	system_init();&lt;br /&gt;
 	&lt;br /&gt;
 	while (1) {&lt;br /&gt;
 		/* Change the led state */&lt;br /&gt;
 		/* Wait some time */&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 }&lt;br /&gt;
Si vous compilez ce petit morceau de code avec notre Makefile, vous obtiendrez un binaire qui globalement ne fait rien, mais a déjà une taille de 5.7 Ko.&lt;br /&gt;
C&#039;est gros pour ne rien faire, d&#039;autant que la mémoire Flash de notre micro-contrôleur ne fait que 32 Ko.&lt;br /&gt;
&lt;br /&gt;
Si on regarde plus loin, par exemple avec l&#039;utilitaire &#039;&#039;file&#039;&#039;, on obtient quelques informations supplémentaires :&lt;br /&gt;
 $ file mod_gpio&lt;br /&gt;
 mod_gpio: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), [....], not stripped&lt;br /&gt;
&lt;br /&gt;
Arghhh, notre binaire est un exécutable dynamique au format ELF, qui utilise des bibliothèques partagées !&lt;br /&gt;
&lt;br /&gt;
Nous l&#039;avons déjà évoqué, notre micro-contrôleur n&#039;a pas de libC ni de système d&#039;exploitation, notre binaire ne peut donc pas être dynamique (lié dynamiquement à des bibliothèques) !&lt;br /&gt;
Il nous faut donc faire l&#039;édition de lien en &amp;quot;static&amp;quot;, en apportant quelques modification à notre Makefile. Nous allons introduire une variable &amp;quot;LDFLAGS&amp;quot;, que l&#039;on ajoutera à la règle de compilation utilisée pour l&#039;édition de liens.&lt;br /&gt;
 LDFLAGS = -static&lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ $(LDFLAGS) -o $@&lt;br /&gt;
Recompilons notre projet ... 608 Ko !!! Re-Argh !&lt;br /&gt;
&lt;br /&gt;
Visiblement quelqu&#039;un ajoute du code dont nous n&#039;avons pas besoin. Il faut du moins l&#039;espérer, sinon il ne sera jamais possible de faire rentrer un programme dans la flash de notre micro-contrôleur, qui fait toujours 32Ko.&lt;br /&gt;
&lt;br /&gt;
L&#039;option &amp;quot;static&amp;quot; demande à l&#039;éditeur de lien de créer un binaire statique, mais résultat il nous ajoute tout ce qui est utile de la libC pour un exécutable ... pour un système Linux.&lt;br /&gt;
D&#039;ailleurs, &#039;&#039;file&#039;&#039; nous dit bien que notre exécutable est au format ELF.&lt;br /&gt;
&lt;br /&gt;
Pour commencer nous allons demander à l&#039;éditeur de liens (ld) de ne pas inclure les éléments de démarrage dans notre binaire, car ils sont inutiles sur notre micro-contrôleur. Pour cela nous ajoutons l&#039;option &amp;quot;-nostartfiles&amp;quot; à nos directives pour l&#039;édition de liens.&lt;br /&gt;
&lt;br /&gt;
Et hop, une recompilation plus tard, notre binaire ne fait plus que 1 Ko :)&lt;br /&gt;
Mais pour &#039;&#039;file&#039;&#039;, ce binaire est toujours au format ELF, et gcc nous informe qu&#039;il n&#039;a pas trouvé de symbole d&#039;entrée &amp;quot;_start&amp;quot; et qu&#039;il utilise une adresse par défaut (nous l&#039;avons cherché, cela fait partie de ce que nous avons demandé à l&#039;éditeur de liens en ajoutant l&#039;option &amp;quot;-nostartfiles&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
En effet, le &amp;quot;main&amp;quot; de nos programmes en C n&#039;est que le point de départ de l&#039;exécution de notre code, mais pas celui du programme. Il est précédé par un certain nombre de routines (fonctions) d&#039;initialisation, dont le point d&#039;entrée est la routine &amp;quot;_start&amp;quot;, qui appellera le main &amp;quot;classique&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Mais notre but n&#039;est pas de créer un exécutable pour un système Linux, nous devons créer un binaire pour notre micro-contrôleur. Il est désormais temps de nous plonger dans la documentation du micro-contrôleur pour comprendre comment il démarre, pour pouvoir adapter notre code au démarrage du micro-contrôleur et fournir l&#039;équivalent de cette routine &amp;quot;_start&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bootstrap == &lt;br /&gt;
&lt;br /&gt;
=== Table des vecteurs d&#039;interruption ===&lt;br /&gt;
&lt;br /&gt;
Pour avoir des informations sur le démarrage du micro-contrôleur LPC1224 dans sa documentation technique [7] il y a deux chapitres intéressants.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons nous référer au chapitre 4 (LPC122x System control) qui inclut une section sur le reset du micro-contrôleur (4.6 : Reset), dans laquelle on apprend qu&#039;une fois que la condition de reset disparait et que les procédures internes se sont exécutées, le processeur commence l&#039;exécution à l&#039;adresse contenue dans le vecteur &amp;quot;Reset&amp;quot; du &amp;quot;boot block&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous avons ainsi quelques informations, mais qu&#039;est-ce que le vecteur &amp;quot;Reset&amp;quot; et le &amp;quot;boot block&amp;quot; ? Cela nous mène au deuxième chapitre intéressant, le chapitre 25 sur le cœur ARM Cortex-M0. On y trouve une section sur le processeur (25.3 : Processor) avec une sous section concernant les exeptions (25.3.3 : Exception model). &lt;br /&gt;
&lt;br /&gt;
Dans les informations sur les exceptions (25.3.3.2), et plus particulièrement l&#039;exception &amp;quot;Reset&amp;quot;, il est indiqué qu&#039;après un &amp;quot;Reset&amp;quot; l&#039;exécution reprend à l&#039;adresse indiquée dans le vecteur &amp;quot;Reset&amp;quot; dans la table des vecteurs d&#039;interruption.&lt;br /&gt;
&lt;br /&gt;
Bien, cela confirme ce qui se trouvait dans le chapitre 4. Mais cette fois, nous avons une sous-section &amp;quot;25.3.3.4 Vector table&amp;quot;, qui décrit cette fameuse table des vecteurs d&#039;exception, précisant qu&#039;elle contient l&#039;addresse de toutes les routines de gestion des exceptions (les fameux &amp;quot;vecteurs&amp;quot; d&#039;exception, dont le vecteur &amp;quot;Reset&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Remarquez au passage que les interruptions sont gérées de la même façon, l&#039;addresse d&#039;entrée des routines de gestion des interruptions se trouve dans cette même table.&lt;br /&gt;
&lt;br /&gt;
Et en dessous de cette table, nous avons une autre information très intéressante : &amp;quot;The vector table is fixed at address 0x00000000&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Si l&#039;on se réfère à la table 65 de la section &amp;quot;25.3.2 Memory model&amp;quot;, et à la figure 2 de la section &amp;quot;2.3 Memory allocation&amp;quot;, on découvre que cette adresse est en fait le début de la mémoire flash du micro-contrôleur, qui devra contenir notre code binaire.&lt;br /&gt;
&lt;br /&gt;
Reste à créer cette table, et à la placer au bon endroit dans le code binaire compilé...&lt;br /&gt;
&lt;br /&gt;
=== Les &amp;quot;handlers&amp;quot; et les &amp;quot;dummy handlers&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
Nous allons commencer par la partie code.&lt;br /&gt;
Ce code peut être placé dans le même fichier que celui ou ce trouve notre fonction main, ou dans un autre fichier, cela n&#039;a pas d&#039;importance. Si vous vous référez au code du module GPIO-Démo disponible dans les dépôts git de Techno-Innov, vous trouverez ce code dans le fichier &amp;quot;core/bootstrap.c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Vecteurs_interruption.png|350px|right]]&lt;br /&gt;
&lt;br /&gt;
 /* Cortex M0 core interrupt handlers */&lt;br /&gt;
 void Reset_Handler(void);&lt;br /&gt;
 void NMI_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 void HardFault_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void);&lt;br /&gt;
 &lt;br /&gt;
 void *vector_table[] = {&lt;br /&gt;
 	0,&lt;br /&gt;
 	Reset_Handler,&lt;br /&gt;
 	NMI_Handler,&lt;br /&gt;
 	HardFault_Handler,&lt;br /&gt;
 	0,&lt;br /&gt;
 	/* [......] */&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void) {&lt;br /&gt;
     while (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Voici un petit morceau de code relativement court qui définit notre table de vecteur ainsi que les routines de gestion correspondantes.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, faisons un petit point sur certains éléments : les attributs utilisés pour la déclaration de deux de nos routines de gestion des exceptions : &amp;quot;__attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ces attributs permettent de définir un alias &amp;quot;faible&amp;quot; pour une fonction, ce qui veut dire que si le compilateur ne trouve pas de définition pour cette fonction, il pourra utiliser son alias, que nous avons défini plus bas. Au contraire, si dans un autre fichier (ou celui-ci) vous définissez l&#039;une de ces fonctions, c&#039;est votre définition qui sera utilisée.&lt;br /&gt;
&lt;br /&gt;
Note : je n&#039;ai pas mis la totalité de la table des vecteurs, cela n&#039;a pas d&#039;intérêt pour les explications, et notre programme fonctionnera sans, mais il faudrait la compléter pour un vrai programme, en faisant attention à l&#039;ordre, à partir des informations de la figure 68 déjà évoquée, et de la table 4 du chapitre 3 concernant le gestionnaire d&#039;interruptions (vous noterez la typo, il s&#039;agit des numéros d&#039;IRQ et non pas des numéros des vecteurs d&#039;exception).&lt;br /&gt;
&lt;br /&gt;
=== Appeler notre main() ===&lt;br /&gt;
Ce petit bout de code compile donc, puisque tout est défini, mais nous avons toujours l&#039;avertissement concernant le symbole d&#039;entrée &amp;quot;_start&amp;quot; qui n&#039;a pas été trouvé. Nous ne sommes pas plus avancé.&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, nous avons déjà indiqué que le point d&#039;entrée de notre code est la fonction main() (qui pourrait avoir n&#039;importe quel nom), mais pour notre micro-controlleur la fonction d&#039;entrée du programme est la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
La solution pour faire le lien est toute simple : il suffit d&#039;appeler la fonction main() depuis la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
 int main(void);&lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 	main();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Tisser des liens, c&#039;est important ===&lt;br /&gt;
Cela ne résout cependant aucun de nos problèmes, nous allons donc devoir donner plus d&#039;indications à l&#039;éditeur de liens, en créant un script pour l&#039;édition de lien (lpc_link_lpc1224.ld). Nous donnerons le nom de ce script à l&#039;éditeur de liens en utilisant l&#039;otion &amp;quot;-T&#039;&#039;lpc_link_lpc1224.ld&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ce script d&#039;édition de lien (&amp;quot;linker script&amp;quot; en anglais) est en fait un fichier qui décrit la mémoire de notre micro-contrôleur, ainsi que l&#039;organisation que devra respecter notre binaire.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc commencer, toujours à partir des mêmes informations en provenance de la documentation technique, par définir quelle est la mémoire disponible, aussi bien la mémoire &amp;quot;vive&amp;quot; (SRAM) que la mémoire &amp;quot;morte&amp;quot; (FLASH).&lt;br /&gt;
&lt;br /&gt;
 MEMORY&lt;br /&gt;
 {&lt;br /&gt;
 	sram (rwx) : ORIGIN = 0x10000000, LENGTH = 4k&lt;br /&gt;
 	flash (rx) : ORIGIN = 0x00000000, LENGTH = 32k&lt;br /&gt;
 }&lt;br /&gt;
Nous définissons ainsi l&#039;adresse et la taille (et les droits d&#039;accès) de la sram et de la flash, qui deviennent deux blocs de mémoire disponibles pour l&#039;éditeur de liens, qui pourra donc y placer du code et des données.&lt;br /&gt;
&lt;br /&gt;
Il nous faut maintenant expliquer à l&#039;éditeur de liens comment organiser le code et les données dans ces blocs de mémoire, et tout particulièrement notre tableau de vecteurs d&#039;interruptions&lt;br /&gt;
&lt;br /&gt;
Le code d&#039;un programme est composé de &amp;quot;sections&amp;quot;, dans lesquelles le compilateur place chaque fonction et chaque variable en fonction de différents critères, que l&#039;on peut contrôler soit à partir de directives de compilation, soit d&#039;attributs ajoutés dans notre code C&lt;br /&gt;
&lt;br /&gt;
Nous allons donc modifier notre tableau de vecteurs d&#039;interruptions pour lui ajouter un attribut &amp;quot;section&amp;quot; qui forcera l&#039;éditeur de liens à le placer dans la section que nous avons défini.&lt;br /&gt;
: void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
&lt;br /&gt;
Et en parallèle, nous allons définir dans notre script quelles sont les sections que nous voulons trouver dans notre binaire, et dans quel ordre.&lt;br /&gt;
Commençons simple (si si, je vous assure), nous compliquerons plus tard :&lt;br /&gt;
 SECTIONS {&lt;br /&gt;
 	. = ORIGIN(flash);&lt;br /&gt;
 	.text :&lt;br /&gt;
 	{&lt;br /&gt;
 		KEEP(*(.vectors))&lt;br /&gt;
 		*(.text*)&lt;br /&gt;
 		*(.rodata*)&lt;br /&gt;
 	} &amp;gt;flash&lt;br /&gt;
 	.data :&lt;br /&gt;
 	{&lt;br /&gt;
 		*(.data*)&lt;br /&gt;
 		*(.bss*)&lt;br /&gt;
 	} &amp;gt;sram&lt;br /&gt;
 }&lt;br /&gt;
Pour commencer, nous définissons l&#039;adresse courante (.) comme étant l&#039;origine de du bloc de mémoire &amp;quot;flash&amp;quot; (le bloc de mémoire défini précédemment et auquel nous avons donné ce nom, bien qu&#039;un autre nom aurait pu faire l&#039;affaire).&lt;br /&gt;
Ceci est important pour que l&#039;éditeur de liens puisse définir les adresses des fonctions pour l&#039;exécution de notre code.&lt;br /&gt;
À partir de ce point nous définissons une section &amp;quot;text&amp;quot;, dans laquelle nous allons demander à l&#039;éditeur de lien de mettre plusieurs éléments, à commencer par notre fameuse table de vecteurs, en lui interdisant d&#039;en changer la position !&lt;br /&gt;
Après quoi, nous lui demandons de placer l&#039;ensemble du code, que le compilateur a placé dans des section &amp;quot;.text.*&amp;quot;, puis les données en lecture seule (Read-Only data = rodata), et de placer le tout dans le bloc de mémoire &amp;quot;flash&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
À la suite, nous créons une section &amp;quot;data&amp;quot;, dans laquelle nous lui demandons de placer les données initialisées à des valeurs non nulles (data), puis les données initialement nulles (bss [8]), et de placer cette section en RAM.&lt;br /&gt;
&lt;br /&gt;
Ne reste plus qu&#039;une information à donner à l&#039;éditeur de liens (pour l&#039;instant): le point d&#039;entrée de notre programme.&lt;br /&gt;
Ceci est relativement simple et explicite :&lt;br /&gt;
: ENTRY(Reset_Handler)&lt;br /&gt;
&lt;br /&gt;
Dans notre Makefile la variable LDFLAGS devient :&lt;br /&gt;
: LDFLAGS = -static -nostartfiles -Tlpc_link_lpc1224.ld&lt;br /&gt;
&lt;br /&gt;
Une compilation plus tard, sans avertissements cette fois, nous avons un binaire ... beaucoup trop gros : notre binaire fait maintenant plus de 66 Ko !&lt;br /&gt;
&lt;br /&gt;
Soyons un peu curieux et allons donc voir ce qu&#039;il contient, mais pas à la main, rassurez vous, utilisons un utilitaire fait exprès pour cela : &#039;&#039;objdump&#039;&#039;. attention, il faut bien entendu utiliser la version &amp;quot;ARM&amp;quot; de objdump, donc avec le préfixe &amp;quot;CROSS_COMPILE&amp;quot;, soit dans mon cas &#039;&#039;arm-linux-gnueabi-objdump&#039;&#039;, avec l&#039;option &#039;&#039;--disassemble-all&#039;&#039; (-D) :&lt;br /&gt;
: arm-linux-gnueabi-objdump -D mod_gpio &amp;gt; dump&lt;br /&gt;
Et là, surprise, la version &amp;quot;désassemblée&amp;quot; de notre binaire est plus petite que la version binaire (le fichier &amp;quot;dump&amp;quot; fait 2.2 Ko).&lt;br /&gt;
&lt;br /&gt;
Regardons tout de même son contenu.&lt;br /&gt;
La première ligne nous informe que le format du fichier est &amp;quot;elf32-littlearm&amp;quot; ... pas grand chose à voir avec ce que nous voulions, un &amp;quot;simple&amp;quot; binaire (Notre micro-contrôleur n&#039;a toujours pas appris à lire les exécutables au format ELF). Premier problème.&lt;br /&gt;
&lt;br /&gt;
Quelqu&#039;un est venu glisser une section &amp;quot;.note.gnu.build-id&amp;quot; avant notre section &amp;quot;.text&amp;quot;, que l&#039;éditeur de liens aimerait placer en début de RAM (&amp;quot;10000000 &amp;lt;_sram_base&amp;gt;&amp;quot;), ce qui n&#039;a pas d&#039;intérêt pour nous.&lt;br /&gt;
&lt;br /&gt;
S&#039;en suit tout de même notre section &amp;quot;.text&amp;quot;, qui commence bien par notre table (enfin ! on nous écoute un peu !), suivie de nos quelques maigres fonctions. Notez les adresses des fonctions dans la table des vecteurs, qui sont toutes impaires. Ceci indique que notre processeur exécutera ces fonctions en mode &amp;quot;thumb&amp;quot; qui est bien le mode que nous avions demandé (-mthumb).&lt;br /&gt;
&lt;br /&gt;
Et encore une fois, notre section &amp;quot;.text&amp;quot; n&#039;est pas suivie de nos données, mais d&#039;autres sections que nous n&#039;avions pas demandées !&lt;br /&gt;
Certes, nous n&#039;avons pas de variables, et l&#039;éditeur de lien n&#039;ayant rien à mettre dans notre section &amp;quot;.data&amp;quot;, il ne l&#039;a pas créée, mais au final nous sommes relativement loin de ce que nous voulions.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc demander à l&#039;éditeur de liens de générer un petit peu moins de choses en ajoutant l&#039;option &#039;&#039;-Wl,--build-id=none&#039;&#039; à nos directives de compilation (variable LDFLAGS de notre Makefile), ce qui nous donne un binaire moitié plus petit mais toujours trop gros.&lt;br /&gt;
&lt;br /&gt;
=== Un binaire vraiment binaire ===&lt;br /&gt;
Mais nous ne pouvons pas en demander bien plus à l&#039;éditeur de liens, dont le travail est de créer des exécutables au format ELF.&lt;br /&gt;
Pour créer d&#039;autres types de binaire, nous devrons utiliser l&#039;utilitaire &#039;&#039;objcopy&#039;&#039; (toujours la version ARM, donc en fait &#039;&#039;arm-linux-gnueabi-objcopy&#039;&#039;).&lt;br /&gt;
Le travail de cet utilitaire est de créer des binaires à partir des exécutables ELF, en ne conservant que les sections qui nous intéressent (du moins, c&#039;est l&#039;usage que nous en ferons).&lt;br /&gt;
&lt;br /&gt;
Nous allons demander à cet utilitaire de nous générer une image binaire à partir du résultat de notre compilation en ajoutant dans notre Makefile une cible &amp;quot;$(NAME).bin&amp;quot; qui deviendra notre cible par défaut et dépendra de la génération du fichier au format ELF :&lt;br /&gt;
&lt;br /&gt;
 all: $(NAME).bin&lt;br /&gt;
 &lt;br /&gt;
 $(NAME).bin: $(NAME)&lt;br /&gt;
 	$(CROSS_COMPILE)objcopy -O binary $^ $@&lt;br /&gt;
&lt;br /&gt;
Et notre objectif est enfin atteint, avec un binaire de ... 36 octets !&amp;lt;br /&amp;gt;&lt;br /&gt;
Rappelez vous, je n&#039;ai mis que 5 entrées dans ma table de vecteurs, soit 20 octets, suivis de quelques fonctions vides. Tout va bien.&lt;br /&gt;
&lt;br /&gt;
== Un programme un peu plus utile ==&lt;br /&gt;
&lt;br /&gt;
Nous allons désormais pouvoir nous occuper d&#039;allumer nos Leds, en quelque sorte le &amp;quot;Hello world&amp;quot; de l&#039;électronique.&lt;br /&gt;
&lt;br /&gt;
=== Entrées et sorties ===&lt;br /&gt;
Du point de vue de notre micro-contrôleur, allumer ou éteindre une Led revient à changer l&#039;état de la sortie correspondante.&lt;br /&gt;
&lt;br /&gt;
Les entrées/sorties du microcontrôleur peuvent avoir plusieurs fonctions, mais hormis quelques exceptions elles sont par défaut configurées en entrées/sorties (GPIO (general Purpose Input Output) en anglais) avec la résistance de pull-up interne activée. Pour simplifier, nous laisserons donc cette étape de la configuration de côté pour l&#039;instant, et reviendrons dessus lorsque nous attaquerons la programmation d&#039;interfaces plus complexes.&lt;br /&gt;
&lt;br /&gt;
: Note : Les exceptions sont les GPIO 13, 25 et 26 du port 0 (respectivement Reset, SWDIO et SWDCLK), qui permettent le reset et le debug, ainsi que quatre GPIO sur lesquelles la fonction &amp;quot;0&amp;quot; est réservée : les GPIO 30 et 31 du port 0 et les GPIO 0 et 1 du port 1.&lt;br /&gt;
&lt;br /&gt;
=== Les registres ===&lt;br /&gt;
Pour changer l&#039;état d&#039;une de ces entrées/sorties, il faut commencer par la configurer en sortie, puis définir sont état.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, il est important de comprendre que le processeur de notre micro-contrôleur ne voit que de la mémoire autour de lui. Il n&#039;a pas accès directement aux signaux électriques.&lt;br /&gt;
Pour accéder aux fonctions spéciales comme l&#039;état électrique d&#039;une sortie le processeur doit donc modifier des données dans une zone mémoire spécifique, dédiée à cette sortie, que l&#039;on appelle un registre.&lt;br /&gt;
&lt;br /&gt;
Notre micro-contrôleur dispose d&#039;un grand nombre de registres qui ont tous une taille de 32 bits, même si souvent certains bits ne sont pas utilisés (ils sont alors &amp;quot;réservés&amp;quot;).&lt;br /&gt;
Ces registres particuliers, qui nous donnent accès aux fonctions spéciales du micro-contrôleur, comme la configuration et l&#039;état des entrées sorties, sont accessibles chacun à une adresse fixe dans l&#039;espace d&#039;adressage du micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Nous avons déjà eu besoin d&#039;informations sur cet espace d&#039;adressage lorsque nous avons cherché des informations sur le démarrage du micro-contrôleur, il se trouve représenté sur la figure 2 dans la section &amp;quot;2.3 Memory allocation&amp;quot; du chapitre 2 (LPC122x Memory map).&lt;br /&gt;
&lt;br /&gt;
L&#039;adresse qui nous intéresse dépend du port sur lequel les leds sont connectées.&lt;br /&gt;
La led bicolore étant connectée sur le port 1 ce sont les registres présents à l&#039;adresse 0x50010000 que nous devrons utiliser.&lt;br /&gt;
Cette adresse est aussi rappelée avec la description des registres dans le chapitre 8 (LPC122x General Purpose I/O (GPIO))&lt;br /&gt;
&lt;br /&gt;
À partir de cette adresse se trouvent une série de registres permettant de contrôler les entrées/sorties du port 1. La modification du contenu de la mémoire accessible ainsi modifiera donc le comportement des entrées/sorties correspondantes ou leur état lorsqu&#039;elles sont configurées en sortie.&lt;br /&gt;
&lt;br /&gt;
Très (trop) souvent, pour accéder à ces registres, les programmeurs utilisent des définitions selon le principe suivant:&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 #define PORT1_MASK  (LPC_GPIO_1_BASE + 0x00)&lt;br /&gt;
 #define PORT1_PIN   (LPC_GPIO_1_BASE + 0x04)&lt;br /&gt;
 #define PORT1_OUT   (LPC_GPIO_1_BASE + 0x08)&lt;br /&gt;
 /* [.....] */&lt;br /&gt;
Personnellement je trouve cette façon de faire très inefficace, et peu lisible (voire complètement illisible), et je préfère l&#039;utilisation de structures.&lt;br /&gt;
Cela me semble beaucoup plus lisible, plus adapté pour accéder à de la mémoire qui est structurée, et apporte aussi un très net avantage lorsqu&#039;il existe plusieurs ensembles de registres utilisant la même organisation, par exemple quand il y a plusieurs liaisons séries sur le micro-contrôleur, ou dans le cas qui nous intéresse pour l&#039;instant, plusieurs ports d&#039;entrées/sorties.&lt;br /&gt;
La définition se passe alors ainsi :&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_0_BASE  (LPC_AHB_BASE + 0x00000)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 /* General Purpose Input/Output (GPIO) */&lt;br /&gt;
 struct lpc_gpio&lt;br /&gt;
 {&lt;br /&gt;
    volatile uint32_t mask;       /* 0x00 : Pin mask, affects data, out, set, clear and invert */&lt;br /&gt;
    volatile uint32_t in;         /* 0x04 : Port data Register (R/-) */&lt;br /&gt;
    volatile uint32_t out;        /* 0x08 : Port output Register (R/W) */&lt;br /&gt;
    volatile uint32_t set;        /* 0x0C : Port output set Register (-/W) */&lt;br /&gt;
    volatile uint32_t clear;      /* 0x10 : Port output clear Register (-/W) */&lt;br /&gt;
    volatile uint32_t toggle;     /* 0x14 : Port output invert Register (-/W) */&lt;br /&gt;
    uint32_t reserved[2];&lt;br /&gt;
    volatile uint32_t data_dir;   /* 0x20 : Data direction Register (R/W) */&lt;br /&gt;
    /* [.....] */&lt;br /&gt;
 };&lt;br /&gt;
 #define LPC_GPIO_0      ((struct lpc_gpio *) LPC_GPIO_0_BASE)&lt;br /&gt;
 #define LPC_GPIO_1      ((struct lpc_gpio *) LPC_GPIO_1_BASE)&lt;br /&gt;
À noter, l&#039;utilisation du mot clé &amp;quot;volatile&amp;quot; qui interdira au compilateur d&#039;optimiser les accès à ces registres en gardant des copies intermédiaires, forçant la lecture ou l&#039;écriture immédiate.&lt;br /&gt;
&lt;br /&gt;
Cette notation nous donne aussi l&#039;information de la taille des données présentes à ces adresses, dans ce cas là, des valeurs sur 32 bits.&lt;br /&gt;
&lt;br /&gt;
Pour l&#039;utilisation dans le code, c&#039;est ensuite très simple, il suffit de déclarer un pointeur vers cette structure, puis d&#039;accéder au champ qui nous intéresse :&lt;br /&gt;
 struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
 gpio1-&amp;gt;out = 0;&lt;br /&gt;
&lt;br /&gt;
=== Allumer les leds ===&lt;br /&gt;
&lt;br /&gt;
Reste à déterminer quels sont les champs qui nous intéressent et quelles valeurs nous devons écrire dedans.&lt;br /&gt;
Pour configurer les pins reliées à nos Leds en sortie nous devons modifier le registre &amp;quot;DIR&amp;quot; (appelé &amp;quot;data_dir&amp;quot; dans la structure), et mettre les bits 4 et 5 à &amp;quot;1&amp;quot; puisque chaque bit de ce registre permet de configurer une des pins du port correspondant, le bit 0 pour la pin 0, le bit 1 pour la pin 1, et ainsi de suite (attention, ici les numéros de pins ne sont pas les numéros des pattes du composant).&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc modifier notre main() pour obtenir le code suivant qui réalise cette opération de façon lisible, et positionne la Led verte à l&#039;état &amp;quot;allumée&amp;quot;, sans modifier l&#039;état des autres sorties du port 1 :&lt;br /&gt;
 /* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */&lt;br /&gt;
 #define LED_RED    5&lt;br /&gt;
 #define LED_GREEN  4&lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
    /* Micro-controller init */&lt;br /&gt;
    system_init();&lt;br /&gt;
    /* Configure the Status Led pins */&lt;br /&gt;
    gpio1-&amp;gt;data_dir |= (1 &amp;lt;&amp;lt; LED_GREEN) | (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    /* Turn Green Led ON */&lt;br /&gt;
    gpio1-&amp;gt;set = (1 &amp;lt;&amp;lt; LED_GREEN);&lt;br /&gt;
    gpio1-&amp;gt;clear = (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    while (1) {&lt;br /&gt;
        /* Change the led state */&lt;br /&gt;
        /* Wait some time */&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[Encart : Décalages de bits] :&lt;br /&gt;
: La notation &amp;quot;&amp;lt;&amp;lt;&amp;quot; correspond à l&#039;opérateur logique &amp;quot;décalage de bits vers la gauche&amp;quot; (&amp;quot;&amp;gt;&amp;gt;&amp;quot; pour le décalage à droite). Voir l&#039;article wikipedia sur le sujet, en Anglais, la version Française étant catastrophiquement incomplète [9].&lt;br /&gt;
&lt;br /&gt;
== Mettre le code sur le micro-contrôleur : lpctools ==&lt;br /&gt;
&lt;br /&gt;
Je sais que vous êtes de plus en plus impatients et que vous voulez voir le résultat de tout ceci en vrai, nous allons donc passer à la mise en flash sur le micro-contrôleur pour tester tout cela.&lt;br /&gt;
&lt;br /&gt;
Je ne traiterais ici que le cas de la version 48 broches du micro-contrôleur LPC1224 (package LQFP48). A vous d&#039;adapter si vous utilisez un autre micro-contrôleur, le principe étant très similaire pour tous les LPC de NXP. Pour les autres gammes de micro-contrôleurs, référez vous à leurs docs techniques et aux informations sur Internet.&lt;br /&gt;
&lt;br /&gt;
=== Connexion ===&lt;br /&gt;
Si vous avez mis l&#039;adaptateur USB-UART sur votre module comme proposé dans les articles précédents, l&#039;étape de connexion au PC est simple, connectez votre module sur un port USB, directement ou via un câble en fonction du connecteur USB que vous avez choisi.&lt;br /&gt;
&lt;br /&gt;
Sinon, il vous faudra un adaptateur USB-UART (souvent vendus comme adaptateurs USB-série) fonctionnant en 3.3V, et relier les signaux Rx et Tx aux signaux TXD0 et RXD0 correspondant à l&#039;UART 0 du micro-contrôleur LPC1224 qui se trouvent sur le port 0, pins 1 et 2 (broches 16 et 17 du composant). Il est alors préférable d&#039;avoir rendu ces signaux accesssibles sur un connecteur de votre choix, sans quoi il vous faudra souder des fils directement sur les pattes du micro-contrôleur ... possible, mais pas conseillé du tout).&lt;br /&gt;
&lt;br /&gt;
=== Mode ISP ===&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite mettre le micro-contrôleur en mode programmation (ISP : &amp;quot;In System Programming&amp;quot; en anglais). Le chapitre 20 (LPC122x Flash ISP/IAP) indique qu&#039;il faut maintenir la pin 12 du port 0 (broche 27) à l&#039;état bas (0V) pendant au moins 3ms après avoir relaché le signal &amp;quot;Reset&amp;quot; (pin 13 du port 0, broche 28). La suite du chapitre décrit le protocole de programmation, uniquement utile si vous voulez créer votre propre utilitaire pour programmer le micro-contrôleur, ou si vous voulez réaliser des opérations très spécifiques.&lt;br /&gt;
&lt;br /&gt;
Puisque nous avons placé des boutons poussoir reliant ces signaux à la masse, avec des résistance de &amp;quot;pull-up&amp;quot;, cette opération est très simple : il faut appuyer sur les deux boutons en même temps, puis relacher le bouton reset avant de relacher le bouton ISP.&lt;br /&gt;
Lorsque tout c&#039;est bien passé, la led bicolore doit avoir deux petits points lumineux à peine visibles dans l&#039;obscurité (un rouge et un vert).&lt;br /&gt;
&lt;br /&gt;
=== Dialogue avec le micro-contrôleur ===&lt;br /&gt;
&lt;br /&gt;
La suite se passe sur le PC. Le paquet lpctools contient deux binaires : lpcisp et lpcprog.&lt;br /&gt;
Le premier donne accès aux opérations élémentaires du protocole de programmation, et ne nous sera pas utile. Le second permet de programmer le micro-contrôleur en utilisant une unique commande, bien que d&#039;autres commandes permettent d&#039;effectuer quelques opérations intéressantes.&lt;br /&gt;
&lt;br /&gt;
Nous allons d&#039;ailleurs commencer par une de ces autres opération : demander les identifiants de notre micro-contrôleur avec la commande &amp;quot;id&amp;quot;.&lt;br /&gt;
La syntaxe des commandes lpcprog est simple, il suffit de lui passer un nom de device, que l&#039;on passe comme argument de l&#039;option &amp;quot;-d&amp;quot;, une commande (argument de l&#039;option &amp;quot;-c&amp;quot;), et si besoin le nom du fichier à utiliser.&lt;br /&gt;
Dans l&#039;exemple suivant le module GPIO-Démo est identifié sur le poste de développement comme périphérique &amp;quot;ttyUSB0&amp;quot;, nous utiliserons donc le &#039;&#039;device&#039;&#039; &amp;quot;/dev/ttyUSB0&amp;quot;.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c id&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Part ID is 0x3640c02b&lt;br /&gt;
 UID: 0x2c0cf5f5 - 0x4b32430e - 0x02333834 - 0x4d7c501a&lt;br /&gt;
 Boot code version is 6.1&lt;br /&gt;
La première ligne nous indique que lpcprog a reconnu le micro-contrôleur et qu&#039;il sera donc possible de le programmer. (Si ce n&#039;est pas le cas, vous devrez compléter le fichier de description des micro-contrôleurs).&lt;br /&gt;
Ensuite, lpcprog nous donne les informations propres au micro-contrôleur, à savoir son identifiant unique et la version du &amp;quot;boot code&amp;quot; qui se trouve en rom sur le micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Si vous avez un affichage similaire, tout va bien.&lt;br /&gt;
Sinon, vérifiez la connexion et que le micro-contrôleur est bien en mode ISP.&lt;br /&gt;
&lt;br /&gt;
La programmation se fait ensuite très simplement avec la commande &amp;quot;flash&amp;quot;, en ajoutant le nom du fichier binaire à envoyer.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c flash mod_gpio.bin&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Flash now all blank.&lt;br /&gt;
 Checksum check OK&lt;br /&gt;
 Flash size : 32768, trying to flash 1 blocks of 1024 bytes : 1024&lt;br /&gt;
 Writing started, 1 blocks of 1024 bytes ...&lt;br /&gt;
lpcprog se charge d&#039;effacer la flash, de générer la somme de contrôle de l&#039;entête et de la placer au bon endroit dans le binaire, et d&#039;envoyer le tout au micro-contrôleur pour mise en flash.&lt;br /&gt;
&lt;br /&gt;
Pour tester, il suffit d&#039;appuyer sur le bouton Reset, et de constater qu&#039;il ne se passe rien, ce qui n&#039;est pas ce que nous attendions.&lt;br /&gt;
&lt;br /&gt;
Il y a plusieurs problèmes.&lt;br /&gt;
&lt;br /&gt;
=== Votre code s&#039;il vous plait ! ===&lt;br /&gt;
&lt;br /&gt;
Le premier vient de la génération de la somme de contrôle, ou plutôt de sa position dans notre binaire.&lt;br /&gt;
Tous les LPC de NXP utilisent (à ce jour de ce que j&#039;ai pu voir) le même mécanisme pour déterminer si la flash contient une image valide avant d&#039;essayer d&#039;exécuter son contenu : la vérification du checksum des 8 premiers vecteurs d&#039;interruption, qui doit être nulle.&lt;br /&gt;
&lt;br /&gt;
Pour que ceci soit possible, conformément à la documentation technique des micro-contrôleurs, lpcprog calcule le complément à 2 des 7 premiers vecteurs, et le place dans le huitième.&lt;br /&gt;
&lt;br /&gt;
Sauf que notre tableau ne fait pour l&#039;instant que 5 &amp;quot;cases&amp;quot; et que la huitième case contenait en fait notre code exécutable, qui a été écrasé.&lt;br /&gt;
&lt;br /&gt;
La première modification est donc de remplir au moins 8 cases de ce tableau, au pire avec des valeurs nulles, sinon, avec des valeurs correspondant à ce qui est attendu dans la documentation : les adresses des routines de gestion, ou au moins celle de notre routine &amp;quot;de remplacement&amp;quot; (Dummy_Handler()) lorsque la documentation indique que l&#039;emplacement est utilisé (table 363 et figure 68 pour les exceptions, et table 4 pour les interruption).&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    0, /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
    NMI_Handler,&lt;br /&gt;
    HardFault_Handler,&lt;br /&gt;
    0,&lt;br /&gt;
    0, /* 5 */&lt;br /&gt;
    0,&lt;br /&gt;
    /* Entry 7 (8th entry) must contain the 2’s complement of the check-sum&lt;br /&gt;
       of table entries 0 through 6. This causes the checksum of the first 8&lt;br /&gt;
       table entries to be 0 */&lt;br /&gt;
    (void *)0xDEADBEEF, /* Actually, this is done using an external tool. */&lt;br /&gt;
    0,&lt;br /&gt;
    /* [.....] voir le code du module GPIO-Demo pour la suite */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Cependant ceci n&#039;est pas suffisant (vous pouvez désormais le tester très simplement, je vous laisse faire).&lt;br /&gt;
&lt;br /&gt;
=== Un peu de place pour la pile ===&lt;br /&gt;
&lt;br /&gt;
Le dernier point un petit peu particulier est encore sur cette fameuse table des vecteurs, et concerne la première entrée.&lt;br /&gt;
Si vous regardez attentivement la figure 68, le vecteur &amp;quot;Reset&amp;quot; n&#039;est que la deuxième entrée de la table.&lt;br /&gt;
La première est la valeur initiale du pointeur de la pile (Stack pointer), qui correspond en fait à son sommet puisque cette pile est remplie en faisant décroître les adresses (cette information se trouve dans le chapitre 25, mais cette fois je vous laisse chercher un petit peu).&lt;br /&gt;
&lt;br /&gt;
Nous avons initialisé cette valeur à 0, ce qui forcément pose un soucis.&lt;br /&gt;
&lt;br /&gt;
Pour obtenir la bonne valeur, nous pourrions coder en dur l&#039;adresse du haut de notre sram, mais ce n&#039;est pas propre.&lt;br /&gt;
Pour que tout soit fait correctement et automatiquement, nous allons modifier le script de l&#039;édition de liens, et demander à &#039;&#039;&#039;ld&#039;&#039;&#039; de remplir cette adresse à notre place, en fonction de l&#039;adresse de la sram et de sa taille.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc créer des variables dans notre script, juste après la définition de la mémoire disponible, et chose très importante, ces variables seront des variables externes utilisables dans notre code C !&lt;br /&gt;
: _sram_size = LENGTH(sram);&lt;br /&gt;
: _sram_base = ORIGIN(sram);&lt;br /&gt;
: _end_stack = (_sram_base + _sram_size);&lt;br /&gt;
Nous appelons le bas de la pile (la &amp;quot;fin&amp;quot; de la pile) &#039;&#039;&#039;_end_stack&#039;&#039;&#039;, et plaçons cette fin de pile tout en haut de la mémoire vive.&lt;br /&gt;
&lt;br /&gt;
Et pour l&#039;utilisation dans notre code C, tout simplement :&lt;br /&gt;
 extern unsigned int _end_stack;&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    &amp;amp;_end_stack, /* Initial SP value */ /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Si vous compilez votre code avec ces modifications, vous obtenez enfin un binaire qui allume la Led !&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Nous avons enfin notre &amp;quot;Hello World !&amp;quot; version électronique, mais la route est encore longue.&lt;br /&gt;
&lt;br /&gt;
Vous pourrez voir dans le prochain article que cette première étape n&#039;était qu&#039;une étape, et qu&#039;il reste encore plusieurs étapes importantes avant de pouvoir vraiment commencer à écrire du code &amp;quot;fonctionnel&amp;quot;, comme la gestion du &amp;quot;watchdog&amp;quot;, la configuration de l&#039;horloge interne, l&#039;initialisation de la mémoire, et l&#039;écriture des drivers pour chaque bloc fonctionnel (liaison série, I2C, SPI, ADC, ....).&lt;br /&gt;
&lt;br /&gt;
Rendez-vous donc pour le second article dédié à la programmation de notre micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Merci pour votre lecture attentive !&lt;br /&gt;
&lt;br /&gt;
== Les fichiers créés ==&lt;br /&gt;
Vous trouverez sur notre serveur le [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/Makefile Makefile], le fichier C [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/main.c main.c], et le script de lien [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/lpc_link_lpc1224.ld lpc_link_lpc1224.ld]&lt;br /&gt;
&lt;br /&gt;
== Liens - Bibliographie ==&lt;br /&gt;
* [1] https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Option-Summary.html&lt;br /&gt;
* [2] https://sourceware.org/binutils/docs/binutils/objdump.html&lt;br /&gt;
* [3] https://sourceware.org/binutils/docs/binutils/readelf.html&lt;br /&gt;
* [4] Page du module et Manuel utilisateur : http://www.techno-innov.fr/technique-module-gpio-demo/ - http://techdata.techno-innov.fr/Modules/GPIO_Demo/System_Reference_Manual_Module_GPIO_Demo_v03.pdf&lt;br /&gt;
* [5] Dépôt GIT lpctools : http://git.techno-innov.fr/?p=lpctools&lt;br /&gt;
* [6] Lien vers d&#039;autres outils pour programmer les LPC :&lt;br /&gt;
** mxli : http://www.windscooting.com/softy/mxli.html&lt;br /&gt;
** lpc21isp : http://sourceforge.net/projects/lpc21isp/&lt;br /&gt;
** nxpprog : http://sourceforge.net/projects/nxpprog/&lt;br /&gt;
** GLPC (GUI pour lpc21isp) : http://sourceforge.net/projects/glpc/&lt;br /&gt;
* [7] Manuel utilisateur du LPC1224 : http://www.nxp.com/documents/user_manual/UM10441.pdf&lt;br /&gt;
* [8] http://fr.wikipedia.org/wiki/Segment_BSS&lt;br /&gt;
* [9] http://en.wikipedia.org/wiki/Bitwise_operation&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=108</id>
		<title>Articles/Nathael/Domotab et elec Libre partie5</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=108"/>
		<updated>2020-09-02T21:16:03Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Tisser des liens, c&amp;#039;est important */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Électronique et domotique libre - partie 5 : Programmation, Premiers signes de vie}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; margin-right: 2.5em;&amp;quot;&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DomoTab.png|200px|right]]&lt;br /&gt;
Programmation du module !&lt;br /&gt;
&lt;br /&gt;
Nous avons vu dans le quatrième article comment fabriquer le module GPIO-Démo (ou toute version modifiée), nous allons désormais nous atteler à lui donner vie.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1&#039;&#039;&#039; : La programmation sera faite en C, bien que d&#039;autres langages puissent être utilisés, à la seule condition qu&#039;il existe un compilateur qui puisse générer du code binaire pour ARM à partir de ce langage.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2&#039;&#039;&#039; : Les tailles indiquées dans cet article dépendent de la version de GCC utilisé, et il est presque certain que vous obtiendrez des tailles différentes. Si il y a de trop gros écarts, c&#039;est que vous avez fait une erreur, par exemple un cas que j&#039;ai eu fréquement en TP : l&#039;oubli du &amp;quot;AT &amp;gt;flash&amp;quot; pour le bloc de données placé en RAM, à l&#039;adresse 0x10000000, soit 256Mo ... et produit un binaire de ... 256Mo :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;par Nathael Pajani&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:right&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
Paru dans le [http://boutique.ed-diamond.com/home/851-open-silicium-14.html numéro 14] du magazine Open Silicium.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Les documentations techniques ==&lt;br /&gt;
&lt;br /&gt;
La première étape lorsqu&#039;on veut écrire du code pour un système embarqué qui utilise un micro-contrôleur, c&#039;est d&#039;en trouver la documentation technique.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès aux documentations techniques est à mon avis un des critères principaux dans le choix des composants pour un projet, aussi bien pour les concepteurs que pour les utilisateurs.&lt;br /&gt;
&lt;br /&gt;
Si vous avez réalisé la conception du circuit, vous aurez normalement déjà eu besoin de ces documentations, dans le cas contraire, c&#039;est le moment de les récupérer.&lt;br /&gt;
Pour le module GPIO-Démo, il y a plusieurs documentations techniques nécessaires pour utiliser la totalité des fonctionnalités du module.&lt;br /&gt;
La première et la plus importante est celle du micro-contrôleur [7], mais vous aurez aussi besoin de celle du module, disponible sur le site de Techno-Innov [4], et de celles de l&#039;EEPROM I2C, et du capteur de température I2C.&lt;br /&gt;
&lt;br /&gt;
Encart : Pour ce qui est du bridge USB-UART, la documentation n&#039;est pas nécessaire pour la programmation du micro-contrôleur et du module, mais elle le devient si vous voulez modifier la façon dont le composant s&#039;identifie lorsque vous le connectez, par exemple pour pouvoir lui donner un nom spécifique ou simplifier l&#039;identification. Cela ne sera cependant pas le sujet de cet article.&lt;br /&gt;
&lt;br /&gt;
Pour récupérer les documentations techniques, vous avez le choix entre le site du fabriquant et celui du distributeur chez qui vous avec acheté les composants. Pour la majorité des composants j&#039;utilise le site du distributeur (possible uniquement si il fourni les bonnes documentations), mais pour les micro-contrôleurs je consulte le site du fabriquant car il fourni aussi les &amp;quot;errata&amp;quot; (notes d&#039;informations contenant les corrections sur la documentation) et le plus souvent des notes d&#039;application qui indiquent comment utiliser le composant pour telle ou telle application (avec parfois des exemples de code).&lt;br /&gt;
&lt;br /&gt;
== Outils de programmation ==&lt;br /&gt;
&lt;br /&gt;
La deuxième étape ne concerne toujours pas le code que vous voulez écrire.&lt;br /&gt;
&lt;br /&gt;
En effet, pour écrire du code vous n&#039;avez pas besoin de la &amp;quot;cible&amp;quot; (target en anglais) qui est le matériel sur lequel vous allez exécuter la version compilée du code, mais uniquement d&#039;un poste de développement, couramment appelé hôte (host en anglais).&lt;br /&gt;
&lt;br /&gt;
Cependant, la cible en question n&#039;a que faire des fichiers sources qui se trouvent sur votre poste de développement, et il vous faudra un certain nombre d&#039;outils pour passer des fichiers source (quelque soit le langage) au code exécutable par votre carte électronique.&lt;br /&gt;
&lt;br /&gt;
C&#039;est aussi un point très important à mon sens dans le choix d&#039;un système embarqué ou d&#039;un micro-contrôleur : quels sont les outils dont j&#039;aurais besoin pour passer de mon code source à un système fonctionnant avec ?&lt;br /&gt;
&lt;br /&gt;
Dans le cas des micro-contrôleurs de la gamme LPC de NXP il existe de nombreuses solutions pour passer de l&#039;un à l&#039;autre, mais ce qui est intéressant à mon sens c&#039;est qu&#039;il est possible de le faire avec un minimum de matériel et de logiciel : une liaison série &amp;quot;TTL 3.3V&amp;quot;, une chaîne de compilation croisée et un utilitaire pour &amp;quot;uploader&amp;quot; le code binaire.&lt;br /&gt;
&lt;br /&gt;
=== Matériel : un port USB (et le PC qui va avec) ===&lt;br /&gt;
&lt;br /&gt;
[[Image:14-Module sur USB.png|300px|right]]&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la liaison série &amp;quot;TTL 3.3V&amp;quot;, il existe plein d&#039;adaptateurs USB-UART fonctionnant en 3.3V, et pour le cas du module GPIO-Démo cet adaptateur est intégré sur le module, un port USB suffit donc.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès à cette liaison série se fera via un fichier spécial dont le nom sera devrait ressembler à &amp;quot;/dev/ttyUSB0&amp;quot;, le &amp;quot;USB0&amp;quot; pouvant différer selon votre système (&amp;quot;USB1&amp;quot;, USB2&amp;quot;, ... ou même &amp;quot;ACM0&amp;quot; avec d&#039;autres adaptateurs).&lt;br /&gt;
&lt;br /&gt;
=== Compilation : GNU ===&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la chaîne de compilation croisée, les micro-contrôleurs LPC de NXP utilisent des cœurs ARM Cortex-M*, très bien supportés par gcc, bien connu de tous les lecteurs de ce magazine (du moins je le pense), et parfaitement adapté à la cross-compilation.&lt;br /&gt;
&lt;br /&gt;
Dit comme ça, c&#039;est simple ... mais en fait, pas tant que ça.&lt;br /&gt;
Cette problématique pourrait faire l&#039;objet d&#039;un (petit ?) article, je ne l&#039;inclurai donc pas ici, je vous donne juste quelques pistes et suppose que vous saurez trouver les informations sur le net. De mon côté je dois les intégrer à la documentation technique du module GPIO-Démo, mais ce n&#039;est pas encore fait à l&#039;heure où j&#039;écris ces lignes :( [4].&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;avez pas déjà une chaîne de cross-compilation installée pour ARM vous avez globalement trois solutions : Debian/EmDebian (celle que j&#039;utilise), Launchpad, et Crosstools-ng.&lt;br /&gt;
&lt;br /&gt;
Le projet EmDebian fournit des paquets debian pour différentes chaînes de cross-compilation (ARM parmi tant d&#039;autres), qui sont entrain d&#039;être intégrées à Debian. Cela devrait simplifier les problèmes de dépôts et de dépendances dont souffrait les dépôts EmDebian, même si seule la version &amp;quot;arm-none-eabi&amp;quot; (qui nous suffit, nous n&#039;avons pas besoin de libC) est actuellement intégrée dans SID sans problèmes de dépendances (j&#039;ai bien dit &amp;quot;devrait&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Le site de Launchpad fourni aussi des versions binaires de la chaîne de cross-compilation GCC ARM.&lt;br /&gt;
&lt;br /&gt;
La solution CrossTools-ng : recompilation de sa propre chaîne de compilation croisée : la solution du dernier recours, si votre distribution ne fournit pas de solution packagée et que les versions binaires non signées ne vous conviennent pas.&lt;br /&gt;
&lt;br /&gt;
=== Programmation : lpctools (ou autre) ===&lt;br /&gt;
&lt;br /&gt;
Enfin, pour ce qui est de l&#039;utilitaire permettant de charger (uploader) le code binaire sur le micro-contrôleur (flasher le micro-contrôleur), je n&#039;avais pas trouvé d&#039;outil libre permettant de réaliser cette étape au moment où j&#039;ai étudié la possibilité d&#039;utiliser les micro-contrôleurs de NXP, mais le protocole série permettant de réaliser cette opération était documenté dans la documentation technique des micro-contrôleurs, il ne devait donc pas y avoir de problème de ce côté là.&lt;br /&gt;
&lt;br /&gt;
La seule solution &amp;quot;gratuite&amp;quot; que j&#039;avais trouvé à l&#039;époque ne fonctionnait que sur un seul système (pas le miens), ne fournissait pas ses sources, et interdisait une utilisation commerciale sans payer une licence, hors je voulais justement en faire une utilisation commerciale.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai donc pris quelques heures de mon temps pour coder un utilitaire permettant de programmer les micro-contrôleurs LPC, et placé le tout sous licence GPL v3 [5].&lt;br /&gt;
Le tout est désormais disponible sur le site de Techno-Innov, et est intégré depuis peu à la distribution Debian GNU/Linux (Sid et Jessie à l&#039;heure de l&#039;écriture de ces lignes).&lt;br /&gt;
&lt;br /&gt;
J&#039;ai entre-temps découvert d&#039;autres projets permettant de programmer des micro-contrôleurs LPC, mais je ne les ai pas testés (nxpprog - licence MIT, mxli - GPLv3, pyLPCTools - GPLv2) et constaté qu&#039;un autre paquet Debian fournit les outils permetant de programmer les micro-contrôleurs LPC de NXP : lpc21isp (qui dispose d&#039;ailleurs d&#039;une interface graphique : GLPC, qui elle n&#039;est pas dans les dépôts). Voir liens [6] en fin d&#039;article.&lt;br /&gt;
&lt;br /&gt;
== Makefile - particularités pour la compilation croisée ==&lt;br /&gt;
&lt;br /&gt;
Une dernière petite étape avant d&#039;écrire notre code, bien que l&#039;on se rapproche de la programmation, puisqu&#039;il s&#039;agit d&#039;un élément essentiel de tout projet : la création du Makefile.&lt;br /&gt;
&lt;br /&gt;
Dans le cas de la compilation pour une cible comme le module GPIO-Démo le Makefile doit inclure quelques éléments supplémentaires que l&#039;on ne retrouve habituellement pas dans un Makefile classique.&lt;br /&gt;
&lt;br /&gt;
Le premier élément concerne la définition du compilateur à utiliser. Nous utiliserons la variable &amp;quot;CROSS_COMPILE&amp;quot; à laquelle nous affecterons une valeur par défaut correspondant au préfixe du compilateur. Si vous voulez utiliser un compilateur correctement installé sur le système, il suffit d&#039;utiliser le préfixe, sinon, il faudra ajouter devant la totalité du chemin donnant accès au compilateur.&lt;br /&gt;
&lt;br /&gt;
Par exemple pour le compilateur EmDebian :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
ou avec un chemin complet pour un autre compilateur :&lt;br /&gt;
: CROSS_COMPILE ?= /usr/local/mon/compilateur/bin/arm-none-eabi-&lt;br /&gt;
&lt;br /&gt;
Le &amp;quot;?=&amp;quot; permet de ne modifier la variable que si elle n&#039;existe pas, notamment si elle n&#039;est pas déjà présente dans la ligne de commande.&lt;br /&gt;
&lt;br /&gt;
Cette variable est ensuite utilisée pour modifier la variable &amp;quot;CC&amp;quot; utilisée par &amp;quot;make&amp;quot; pour compiler les fichiers de code source C. Si vous utilisez un autre langage, modifiez la variable correspondante.&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
Il est aussi possible d&#039;en profiter pour spécifier une version du compilateur installé :&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc-4.7&lt;br /&gt;
Nous allons en profiter pour définir la variable &amp;quot;LD&amp;quot; qui correspond à l&#039;éditeur de liens (linker en anglais) :&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
&lt;br /&gt;
Il nous faut ensuite définir la cible pour laquelle nous voulons compiler. Dans notre cas il s&#039;agit d&#039;un cœur ARM Cortex-M0, qui utilise le jeu d&#039;instructions &amp;quot;thumb&amp;quot; (instructions sur 16bits permettant d&#039;obtenir un code plus compact), nous allons donc utiliser les options -mcpu et -mthumb de gcc pour lui indiquer notre besoin :&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: CFLAGS = -Wall -mthumb -mcpu=$(CPU)&lt;br /&gt;
&lt;br /&gt;
En plus de cela, nous allons demander au compilateur de ne pas reconnaître les fonctions pour lesquelles il a une définition interne (builtin) tout simplement parce que la majorité de ces fonctions dépendent d&#039;un environnement très différent de celui de notre micro-contrôleur, soit par la présence d&#039;une bibliothèque C, d&#039;un système d&#039;exploitation respectant la norme POSIX, ou d&#039;une unité de calcul flottant.&lt;br /&gt;
Rien de tout ceci n&#039;est vrai dans notre cas, et il est donc préférable que le compilateur nous informe si nous tentons d&#039;utiliser ces fonctions sans l&#039;avoir explicitement demandé en utilisant le préfixe &amp;quot;__builtin__&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous demanderons aussi au compilateur de bien placer les données et les fonctions dans leurs sections respectives. Malgré ce que dit la documentation de GCC, cela permet (au moins dans notre cas) de produire un binaire plus petit. Cela se fait à l&#039;aide des directives d&#039;optimisation &amp;quot;-ffunction-sections&amp;quot; et &amp;quot;-fdata-sections&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous ajouterons ces directives dans une variable dédiée :&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Nous obtenons donc les lignes suivantes à ajouter à votre Makefile :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
: CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
&lt;br /&gt;
Notre Makefile ressemblerait alors à ceci :&lt;br /&gt;
 NAME = mod_gpio&lt;br /&gt;
 CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
 CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
 LD = $(CROSS_COMPILE)ld&lt;br /&gt;
 CPU = cortex-m0&lt;br /&gt;
 FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
 CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
 &lt;br /&gt;
 .PHONY: all&lt;br /&gt;
 all: $(NAME)&lt;br /&gt;
 &lt;br /&gt;
 SRC = $(wildcard *.c)&lt;br /&gt;
 OBJS = $(SRC:.c=.o)&lt;br /&gt;
 &lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ -o $@&lt;br /&gt;
Ce Makefile est encore incomplet et ne permet pas d&#039;obtenir le binaire pour notre micro-contrôleur, mais nous ajouterons les parties manquantes plus tard.&lt;br /&gt;
&lt;br /&gt;
En attendant, ce Makefile nous permettra de compiler le code que nous allons écrire, passons donc aux parties intéressantes, et le reste du Makefile sera bien plus simple à comprendre.&lt;br /&gt;
&lt;br /&gt;
== Commençons simple ==&lt;br /&gt;
&lt;br /&gt;
Pour ne pas trop compliquer les choses dès le début, nous allons tenter de faire clignoter la led bicolore présente sur le module GPIO-Démo.&lt;br /&gt;
&lt;br /&gt;
Notre squelette de code ressemblera à s&#039;y méprendre à ce que l&#039;on pourrait avoir pour un programme plus commun :&lt;br /&gt;
 /*&lt;br /&gt;
  * Notre exemple simple pour Open Silicium&lt;br /&gt;
  */&lt;br /&gt;
 void system_init(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* System init ? */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* Micro-controller init */&lt;br /&gt;
 	system_init();&lt;br /&gt;
 	&lt;br /&gt;
 	while (1) {&lt;br /&gt;
 		/* Change the led state */&lt;br /&gt;
 		/* Wait some time */&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 }&lt;br /&gt;
Si vous compilez ce petit morceau de code avec notre Makefile, vous obtiendrez un binaire qui globalement ne fait rien, mais a déjà une taille de 5.7 Ko.&lt;br /&gt;
C&#039;est gros pour ne rien faire, d&#039;autant que la mémoire Flash de notre micro-contrôleur ne fait que 32 Ko.&lt;br /&gt;
&lt;br /&gt;
Si on regarde plus loin, par exemple avec l&#039;utilitaire &#039;&#039;file&#039;&#039;, on obtient quelques informations supplémentaires :&lt;br /&gt;
 $ file mod_gpio&lt;br /&gt;
 mod_gpio: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), [....], not stripped&lt;br /&gt;
&lt;br /&gt;
Arghhh, notre binaire est un exécutable dynamique au format ELF, qui utilise des bibliothèques partagées !&lt;br /&gt;
&lt;br /&gt;
Nous l&#039;avons déjà évoqué, notre micro-contrôleur n&#039;a pas de libC ni de système d&#039;exploitation, notre binaire ne peut donc pas être dynamique (lié dynamiquement à des bibliothèques) !&lt;br /&gt;
Il nous faut donc faire l&#039;édition de lien en &amp;quot;static&amp;quot;, en apportant quelques modification à notre Makefile. Nous allons introduire une variable &amp;quot;LDFLAGS&amp;quot;, que l&#039;on ajoutera à la règle de compilation utilisée pour l&#039;édition de liens.&lt;br /&gt;
 LDFLAGS = -static&lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ $(LDFLAGS) -o $@&lt;br /&gt;
Recompilons notre projet ... 608 Ko !!! Re-Argh !&lt;br /&gt;
&lt;br /&gt;
Visiblement quelqu&#039;un ajoute du code dont nous n&#039;avons pas besoin. Il faut du moins l&#039;espérer, sinon il ne sera jamais possible de faire rentrer un programme dans la flash de notre micro-contrôleur, qui fait toujours 32Ko.&lt;br /&gt;
&lt;br /&gt;
L&#039;option &amp;quot;static&amp;quot; demande à l&#039;éditeur de lien de créer un binaire statique, mais résultat il nous ajoute tout ce qui est utile de la libC pour un exécutable ... pour un système Linux.&lt;br /&gt;
D&#039;ailleurs, &#039;&#039;file&#039;&#039; nous dit bien que notre exécutable est au format ELF.&lt;br /&gt;
&lt;br /&gt;
Pour commencer nous allons demander à l&#039;éditeur de liens (ld) de ne pas inclure les éléments de démarrage dans notre binaire, car ils sont inutiles sur notre micro-contrôleur. Pour cela nous ajoutons l&#039;option &amp;quot;-nostartfiles&amp;quot; à nos directives pour l&#039;édition de liens.&lt;br /&gt;
&lt;br /&gt;
Et hop, une recompilation plus tard, notre binaire ne fait plus que 1 Ko :)&lt;br /&gt;
Mais pour &#039;&#039;file&#039;&#039;, ce binaire est toujours au format ELF, et gcc nous informe qu&#039;il n&#039;a pas trouvé de symbole d&#039;entrée &amp;quot;_start&amp;quot; et qu&#039;il utilise une adresse par défaut (nous l&#039;avons cherché, cela fait partie de ce que nous avons demandé à l&#039;éditeur de liens en ajoutant l&#039;option &amp;quot;-nostartfiles&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
En effet, le &amp;quot;main&amp;quot; de nos programmes en C n&#039;est que le point de départ de l&#039;exécution de notre code, mais pas celui du programme. Il est précédé par un certain nombre de routines (fonctions) d&#039;initialisation, dont le point d&#039;entrée est la routine &amp;quot;_start&amp;quot;, qui appellera le main &amp;quot;classique&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Mais notre but n&#039;est pas de créer un exécutable pour un système Linux, nous devons créer un binaire pour notre micro-contrôleur. Il est désormais temps de nous plonger dans la documentation du micro-contrôleur pour comprendre comment il démarre, pour pouvoir adapter notre code au démarrage du micro-contrôleur et fournir l&#039;équivalent de cette routine &amp;quot;_start&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bootstrap == &lt;br /&gt;
&lt;br /&gt;
=== Table des vecteurs d&#039;interruption ===&lt;br /&gt;
&lt;br /&gt;
Pour avoir des informations sur le démarrage du micro-contrôleur LPC1224 dans sa documentation technique [7] il y a deux chapitres intéressants.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons nous référer au chapitre 4 (LPC122x System control) qui inclut une section sur le reset du micro-contrôleur (4.6 : Reset), dans laquelle on apprend qu&#039;une fois que la condition de reset disparait et que les procédures internes se sont exécutées, le processeur commence l&#039;exécution à l&#039;adresse contenue dans le vecteur &amp;quot;Reset&amp;quot; du &amp;quot;boot block&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous avons ainsi quelques informations, mais qu&#039;est-ce que le vecteur &amp;quot;Reset&amp;quot; et le &amp;quot;boot block&amp;quot; ? Cela nous mène au deuxième chapitre intéressant, le chapitre 25 sur le cœur ARM Cortex-M0. On y trouve une section sur le processeur (25.3 : Processor) avec une sous section concernant les exeptions (25.3.3 : Exception model). &lt;br /&gt;
&lt;br /&gt;
Dans les informations sur les exceptions (25.3.3.2), et plus particulièrement l&#039;exception &amp;quot;Reset&amp;quot;, il est indiqué qu&#039;après un &amp;quot;Reset&amp;quot; l&#039;exécution reprend à l&#039;adresse indiquée dans le vecteur &amp;quot;Reset&amp;quot; dans la table des vecteurs d&#039;interruption.&lt;br /&gt;
&lt;br /&gt;
Bien, cela confirme ce qui se trouvait dans le chapitre 4. Mais cette fois, nous avons une sous-section &amp;quot;25.3.3.4 Vector table&amp;quot;, qui décrit cette fameuse table des vecteurs d&#039;exception, précisant qu&#039;elle contient l&#039;addresse de toutes les routines de gestion des exceptions (les fameux &amp;quot;vecteurs&amp;quot; d&#039;exception, dont le vecteur &amp;quot;Reset&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Remarquez au passage que les interruptions sont gérées de la même façon, l&#039;addresse d&#039;entrée des routines de gestion des interruptions se trouve dans cette même table.&lt;br /&gt;
&lt;br /&gt;
Et en dessous de cette table, nous avons une autre information très intéressante : &amp;quot;The vector table is fixed at address 0x00000000&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Si l&#039;on se réfère à la table 65 de la section &amp;quot;25.3.2 Memory model&amp;quot;, et à la figure 2 de la section &amp;quot;2.3 Memory allocation&amp;quot;, on découvre que cette adresse est en fait le début de la mémoire flash du micro-contrôleur, qui devra contenir notre code binaire.&lt;br /&gt;
&lt;br /&gt;
Reste à créer cette table, et à la placer au bon endroit dans le code binaire compilé...&lt;br /&gt;
&lt;br /&gt;
=== Les &amp;quot;handlers&amp;quot; et les &amp;quot;dummy handlers&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
Nous allons commencer par la partie code.&lt;br /&gt;
Ce code peut être placé dans le même fichier que celui ou ce trouve notre fonction main, ou dans un autre fichier, cela n&#039;a pas d&#039;importance. Si vous vous référez au code du module GPIO-Démo disponible dans les dépôts git de Techno-Innov, vous trouverez ce code dans le fichier &amp;quot;core/bootstrap.c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Vecteurs_interruption.png|350px|right]]&lt;br /&gt;
&lt;br /&gt;
 /* Cortex M0 core interrupt handlers */&lt;br /&gt;
 void Reset_Handler(void);&lt;br /&gt;
 void NMI_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 void HardFault_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void);&lt;br /&gt;
 &lt;br /&gt;
 void *vector_table[] = {&lt;br /&gt;
 	0,&lt;br /&gt;
 	Reset_Handler,&lt;br /&gt;
 	NMI_Handler,&lt;br /&gt;
 	HardFault_Handler,&lt;br /&gt;
 	0,&lt;br /&gt;
 	/* [......] */&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void) {&lt;br /&gt;
     while (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Voici un petit morceau de code relativement court qui définit notre table de vecteur ainsi que les routines de gestion correspondantes.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, faisons un petit point sur certains éléments : les attributs utilisés pour la déclaration de deux de nos routines de gestion des exceptions : &amp;quot;__attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ces attributs permettent de définir un alias &amp;quot;faible&amp;quot; pour une fonction, ce qui veut dire que si le compilateur ne trouve pas de définition pour cette fonction, il pourra utiliser son alias, que nous avons défini plus bas. Au contraire, si dans un autre fichier (ou celui-ci) vous définissez l&#039;une de ces fonctions, c&#039;est votre définition qui sera utilisée.&lt;br /&gt;
&lt;br /&gt;
Note : je n&#039;ai pas mis la totalité de la table des vecteurs, cela n&#039;a pas d&#039;intérêt pour les explications, et notre programme fonctionnera sans, mais il faudrait la compléter pour un vrai programme, en faisant attention à l&#039;ordre, à partir des informations de la figure 68 déjà évoquée, et de la table 4 du chapitre 3 concernant le gestionnaire d&#039;interruptions (vous noterez la typo, il s&#039;agit des numéros d&#039;IRQ et non pas des numéros des vecteurs d&#039;exception).&lt;br /&gt;
&lt;br /&gt;
=== Appeler notre main() ===&lt;br /&gt;
Ce petit bout de code compile donc, puisque tout est défini, mais nous avons toujours l&#039;avertissement concernant le symbole d&#039;entrée &amp;quot;_start&amp;quot; qui n&#039;a pas été trouvé. Nous ne sommes pas plus avancé.&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, nous avons déjà indiqué que le point d&#039;entrée de notre code est la fonction main() (qui pourrait avoir n&#039;importe quel nom), mais pour notre micro-controlleur la fonction d&#039;entrée du programme est la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
La solution pour faire le lien est toute simple : il suffit d&#039;appeler la fonction main() depuis la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
 int main(void);&lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 	main();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Tisser des liens, c&#039;est important ===&lt;br /&gt;
Cela ne résout cependant aucun de nos problèmes, nous allons donc devoir donner plus d&#039;indications à l&#039;éditeur de liens, en créant un script pour l&#039;édition de lien (lpc_link_lpc1224.ld). Nous donnerons le nom de ce script à l&#039;éditeur de liens en utilisant l&#039;otion &amp;quot;-T&#039;&#039;lpc_link_lpc1224.ld&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ce script d&#039;édition de lien (&amp;quot;linker script&amp;quot; en anglais) est en fait un fichier qui décrit la mémoire de notre micro-contrôleur, ainsi que l&#039;organisation que devra respecter notre binaire.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc commencer, toujours à partir des mêmes informations en provenance de la documentation technique, par définir quelle est la mémoire disponible, aussi bien la mémoire &amp;quot;vive&amp;quot; (SRAM) que la mémoire &amp;quot;morte&amp;quot; (FLASH).&lt;br /&gt;
&lt;br /&gt;
 MEMORY&lt;br /&gt;
 {&lt;br /&gt;
 	sram (rwx) : ORIGIN = 0x10000000, LENGTH = 4k&lt;br /&gt;
 	flash (rx) : ORIGIN = 0x00000000, LENGTH = 32k&lt;br /&gt;
 }&lt;br /&gt;
Nous définissons ainsi l&#039;adresse et la taille (et les droits d&#039;accès) de la sram et de la flash, qui deviennent deux blocs de mémoire disponibles pour l&#039;éditeur de liens, qui pourra donc y placer du code et des données.&lt;br /&gt;
&lt;br /&gt;
Il nous faut maintenant expliquer à l&#039;éditeur de liens comment organiser le code et les données dans ces blocs de mémoire, et tout particulièrement notre tableau de vecteurs d&#039;interruptions&lt;br /&gt;
&lt;br /&gt;
Le code d&#039;un programme est composé de &amp;quot;sections&amp;quot;, dans lesquelles le compilateur place chaque fonction et chaque variable en fonction de différents critères, que l&#039;on peut contrôler soit à partir de directives de compilation, soit d&#039;attributs ajoutés dans notre code C&lt;br /&gt;
&lt;br /&gt;
Nous allons donc modifier notre tableau de vecteurs d&#039;interruptions pour lui ajouter un attribut &amp;quot;section&amp;quot; qui forcera l&#039;éditeur de liens à le placer dans la section que nous avons défini.&lt;br /&gt;
: void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
&lt;br /&gt;
Et en parallèle, nous allons définir dans notre script quelles sont les sections que nous voulons trouver dans notre binaire, et dans quel ordre.&lt;br /&gt;
Commençons simple (si si, je vous assure), nous compliquerons plus tard :&lt;br /&gt;
 SECTIONS {&lt;br /&gt;
 	. = ORIGIN(flash);&lt;br /&gt;
 	.text :&lt;br /&gt;
 	{&lt;br /&gt;
 		KEEP(*(.vectors))&lt;br /&gt;
 		*(.text*)&lt;br /&gt;
 		*(.rodata*)&lt;br /&gt;
 	} &amp;gt;flash&lt;br /&gt;
 	.data :&lt;br /&gt;
 	{&lt;br /&gt;
 		*(.data*)&lt;br /&gt;
 		*(.bss*)&lt;br /&gt;
 	} &amp;gt;sram AT &amp;gt;flash&lt;br /&gt;
 }&lt;br /&gt;
Pour commencer, nous définissons l&#039;adresse courante (.) comme étant l&#039;origine de du bloc de mémoire &amp;quot;flash&amp;quot; (le bloc de mémoire défini précédemment et auquel nous avons donné ce nom, bien qu&#039;un autre nom aurait pu faire l&#039;affaire).&lt;br /&gt;
Ceci est important pour que l&#039;éditeur de liens puisse définir les adresses des fonctions pour l&#039;exécution de notre code.&lt;br /&gt;
À partir de ce point nous définissons une section &amp;quot;text&amp;quot;, dans laquelle nous allons demander à l&#039;éditeur de lien de mettre plusieurs éléments, à commencer par notre fameuse table de vecteurs, en lui interdisant d&#039;en changer la position !&lt;br /&gt;
Après quoi, nous lui demandons de placer l&#039;ensemble du code, que le compilateur a placé dans des section &amp;quot;.text.*&amp;quot;, puis les données en lecture seule (Read-Only data = rodata), et de placer le tout dans le bloc de mémoire &amp;quot;flash&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
À la suite, nous créons une section &amp;quot;data&amp;quot;, dans laquelle nous lui demandons de placer les données initialisées à des valeurs non nulles (data), puis les données initialement nulles (bss [8]), et de placer cette section en RAM.&lt;br /&gt;
&lt;br /&gt;
Ne reste plus qu&#039;une information à donner à l&#039;éditeur de liens (pour l&#039;instant): le point d&#039;entrée de notre programme.&lt;br /&gt;
Ceci est relativement simple et explicite :&lt;br /&gt;
: ENTRY(Reset_Handler)&lt;br /&gt;
&lt;br /&gt;
Dans notre Makefile la variable LDFLAGS devient :&lt;br /&gt;
: LDFLAGS = -static -nostartfiles -Tlpc_link_lpc1224.ld&lt;br /&gt;
&lt;br /&gt;
Une compilation plus tard, sans avertissements cette fois, nous avons un binaire ... beaucoup trop gros : notre binaire fait maintenant plus de 66 Ko !&lt;br /&gt;
&lt;br /&gt;
Soyons un peu curieux et allons donc voir ce qu&#039;il contient, mais pas à la main, rassurez vous, utilisons un utilitaire fait exprès pour cela : &#039;&#039;objdump&#039;&#039;. attention, il faut bien entendu utiliser la version &amp;quot;ARM&amp;quot; de objdump, donc avec le préfixe &amp;quot;CROSS_COMPILE&amp;quot;, soit dans mon cas &#039;&#039;arm-linux-gnueabi-objdump&#039;&#039;, avec l&#039;option &#039;&#039;--disassemble-all&#039;&#039; (-D) :&lt;br /&gt;
: arm-linux-gnueabi-objdump -D mod_gpio &amp;gt; dump&lt;br /&gt;
Et là, surprise, la version &amp;quot;désassemblée&amp;quot; de notre binaire est plus petite que la version binaire (le fichier &amp;quot;dump&amp;quot; fait 2.2 Ko).&lt;br /&gt;
&lt;br /&gt;
Regardons tout de même son contenu.&lt;br /&gt;
La première ligne nous informe que le format du fichier est &amp;quot;elf32-littlearm&amp;quot; ... pas grand chose à voir avec ce que nous voulions, un &amp;quot;simple&amp;quot; binaire (Notre micro-contrôleur n&#039;a toujours pas appris à lire les exécutables au format ELF). Premier problème.&lt;br /&gt;
&lt;br /&gt;
Quelqu&#039;un est venu glisser une section &amp;quot;.note.gnu.build-id&amp;quot; avant notre section &amp;quot;.text&amp;quot;, que l&#039;éditeur de liens aimerait placer en début de RAM (&amp;quot;10000000 &amp;lt;_sram_base&amp;gt;&amp;quot;), ce qui n&#039;a pas d&#039;intérêt pour nous.&lt;br /&gt;
&lt;br /&gt;
S&#039;en suit tout de même notre section &amp;quot;.text&amp;quot;, qui commence bien par notre table (enfin ! on nous écoute un peu !), suivie de nos quelques maigres fonctions. Notez les adresses des fonctions dans la table des vecteurs, qui sont toutes impaires. Ceci indique que notre processeur exécutera ces fonctions en mode &amp;quot;thumb&amp;quot; qui est bien le mode que nous avions demandé (-mthumb).&lt;br /&gt;
&lt;br /&gt;
Et encore une fois, notre section &amp;quot;.text&amp;quot; n&#039;est pas suivie de nos données, mais d&#039;autres sections que nous n&#039;avions pas demandées !&lt;br /&gt;
Certes, nous n&#039;avons pas de variables, et l&#039;éditeur de lien n&#039;ayant rien à mettre dans notre section &amp;quot;.data&amp;quot;, il ne l&#039;a pas créée, mais au final nous sommes relativement loin de ce que nous voulions.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc demander à l&#039;éditeur de liens de générer un petit peu moins de choses en ajoutant l&#039;option &#039;&#039;-Wl,--build-id=none&#039;&#039; à nos directives de compilation (variable LDFLAGS de notre Makefile), ce qui nous donne un binaire moitié plus petit mais toujours trop gros.&lt;br /&gt;
&lt;br /&gt;
=== Un binaire vraiment binaire ===&lt;br /&gt;
Mais nous ne pouvons pas en demander bien plus à l&#039;éditeur de liens, dont le travail est de créer des exécutables au format ELF.&lt;br /&gt;
Pour créer d&#039;autres types de binaire, nous devrons utiliser l&#039;utilitaire &#039;&#039;objcopy&#039;&#039; (toujours la version ARM, donc en fait &#039;&#039;arm-linux-gnueabi-objcopy&#039;&#039;).&lt;br /&gt;
Le travail de cet utilitaire est de créer des binaires à partir des exécutables ELF, en ne conservant que les sections qui nous intéressent (du moins, c&#039;est l&#039;usage que nous en ferons).&lt;br /&gt;
&lt;br /&gt;
Nous allons demander à cet utilitaire de nous générer une image binaire à partir du résultat de notre compilation en ajoutant dans notre Makefile une cible &amp;quot;$(NAME).bin&amp;quot; qui deviendra notre cible par défaut et dépendra de la génération du fichier au format ELF :&lt;br /&gt;
&lt;br /&gt;
 all: $(NAME).bin&lt;br /&gt;
 &lt;br /&gt;
 $(NAME).bin: $(NAME)&lt;br /&gt;
 	$(CROSS_COMPILE)objcopy -O binary $^ $@&lt;br /&gt;
&lt;br /&gt;
Et notre objectif est enfin atteint, avec un binaire de ... 36 octets !&amp;lt;br /&amp;gt;&lt;br /&gt;
Rappelez vous, je n&#039;ai mis que 5 entrées dans ma table de vecteurs, soit 20 octets, suivis de quelques fonctions vides. Tout va bien.&lt;br /&gt;
&lt;br /&gt;
== Un programme un peu plus utile ==&lt;br /&gt;
&lt;br /&gt;
Nous allons désormais pouvoir nous occuper d&#039;allumer nos Leds, en quelque sorte le &amp;quot;Hello world&amp;quot; de l&#039;électronique.&lt;br /&gt;
&lt;br /&gt;
=== Entrées et sorties ===&lt;br /&gt;
Du point de vue de notre micro-contrôleur, allumer ou éteindre une Led revient à changer l&#039;état de la sortie correspondante.&lt;br /&gt;
&lt;br /&gt;
Les entrées/sorties du microcontrôleur peuvent avoir plusieurs fonctions, mais hormis quelques exceptions elles sont par défaut configurées en entrées/sorties (GPIO (general Purpose Input Output) en anglais) avec la résistance de pull-up interne activée. Pour simplifier, nous laisserons donc cette étape de la configuration de côté pour l&#039;instant, et reviendrons dessus lorsque nous attaquerons la programmation d&#039;interfaces plus complexes.&lt;br /&gt;
&lt;br /&gt;
: Note : Les exceptions sont les GPIO 13, 25 et 26 du port 0 (respectivement Reset, SWDIO et SWDCLK), qui permettent le reset et le debug, ainsi que quatre GPIO sur lesquelles la fonction &amp;quot;0&amp;quot; est réservée : les GPIO 30 et 31 du port 0 et les GPIO 0 et 1 du port 1.&lt;br /&gt;
&lt;br /&gt;
=== Les registres ===&lt;br /&gt;
Pour changer l&#039;état d&#039;une de ces entrées/sorties, il faut commencer par la configurer en sortie, puis définir sont état.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, il est important de comprendre que le processeur de notre micro-contrôleur ne voit que de la mémoire autour de lui. Il n&#039;a pas accès directement aux signaux électriques.&lt;br /&gt;
Pour accéder aux fonctions spéciales comme l&#039;état électrique d&#039;une sortie le processeur doit donc modifier des données dans une zone mémoire spécifique, dédiée à cette sortie, que l&#039;on appelle un registre.&lt;br /&gt;
&lt;br /&gt;
Notre micro-contrôleur dispose d&#039;un grand nombre de registres qui ont tous une taille de 32 bits, même si souvent certains bits ne sont pas utilisés (ils sont alors &amp;quot;réservés&amp;quot;).&lt;br /&gt;
Ces registres particuliers, qui nous donnent accès aux fonctions spéciales du micro-contrôleur, comme la configuration et l&#039;état des entrées sorties, sont accessibles chacun à une adresse fixe dans l&#039;espace d&#039;adressage du micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Nous avons déjà eu besoin d&#039;informations sur cet espace d&#039;adressage lorsque nous avons cherché des informations sur le démarrage du micro-contrôleur, il se trouve représenté sur la figure 2 dans la section &amp;quot;2.3 Memory allocation&amp;quot; du chapitre 2 (LPC122x Memory map).&lt;br /&gt;
&lt;br /&gt;
L&#039;adresse qui nous intéresse dépend du port sur lequel les leds sont connectées.&lt;br /&gt;
La led bicolore étant connectée sur le port 1 ce sont les registres présents à l&#039;adresse 0x50010000 que nous devrons utiliser.&lt;br /&gt;
Cette adresse est aussi rappelée avec la description des registres dans le chapitre 8 (LPC122x General Purpose I/O (GPIO))&lt;br /&gt;
&lt;br /&gt;
À partir de cette adresse se trouvent une série de registres permettant de contrôler les entrées/sorties du port 1. La modification du contenu de la mémoire accessible ainsi modifiera donc le comportement des entrées/sorties correspondantes ou leur état lorsqu&#039;elles sont configurées en sortie.&lt;br /&gt;
&lt;br /&gt;
Très (trop) souvent, pour accéder à ces registres, les programmeurs utilisent des définitions selon le principe suivant:&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 #define PORT1_MASK  (LPC_GPIO_1_BASE + 0x00)&lt;br /&gt;
 #define PORT1_PIN   (LPC_GPIO_1_BASE + 0x04)&lt;br /&gt;
 #define PORT1_OUT   (LPC_GPIO_1_BASE + 0x08)&lt;br /&gt;
 /* [.....] */&lt;br /&gt;
Personnellement je trouve cette façon de faire très inefficace, et peu lisible (voire complètement illisible), et je préfère l&#039;utilisation de structures.&lt;br /&gt;
Cela me semble beaucoup plus lisible, plus adapté pour accéder à de la mémoire qui est structurée, et apporte aussi un très net avantage lorsqu&#039;il existe plusieurs ensembles de registres utilisant la même organisation, par exemple quand il y a plusieurs liaisons séries sur le micro-contrôleur, ou dans le cas qui nous intéresse pour l&#039;instant, plusieurs ports d&#039;entrées/sorties.&lt;br /&gt;
La définition se passe alors ainsi :&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_0_BASE  (LPC_AHB_BASE + 0x00000)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 /* General Purpose Input/Output (GPIO) */&lt;br /&gt;
 struct lpc_gpio&lt;br /&gt;
 {&lt;br /&gt;
    volatile uint32_t mask;       /* 0x00 : Pin mask, affects data, out, set, clear and invert */&lt;br /&gt;
    volatile uint32_t in;         /* 0x04 : Port data Register (R/-) */&lt;br /&gt;
    volatile uint32_t out;        /* 0x08 : Port output Register (R/W) */&lt;br /&gt;
    volatile uint32_t set;        /* 0x0C : Port output set Register (-/W) */&lt;br /&gt;
    volatile uint32_t clear;      /* 0x10 : Port output clear Register (-/W) */&lt;br /&gt;
    volatile uint32_t toggle;     /* 0x14 : Port output invert Register (-/W) */&lt;br /&gt;
    uint32_t reserved[2];&lt;br /&gt;
    volatile uint32_t data_dir;   /* 0x20 : Data direction Register (R/W) */&lt;br /&gt;
    /* [.....] */&lt;br /&gt;
 };&lt;br /&gt;
 #define LPC_GPIO_0      ((struct lpc_gpio *) LPC_GPIO_0_BASE)&lt;br /&gt;
 #define LPC_GPIO_1      ((struct lpc_gpio *) LPC_GPIO_1_BASE)&lt;br /&gt;
À noter, l&#039;utilisation du mot clé &amp;quot;volatile&amp;quot; qui interdira au compilateur d&#039;optimiser les accès à ces registres en gardant des copies intermédiaires, forçant la lecture ou l&#039;écriture immédiate.&lt;br /&gt;
&lt;br /&gt;
Cette notation nous donne aussi l&#039;information de la taille des données présentes à ces adresses, dans ce cas là, des valeurs sur 32 bits.&lt;br /&gt;
&lt;br /&gt;
Pour l&#039;utilisation dans le code, c&#039;est ensuite très simple, il suffit de déclarer un pointeur vers cette structure, puis d&#039;accéder au champ qui nous intéresse :&lt;br /&gt;
 struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
 gpio1-&amp;gt;out = 0;&lt;br /&gt;
&lt;br /&gt;
=== Allumer les leds ===&lt;br /&gt;
&lt;br /&gt;
Reste à déterminer quels sont les champs qui nous intéressent et quelles valeurs nous devons écrire dedans.&lt;br /&gt;
Pour configurer les pins reliées à nos Leds en sortie nous devons modifier le registre &amp;quot;DIR&amp;quot; (appelé &amp;quot;data_dir&amp;quot; dans la structure), et mettre les bits 4 et 5 à &amp;quot;1&amp;quot; puisque chaque bit de ce registre permet de configurer une des pins du port correspondant, le bit 0 pour la pin 0, le bit 1 pour la pin 1, et ainsi de suite (attention, ici les numéros de pins ne sont pas les numéros des pattes du composant).&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc modifier notre main() pour obtenir le code suivant qui réalise cette opération de façon lisible, et positionne la Led verte à l&#039;état &amp;quot;allumée&amp;quot;, sans modifier l&#039;état des autres sorties du port 1 :&lt;br /&gt;
 /* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */&lt;br /&gt;
 #define LED_RED    5&lt;br /&gt;
 #define LED_GREEN  4&lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
    /* Micro-controller init */&lt;br /&gt;
    system_init();&lt;br /&gt;
    /* Configure the Status Led pins */&lt;br /&gt;
    gpio1-&amp;gt;data_dir |= (1 &amp;lt;&amp;lt; LED_GREEN) | (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    /* Turn Green Led ON */&lt;br /&gt;
    gpio1-&amp;gt;set = (1 &amp;lt;&amp;lt; LED_GREEN);&lt;br /&gt;
    gpio1-&amp;gt;clear = (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    while (1) {&lt;br /&gt;
        /* Change the led state */&lt;br /&gt;
        /* Wait some time */&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[Encart : Décalages de bits] :&lt;br /&gt;
: La notation &amp;quot;&amp;lt;&amp;lt;&amp;quot; correspond à l&#039;opérateur logique &amp;quot;décalage de bits vers la gauche&amp;quot; (&amp;quot;&amp;gt;&amp;gt;&amp;quot; pour le décalage à droite). Voir l&#039;article wikipedia sur le sujet, en Anglais, la version Française étant catastrophiquement incomplète [9].&lt;br /&gt;
&lt;br /&gt;
== Mettre le code sur le micro-contrôleur : lpctools ==&lt;br /&gt;
&lt;br /&gt;
Je sais que vous êtes de plus en plus impatients et que vous voulez voir le résultat de tout ceci en vrai, nous allons donc passer à la mise en flash sur le micro-contrôleur pour tester tout cela.&lt;br /&gt;
&lt;br /&gt;
Je ne traiterais ici que le cas de la version 48 broches du micro-contrôleur LPC1224 (package LQFP48). A vous d&#039;adapter si vous utilisez un autre micro-contrôleur, le principe étant très similaire pour tous les LPC de NXP. Pour les autres gammes de micro-contrôleurs, référez vous à leurs docs techniques et aux informations sur Internet.&lt;br /&gt;
&lt;br /&gt;
=== Connexion ===&lt;br /&gt;
Si vous avez mis l&#039;adaptateur USB-UART sur votre module comme proposé dans les articles précédents, l&#039;étape de connexion au PC est simple, connectez votre module sur un port USB, directement ou via un câble en fonction du connecteur USB que vous avez choisi.&lt;br /&gt;
&lt;br /&gt;
Sinon, il vous faudra un adaptateur USB-UART (souvent vendus comme adaptateurs USB-série) fonctionnant en 3.3V, et relier les signaux Rx et Tx aux signaux TXD0 et RXD0 correspondant à l&#039;UART 0 du micro-contrôleur LPC1224 qui se trouvent sur le port 0, pins 1 et 2 (broches 16 et 17 du composant). Il est alors préférable d&#039;avoir rendu ces signaux accesssibles sur un connecteur de votre choix, sans quoi il vous faudra souder des fils directement sur les pattes du micro-contrôleur ... possible, mais pas conseillé du tout).&lt;br /&gt;
&lt;br /&gt;
=== Mode ISP ===&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite mettre le micro-contrôleur en mode programmation (ISP : &amp;quot;In System Programming&amp;quot; en anglais). Le chapitre 20 (LPC122x Flash ISP/IAP) indique qu&#039;il faut maintenir la pin 12 du port 0 (broche 27) à l&#039;état bas (0V) pendant au moins 3ms après avoir relaché le signal &amp;quot;Reset&amp;quot; (pin 13 du port 0, broche 28). La suite du chapitre décrit le protocole de programmation, uniquement utile si vous voulez créer votre propre utilitaire pour programmer le micro-contrôleur, ou si vous voulez réaliser des opérations très spécifiques.&lt;br /&gt;
&lt;br /&gt;
Puisque nous avons placé des boutons poussoir reliant ces signaux à la masse, avec des résistance de &amp;quot;pull-up&amp;quot;, cette opération est très simple : il faut appuyer sur les deux boutons en même temps, puis relacher le bouton reset avant de relacher le bouton ISP.&lt;br /&gt;
Lorsque tout c&#039;est bien passé, la led bicolore doit avoir deux petits points lumineux à peine visibles dans l&#039;obscurité (un rouge et un vert).&lt;br /&gt;
&lt;br /&gt;
=== Dialogue avec le micro-contrôleur ===&lt;br /&gt;
&lt;br /&gt;
La suite se passe sur le PC. Le paquet lpctools contient deux binaires : lpcisp et lpcprog.&lt;br /&gt;
Le premier donne accès aux opérations élémentaires du protocole de programmation, et ne nous sera pas utile. Le second permet de programmer le micro-contrôleur en utilisant une unique commande, bien que d&#039;autres commandes permettent d&#039;effectuer quelques opérations intéressantes.&lt;br /&gt;
&lt;br /&gt;
Nous allons d&#039;ailleurs commencer par une de ces autres opération : demander les identifiants de notre micro-contrôleur avec la commande &amp;quot;id&amp;quot;.&lt;br /&gt;
La syntaxe des commandes lpcprog est simple, il suffit de lui passer un nom de device, que l&#039;on passe comme argument de l&#039;option &amp;quot;-d&amp;quot;, une commande (argument de l&#039;option &amp;quot;-c&amp;quot;), et si besoin le nom du fichier à utiliser.&lt;br /&gt;
Dans l&#039;exemple suivant le module GPIO-Démo est identifié sur le poste de développement comme périphérique &amp;quot;ttyUSB0&amp;quot;, nous utiliserons donc le &#039;&#039;device&#039;&#039; &amp;quot;/dev/ttyUSB0&amp;quot;.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c id&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Part ID is 0x3640c02b&lt;br /&gt;
 UID: 0x2c0cf5f5 - 0x4b32430e - 0x02333834 - 0x4d7c501a&lt;br /&gt;
 Boot code version is 6.1&lt;br /&gt;
La première ligne nous indique que lpcprog a reconnu le micro-contrôleur et qu&#039;il sera donc possible de le programmer. (Si ce n&#039;est pas le cas, vous devrez compléter le fichier de description des micro-contrôleurs).&lt;br /&gt;
Ensuite, lpcprog nous donne les informations propres au micro-contrôleur, à savoir son identifiant unique et la version du &amp;quot;boot code&amp;quot; qui se trouve en rom sur le micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Si vous avez un affichage similaire, tout va bien.&lt;br /&gt;
Sinon, vérifiez la connexion et que le micro-contrôleur est bien en mode ISP.&lt;br /&gt;
&lt;br /&gt;
La programmation se fait ensuite très simplement avec la commande &amp;quot;flash&amp;quot;, en ajoutant le nom du fichier binaire à envoyer.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c flash mod_gpio.bin&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Flash now all blank.&lt;br /&gt;
 Checksum check OK&lt;br /&gt;
 Flash size : 32768, trying to flash 1 blocks of 1024 bytes : 1024&lt;br /&gt;
 Writing started, 1 blocks of 1024 bytes ...&lt;br /&gt;
lpcprog se charge d&#039;effacer la flash, de générer la somme de contrôle de l&#039;entête et de la placer au bon endroit dans le binaire, et d&#039;envoyer le tout au micro-contrôleur pour mise en flash.&lt;br /&gt;
&lt;br /&gt;
Pour tester, il suffit d&#039;appuyer sur le bouton Reset, et de constater qu&#039;il ne se passe rien, ce qui n&#039;est pas ce que nous attendions.&lt;br /&gt;
&lt;br /&gt;
Il y a plusieurs problèmes.&lt;br /&gt;
&lt;br /&gt;
=== Votre code s&#039;il vous plait ! ===&lt;br /&gt;
&lt;br /&gt;
Le premier vient de la génération de la somme de contrôle, ou plutôt de sa position dans notre binaire.&lt;br /&gt;
Tous les LPC de NXP utilisent (à ce jour de ce que j&#039;ai pu voir) le même mécanisme pour déterminer si la flash contient une image valide avant d&#039;essayer d&#039;exécuter son contenu : la vérification du checksum des 8 premiers vecteurs d&#039;interruption, qui doit être nulle.&lt;br /&gt;
&lt;br /&gt;
Pour que ceci soit possible, conformément à la documentation technique des micro-contrôleurs, lpcprog calcule le complément à 2 des 7 premiers vecteurs, et le place dans le huitième.&lt;br /&gt;
&lt;br /&gt;
Sauf que notre tableau ne fait pour l&#039;instant que 5 &amp;quot;cases&amp;quot; et que la huitième case contenait en fait notre code exécutable, qui a été écrasé.&lt;br /&gt;
&lt;br /&gt;
La première modification est donc de remplir au moins 8 cases de ce tableau, au pire avec des valeurs nulles, sinon, avec des valeurs correspondant à ce qui est attendu dans la documentation : les adresses des routines de gestion, ou au moins celle de notre routine &amp;quot;de remplacement&amp;quot; (Dummy_Handler()) lorsque la documentation indique que l&#039;emplacement est utilisé (table 363 et figure 68 pour les exceptions, et table 4 pour les interruption).&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    0, /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
    NMI_Handler,&lt;br /&gt;
    HardFault_Handler,&lt;br /&gt;
    0,&lt;br /&gt;
    0, /* 5 */&lt;br /&gt;
    0,&lt;br /&gt;
    /* Entry 7 (8th entry) must contain the 2’s complement of the check-sum&lt;br /&gt;
       of table entries 0 through 6. This causes the checksum of the first 8&lt;br /&gt;
       table entries to be 0 */&lt;br /&gt;
    (void *)0xDEADBEEF, /* Actually, this is done using an external tool. */&lt;br /&gt;
    0,&lt;br /&gt;
    /* [.....] voir le code du module GPIO-Demo pour la suite */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Cependant ceci n&#039;est pas suffisant (vous pouvez désormais le tester très simplement, je vous laisse faire).&lt;br /&gt;
&lt;br /&gt;
=== Un peu de place pour la pile ===&lt;br /&gt;
&lt;br /&gt;
Le dernier point un petit peu particulier est encore sur cette fameuse table des vecteurs, et concerne la première entrée.&lt;br /&gt;
Si vous regardez attentivement la figure 68, le vecteur &amp;quot;Reset&amp;quot; n&#039;est que la deuxième entrée de la table.&lt;br /&gt;
La première est la valeur initiale du pointeur de la pile (Stack pointer), qui correspond en fait à son sommet puisque cette pile est remplie en faisant décroître les adresses (cette information se trouve dans le chapitre 25, mais cette fois je vous laisse chercher un petit peu).&lt;br /&gt;
&lt;br /&gt;
Nous avons initialisé cette valeur à 0, ce qui forcément pose un soucis.&lt;br /&gt;
&lt;br /&gt;
Pour obtenir la bonne valeur, nous pourrions coder en dur l&#039;adresse du haut de notre sram, mais ce n&#039;est pas propre.&lt;br /&gt;
Pour que tout soit fait correctement et automatiquement, nous allons modifier le script de l&#039;édition de liens, et demander à &#039;&#039;&#039;ld&#039;&#039;&#039; de remplir cette adresse à notre place, en fonction de l&#039;adresse de la sram et de sa taille.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc créer des variables dans notre script, juste après la définition de la mémoire disponible, et chose très importante, ces variables seront des variables externes utilisables dans notre code C !&lt;br /&gt;
: _sram_size = LENGTH(sram);&lt;br /&gt;
: _sram_base = ORIGIN(sram);&lt;br /&gt;
: _end_stack = (_sram_base + _sram_size);&lt;br /&gt;
Nous appelons le bas de la pile (la &amp;quot;fin&amp;quot; de la pile) &#039;&#039;&#039;_end_stack&#039;&#039;&#039;, et plaçons cette fin de pile tout en haut de la mémoire vive.&lt;br /&gt;
&lt;br /&gt;
Et pour l&#039;utilisation dans notre code C, tout simplement :&lt;br /&gt;
 extern unsigned int _end_stack;&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    &amp;amp;_end_stack, /* Initial SP value */ /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Si vous compilez votre code avec ces modifications, vous obtenez enfin un binaire qui allume la Led !&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Nous avons enfin notre &amp;quot;Hello World !&amp;quot; version électronique, mais la route est encore longue.&lt;br /&gt;
&lt;br /&gt;
Vous pourrez voir dans le prochain article que cette première étape n&#039;était qu&#039;une étape, et qu&#039;il reste encore plusieurs étapes importantes avant de pouvoir vraiment commencer à écrire du code &amp;quot;fonctionnel&amp;quot;, comme la gestion du &amp;quot;watchdog&amp;quot;, la configuration de l&#039;horloge interne, l&#039;initialisation de la mémoire, et l&#039;écriture des drivers pour chaque bloc fonctionnel (liaison série, I2C, SPI, ADC, ....).&lt;br /&gt;
&lt;br /&gt;
Rendez-vous donc pour le second article dédié à la programmation de notre micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Merci pour votre lecture attentive !&lt;br /&gt;
&lt;br /&gt;
== Les fichiers créés ==&lt;br /&gt;
Vous trouverez sur notre serveur le [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/Makefile Makefile], le fichier C [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/main.c main.c], et le script de lien [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/lpc_link_lpc1224.ld lpc_link_lpc1224.ld]&lt;br /&gt;
&lt;br /&gt;
== Liens - Bibliographie ==&lt;br /&gt;
* [1] https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Option-Summary.html&lt;br /&gt;
* [2] https://sourceware.org/binutils/docs/binutils/objdump.html&lt;br /&gt;
* [3] https://sourceware.org/binutils/docs/binutils/readelf.html&lt;br /&gt;
* [4] Page du module et Manuel utilisateur : http://www.techno-innov.fr/technique-module-gpio-demo/ - http://techdata.techno-innov.fr/Modules/GPIO_Demo/System_Reference_Manual_Module_GPIO_Demo_v03.pdf&lt;br /&gt;
* [5] Dépôt GIT lpctools : http://git.techno-innov.fr/?p=lpctools&lt;br /&gt;
* [6] Lien vers d&#039;autres outils pour programmer les LPC :&lt;br /&gt;
** mxli : http://www.windscooting.com/softy/mxli.html&lt;br /&gt;
** lpc21isp : http://sourceforge.net/projects/lpc21isp/&lt;br /&gt;
** nxpprog : http://sourceforge.net/projects/nxpprog/&lt;br /&gt;
** GLPC (GUI pour lpc21isp) : http://sourceforge.net/projects/glpc/&lt;br /&gt;
* [7] Manuel utilisateur du LPC1224 : http://www.nxp.com/documents/user_manual/UM10441.pdf&lt;br /&gt;
* [8] http://fr.wikipedia.org/wiki/Segment_BSS&lt;br /&gt;
* [9] http://en.wikipedia.org/wiki/Bitwise_operation&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=107</id>
		<title>Articles/Nathael/Domotab et elec Libre partie5</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie5&amp;diff=107"/>
		<updated>2020-09-02T21:13:19Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Électronique et domotique libre - partie 5 : Programmation, Premiers signes de vie}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; margin-right: 2.5em;&amp;quot;&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DomoTab.png|200px|right]]&lt;br /&gt;
Programmation du module !&lt;br /&gt;
&lt;br /&gt;
Nous avons vu dans le quatrième article comment fabriquer le module GPIO-Démo (ou toute version modifiée), nous allons désormais nous atteler à lui donner vie.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1&#039;&#039;&#039; : La programmation sera faite en C, bien que d&#039;autres langages puissent être utilisés, à la seule condition qu&#039;il existe un compilateur qui puisse générer du code binaire pour ARM à partir de ce langage.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2&#039;&#039;&#039; : Les tailles indiquées dans cet article dépendent de la version de GCC utilisé, et il est presque certain que vous obtiendrez des tailles différentes. Si il y a de trop gros écarts, c&#039;est que vous avez fait une erreur, par exemple un cas que j&#039;ai eu fréquement en TP : l&#039;oubli du &amp;quot;AT &amp;gt;flash&amp;quot; pour le bloc de données placé en RAM, à l&#039;adresse 0x10000000, soit 256Mo ... et produit un binaire de ... 256Mo :)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;par Nathael Pajani&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:right&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
Paru dans le [http://boutique.ed-diamond.com/home/851-open-silicium-14.html numéro 14] du magazine Open Silicium.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Les documentations techniques ==&lt;br /&gt;
&lt;br /&gt;
La première étape lorsqu&#039;on veut écrire du code pour un système embarqué qui utilise un micro-contrôleur, c&#039;est d&#039;en trouver la documentation technique.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès aux documentations techniques est à mon avis un des critères principaux dans le choix des composants pour un projet, aussi bien pour les concepteurs que pour les utilisateurs.&lt;br /&gt;
&lt;br /&gt;
Si vous avez réalisé la conception du circuit, vous aurez normalement déjà eu besoin de ces documentations, dans le cas contraire, c&#039;est le moment de les récupérer.&lt;br /&gt;
Pour le module GPIO-Démo, il y a plusieurs documentations techniques nécessaires pour utiliser la totalité des fonctionnalités du module.&lt;br /&gt;
La première et la plus importante est celle du micro-contrôleur [7], mais vous aurez aussi besoin de celle du module, disponible sur le site de Techno-Innov [4], et de celles de l&#039;EEPROM I2C, et du capteur de température I2C.&lt;br /&gt;
&lt;br /&gt;
Encart : Pour ce qui est du bridge USB-UART, la documentation n&#039;est pas nécessaire pour la programmation du micro-contrôleur et du module, mais elle le devient si vous voulez modifier la façon dont le composant s&#039;identifie lorsque vous le connectez, par exemple pour pouvoir lui donner un nom spécifique ou simplifier l&#039;identification. Cela ne sera cependant pas le sujet de cet article.&lt;br /&gt;
&lt;br /&gt;
Pour récupérer les documentations techniques, vous avez le choix entre le site du fabriquant et celui du distributeur chez qui vous avec acheté les composants. Pour la majorité des composants j&#039;utilise le site du distributeur (possible uniquement si il fourni les bonnes documentations), mais pour les micro-contrôleurs je consulte le site du fabriquant car il fourni aussi les &amp;quot;errata&amp;quot; (notes d&#039;informations contenant les corrections sur la documentation) et le plus souvent des notes d&#039;application qui indiquent comment utiliser le composant pour telle ou telle application (avec parfois des exemples de code).&lt;br /&gt;
&lt;br /&gt;
== Outils de programmation ==&lt;br /&gt;
&lt;br /&gt;
La deuxième étape ne concerne toujours pas le code que vous voulez écrire.&lt;br /&gt;
&lt;br /&gt;
En effet, pour écrire du code vous n&#039;avez pas besoin de la &amp;quot;cible&amp;quot; (target en anglais) qui est le matériel sur lequel vous allez exécuter la version compilée du code, mais uniquement d&#039;un poste de développement, couramment appelé hôte (host en anglais).&lt;br /&gt;
&lt;br /&gt;
Cependant, la cible en question n&#039;a que faire des fichiers sources qui se trouvent sur votre poste de développement, et il vous faudra un certain nombre d&#039;outils pour passer des fichiers source (quelque soit le langage) au code exécutable par votre carte électronique.&lt;br /&gt;
&lt;br /&gt;
C&#039;est aussi un point très important à mon sens dans le choix d&#039;un système embarqué ou d&#039;un micro-contrôleur : quels sont les outils dont j&#039;aurais besoin pour passer de mon code source à un système fonctionnant avec ?&lt;br /&gt;
&lt;br /&gt;
Dans le cas des micro-contrôleurs de la gamme LPC de NXP il existe de nombreuses solutions pour passer de l&#039;un à l&#039;autre, mais ce qui est intéressant à mon sens c&#039;est qu&#039;il est possible de le faire avec un minimum de matériel et de logiciel : une liaison série &amp;quot;TTL 3.3V&amp;quot;, une chaîne de compilation croisée et un utilitaire pour &amp;quot;uploader&amp;quot; le code binaire.&lt;br /&gt;
&lt;br /&gt;
=== Matériel : un port USB (et le PC qui va avec) ===&lt;br /&gt;
&lt;br /&gt;
[[Image:14-Module sur USB.png|300px|right]]&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la liaison série &amp;quot;TTL 3.3V&amp;quot;, il existe plein d&#039;adaptateurs USB-UART fonctionnant en 3.3V, et pour le cas du module GPIO-Démo cet adaptateur est intégré sur le module, un port USB suffit donc.&lt;br /&gt;
&lt;br /&gt;
L&#039;accès à cette liaison série se fera via un fichier spécial dont le nom sera devrait ressembler à &amp;quot;/dev/ttyUSB0&amp;quot;, le &amp;quot;USB0&amp;quot; pouvant différer selon votre système (&amp;quot;USB1&amp;quot;, USB2&amp;quot;, ... ou même &amp;quot;ACM0&amp;quot; avec d&#039;autres adaptateurs).&lt;br /&gt;
&lt;br /&gt;
=== Compilation : GNU ===&lt;br /&gt;
&lt;br /&gt;
Pour ce qui est de la chaîne de compilation croisée, les micro-contrôleurs LPC de NXP utilisent des cœurs ARM Cortex-M*, très bien supportés par gcc, bien connu de tous les lecteurs de ce magazine (du moins je le pense), et parfaitement adapté à la cross-compilation.&lt;br /&gt;
&lt;br /&gt;
Dit comme ça, c&#039;est simple ... mais en fait, pas tant que ça.&lt;br /&gt;
Cette problématique pourrait faire l&#039;objet d&#039;un (petit ?) article, je ne l&#039;inclurai donc pas ici, je vous donne juste quelques pistes et suppose que vous saurez trouver les informations sur le net. De mon côté je dois les intégrer à la documentation technique du module GPIO-Démo, mais ce n&#039;est pas encore fait à l&#039;heure où j&#039;écris ces lignes :( [4].&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;avez pas déjà une chaîne de cross-compilation installée pour ARM vous avez globalement trois solutions : Debian/EmDebian (celle que j&#039;utilise), Launchpad, et Crosstools-ng.&lt;br /&gt;
&lt;br /&gt;
Le projet EmDebian fournit des paquets debian pour différentes chaînes de cross-compilation (ARM parmi tant d&#039;autres), qui sont entrain d&#039;être intégrées à Debian. Cela devrait simplifier les problèmes de dépôts et de dépendances dont souffrait les dépôts EmDebian, même si seule la version &amp;quot;arm-none-eabi&amp;quot; (qui nous suffit, nous n&#039;avons pas besoin de libC) est actuellement intégrée dans SID sans problèmes de dépendances (j&#039;ai bien dit &amp;quot;devrait&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Le site de Launchpad fourni aussi des versions binaires de la chaîne de cross-compilation GCC ARM.&lt;br /&gt;
&lt;br /&gt;
La solution CrossTools-ng : recompilation de sa propre chaîne de compilation croisée : la solution du dernier recours, si votre distribution ne fournit pas de solution packagée et que les versions binaires non signées ne vous conviennent pas.&lt;br /&gt;
&lt;br /&gt;
=== Programmation : lpctools (ou autre) ===&lt;br /&gt;
&lt;br /&gt;
Enfin, pour ce qui est de l&#039;utilitaire permettant de charger (uploader) le code binaire sur le micro-contrôleur (flasher le micro-contrôleur), je n&#039;avais pas trouvé d&#039;outil libre permettant de réaliser cette étape au moment où j&#039;ai étudié la possibilité d&#039;utiliser les micro-contrôleurs de NXP, mais le protocole série permettant de réaliser cette opération était documenté dans la documentation technique des micro-contrôleurs, il ne devait donc pas y avoir de problème de ce côté là.&lt;br /&gt;
&lt;br /&gt;
La seule solution &amp;quot;gratuite&amp;quot; que j&#039;avais trouvé à l&#039;époque ne fonctionnait que sur un seul système (pas le miens), ne fournissait pas ses sources, et interdisait une utilisation commerciale sans payer une licence, hors je voulais justement en faire une utilisation commerciale.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai donc pris quelques heures de mon temps pour coder un utilitaire permettant de programmer les micro-contrôleurs LPC, et placé le tout sous licence GPL v3 [5].&lt;br /&gt;
Le tout est désormais disponible sur le site de Techno-Innov, et est intégré depuis peu à la distribution Debian GNU/Linux (Sid et Jessie à l&#039;heure de l&#039;écriture de ces lignes).&lt;br /&gt;
&lt;br /&gt;
J&#039;ai entre-temps découvert d&#039;autres projets permettant de programmer des micro-contrôleurs LPC, mais je ne les ai pas testés (nxpprog - licence MIT, mxli - GPLv3, pyLPCTools - GPLv2) et constaté qu&#039;un autre paquet Debian fournit les outils permetant de programmer les micro-contrôleurs LPC de NXP : lpc21isp (qui dispose d&#039;ailleurs d&#039;une interface graphique : GLPC, qui elle n&#039;est pas dans les dépôts). Voir liens [6] en fin d&#039;article.&lt;br /&gt;
&lt;br /&gt;
== Makefile - particularités pour la compilation croisée ==&lt;br /&gt;
&lt;br /&gt;
Une dernière petite étape avant d&#039;écrire notre code, bien que l&#039;on se rapproche de la programmation, puisqu&#039;il s&#039;agit d&#039;un élément essentiel de tout projet : la création du Makefile.&lt;br /&gt;
&lt;br /&gt;
Dans le cas de la compilation pour une cible comme le module GPIO-Démo le Makefile doit inclure quelques éléments supplémentaires que l&#039;on ne retrouve habituellement pas dans un Makefile classique.&lt;br /&gt;
&lt;br /&gt;
Le premier élément concerne la définition du compilateur à utiliser. Nous utiliserons la variable &amp;quot;CROSS_COMPILE&amp;quot; à laquelle nous affecterons une valeur par défaut correspondant au préfixe du compilateur. Si vous voulez utiliser un compilateur correctement installé sur le système, il suffit d&#039;utiliser le préfixe, sinon, il faudra ajouter devant la totalité du chemin donnant accès au compilateur.&lt;br /&gt;
&lt;br /&gt;
Par exemple pour le compilateur EmDebian :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
ou avec un chemin complet pour un autre compilateur :&lt;br /&gt;
: CROSS_COMPILE ?= /usr/local/mon/compilateur/bin/arm-none-eabi-&lt;br /&gt;
&lt;br /&gt;
Le &amp;quot;?=&amp;quot; permet de ne modifier la variable que si elle n&#039;existe pas, notamment si elle n&#039;est pas déjà présente dans la ligne de commande.&lt;br /&gt;
&lt;br /&gt;
Cette variable est ensuite utilisée pour modifier la variable &amp;quot;CC&amp;quot; utilisée par &amp;quot;make&amp;quot; pour compiler les fichiers de code source C. Si vous utilisez un autre langage, modifiez la variable correspondante.&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
Il est aussi possible d&#039;en profiter pour spécifier une version du compilateur installé :&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc-4.7&lt;br /&gt;
Nous allons en profiter pour définir la variable &amp;quot;LD&amp;quot; qui correspond à l&#039;éditeur de liens (linker en anglais) :&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
&lt;br /&gt;
Il nous faut ensuite définir la cible pour laquelle nous voulons compiler. Dans notre cas il s&#039;agit d&#039;un cœur ARM Cortex-M0, qui utilise le jeu d&#039;instructions &amp;quot;thumb&amp;quot; (instructions sur 16bits permettant d&#039;obtenir un code plus compact), nous allons donc utiliser les options -mcpu et -mthumb de gcc pour lui indiquer notre besoin :&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: CFLAGS = -Wall -mthumb -mcpu=$(CPU)&lt;br /&gt;
&lt;br /&gt;
En plus de cela, nous allons demander au compilateur de ne pas reconnaître les fonctions pour lesquelles il a une définition interne (builtin) tout simplement parce que la majorité de ces fonctions dépendent d&#039;un environnement très différent de celui de notre micro-contrôleur, soit par la présence d&#039;une bibliothèque C, d&#039;un système d&#039;exploitation respectant la norme POSIX, ou d&#039;une unité de calcul flottant.&lt;br /&gt;
Rien de tout ceci n&#039;est vrai dans notre cas, et il est donc préférable que le compilateur nous informe si nous tentons d&#039;utiliser ces fonctions sans l&#039;avoir explicitement demandé en utilisant le préfixe &amp;quot;__builtin__&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous demanderons aussi au compilateur de bien placer les données et les fonctions dans leurs sections respectives. Malgré ce que dit la documentation de GCC, cela permet (au moins dans notre cas) de produire un binaire plus petit. Cela se fait à l&#039;aide des directives d&#039;optimisation &amp;quot;-ffunction-sections&amp;quot; et &amp;quot;-fdata-sections&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous ajouterons ces directives dans une variable dédiée :&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
&lt;br /&gt;
Nous obtenons donc les lignes suivantes à ajouter à votre Makefile :&lt;br /&gt;
: CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
: CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
: LD = $(CROSS_COMPILE)ld&lt;br /&gt;
: CPU = cortex-m0&lt;br /&gt;
: FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
: CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
&lt;br /&gt;
Notre Makefile ressemblerait alors à ceci :&lt;br /&gt;
 NAME = mod_gpio&lt;br /&gt;
 CROSS_COMPILE ?= arm-linux-gnueabi-&lt;br /&gt;
 CC = $(CROSS_COMPILE)gcc&lt;br /&gt;
 LD = $(CROSS_COMPILE)ld&lt;br /&gt;
 CPU = cortex-m0&lt;br /&gt;
 FOPTS = -fno-builtin -ffunction-sections -fdata-sections&lt;br /&gt;
 CFLAGS = -Wall -Wextra -mthumb -mcpu=$(CPU) $(FOPTS)&lt;br /&gt;
 &lt;br /&gt;
 .PHONY: all&lt;br /&gt;
 all: $(NAME)&lt;br /&gt;
 &lt;br /&gt;
 SRC = $(wildcard *.c)&lt;br /&gt;
 OBJS = $(SRC:.c=.o)&lt;br /&gt;
 &lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ -o $@&lt;br /&gt;
Ce Makefile est encore incomplet et ne permet pas d&#039;obtenir le binaire pour notre micro-contrôleur, mais nous ajouterons les parties manquantes plus tard.&lt;br /&gt;
&lt;br /&gt;
En attendant, ce Makefile nous permettra de compiler le code que nous allons écrire, passons donc aux parties intéressantes, et le reste du Makefile sera bien plus simple à comprendre.&lt;br /&gt;
&lt;br /&gt;
== Commençons simple ==&lt;br /&gt;
&lt;br /&gt;
Pour ne pas trop compliquer les choses dès le début, nous allons tenter de faire clignoter la led bicolore présente sur le module GPIO-Démo.&lt;br /&gt;
&lt;br /&gt;
Notre squelette de code ressemblera à s&#039;y méprendre à ce que l&#039;on pourrait avoir pour un programme plus commun :&lt;br /&gt;
 /*&lt;br /&gt;
  * Notre exemple simple pour Open Silicium&lt;br /&gt;
  */&lt;br /&gt;
 void system_init(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* System init ? */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
 	/* Micro-controller init */&lt;br /&gt;
 	system_init();&lt;br /&gt;
 	&lt;br /&gt;
 	while (1) {&lt;br /&gt;
 		/* Change the led state */&lt;br /&gt;
 		/* Wait some time */&lt;br /&gt;
 	}&lt;br /&gt;
 	return 0;&lt;br /&gt;
 }&lt;br /&gt;
Si vous compilez ce petit morceau de code avec notre Makefile, vous obtiendrez un binaire qui globalement ne fait rien, mais a déjà une taille de 5.7 Ko.&lt;br /&gt;
C&#039;est gros pour ne rien faire, d&#039;autant que la mémoire Flash de notre micro-contrôleur ne fait que 32 Ko.&lt;br /&gt;
&lt;br /&gt;
Si on regarde plus loin, par exemple avec l&#039;utilitaire &#039;&#039;file&#039;&#039;, on obtient quelques informations supplémentaires :&lt;br /&gt;
 $ file mod_gpio&lt;br /&gt;
 mod_gpio: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), [....], not stripped&lt;br /&gt;
&lt;br /&gt;
Arghhh, notre binaire est un exécutable dynamique au format ELF, qui utilise des bibliothèques partagées !&lt;br /&gt;
&lt;br /&gt;
Nous l&#039;avons déjà évoqué, notre micro-contrôleur n&#039;a pas de libC ni de système d&#039;exploitation, notre binaire ne peut donc pas être dynamique (lié dynamiquement à des bibliothèques) !&lt;br /&gt;
Il nous faut donc faire l&#039;édition de lien en &amp;quot;static&amp;quot;, en apportant quelques modification à notre Makefile. Nous allons introduire une variable &amp;quot;LDFLAGS&amp;quot;, que l&#039;on ajoutera à la règle de compilation utilisée pour l&#039;édition de liens.&lt;br /&gt;
 LDFLAGS = -static&lt;br /&gt;
 $(NAME): $(OBJS)&lt;br /&gt;
 	$(LD) $^ $(LDFLAGS) -o $@&lt;br /&gt;
Recompilons notre projet ... 608 Ko !!! Re-Argh !&lt;br /&gt;
&lt;br /&gt;
Visiblement quelqu&#039;un ajoute du code dont nous n&#039;avons pas besoin. Il faut du moins l&#039;espérer, sinon il ne sera jamais possible de faire rentrer un programme dans la flash de notre micro-contrôleur, qui fait toujours 32Ko.&lt;br /&gt;
&lt;br /&gt;
L&#039;option &amp;quot;static&amp;quot; demande à l&#039;éditeur de lien de créer un binaire statique, mais résultat il nous ajoute tout ce qui est utile de la libC pour un exécutable ... pour un système Linux.&lt;br /&gt;
D&#039;ailleurs, &#039;&#039;file&#039;&#039; nous dit bien que notre exécutable est au format ELF.&lt;br /&gt;
&lt;br /&gt;
Pour commencer nous allons demander à l&#039;éditeur de liens (ld) de ne pas inclure les éléments de démarrage dans notre binaire, car ils sont inutiles sur notre micro-contrôleur. Pour cela nous ajoutons l&#039;option &amp;quot;-nostartfiles&amp;quot; à nos directives pour l&#039;édition de liens.&lt;br /&gt;
&lt;br /&gt;
Et hop, une recompilation plus tard, notre binaire ne fait plus que 1 Ko :)&lt;br /&gt;
Mais pour &#039;&#039;file&#039;&#039;, ce binaire est toujours au format ELF, et gcc nous informe qu&#039;il n&#039;a pas trouvé de symbole d&#039;entrée &amp;quot;_start&amp;quot; et qu&#039;il utilise une adresse par défaut (nous l&#039;avons cherché, cela fait partie de ce que nous avons demandé à l&#039;éditeur de liens en ajoutant l&#039;option &amp;quot;-nostartfiles&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
En effet, le &amp;quot;main&amp;quot; de nos programmes en C n&#039;est que le point de départ de l&#039;exécution de notre code, mais pas celui du programme. Il est précédé par un certain nombre de routines (fonctions) d&#039;initialisation, dont le point d&#039;entrée est la routine &amp;quot;_start&amp;quot;, qui appellera le main &amp;quot;classique&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Mais notre but n&#039;est pas de créer un exécutable pour un système Linux, nous devons créer un binaire pour notre micro-contrôleur. Il est désormais temps de nous plonger dans la documentation du micro-contrôleur pour comprendre comment il démarre, pour pouvoir adapter notre code au démarrage du micro-contrôleur et fournir l&#039;équivalent de cette routine &amp;quot;_start&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Bootstrap == &lt;br /&gt;
&lt;br /&gt;
=== Table des vecteurs d&#039;interruption ===&lt;br /&gt;
&lt;br /&gt;
Pour avoir des informations sur le démarrage du micro-contrôleur LPC1224 dans sa documentation technique [7] il y a deux chapitres intéressants.&lt;br /&gt;
&lt;br /&gt;
Nous pouvons nous référer au chapitre 4 (LPC122x System control) qui inclut une section sur le reset du micro-contrôleur (4.6 : Reset), dans laquelle on apprend qu&#039;une fois que la condition de reset disparait et que les procédures internes se sont exécutées, le processeur commence l&#039;exécution à l&#039;adresse contenue dans le vecteur &amp;quot;Reset&amp;quot; du &amp;quot;boot block&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Nous avons ainsi quelques informations, mais qu&#039;est-ce que le vecteur &amp;quot;Reset&amp;quot; et le &amp;quot;boot block&amp;quot; ? Cela nous mène au deuxième chapitre intéressant, le chapitre 25 sur le cœur ARM Cortex-M0. On y trouve une section sur le processeur (25.3 : Processor) avec une sous section concernant les exeptions (25.3.3 : Exception model). &lt;br /&gt;
&lt;br /&gt;
Dans les informations sur les exceptions (25.3.3.2), et plus particulièrement l&#039;exception &amp;quot;Reset&amp;quot;, il est indiqué qu&#039;après un &amp;quot;Reset&amp;quot; l&#039;exécution reprend à l&#039;adresse indiquée dans le vecteur &amp;quot;Reset&amp;quot; dans la table des vecteurs d&#039;interruption.&lt;br /&gt;
&lt;br /&gt;
Bien, cela confirme ce qui se trouvait dans le chapitre 4. Mais cette fois, nous avons une sous-section &amp;quot;25.3.3.4 Vector table&amp;quot;, qui décrit cette fameuse table des vecteurs d&#039;exception, précisant qu&#039;elle contient l&#039;addresse de toutes les routines de gestion des exceptions (les fameux &amp;quot;vecteurs&amp;quot; d&#039;exception, dont le vecteur &amp;quot;Reset&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Remarquez au passage que les interruptions sont gérées de la même façon, l&#039;addresse d&#039;entrée des routines de gestion des interruptions se trouve dans cette même table.&lt;br /&gt;
&lt;br /&gt;
Et en dessous de cette table, nous avons une autre information très intéressante : &amp;quot;The vector table is fixed at address 0x00000000&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Si l&#039;on se réfère à la table 65 de la section &amp;quot;25.3.2 Memory model&amp;quot;, et à la figure 2 de la section &amp;quot;2.3 Memory allocation&amp;quot;, on découvre que cette adresse est en fait le début de la mémoire flash du micro-contrôleur, qui devra contenir notre code binaire.&lt;br /&gt;
&lt;br /&gt;
Reste à créer cette table, et à la placer au bon endroit dans le code binaire compilé...&lt;br /&gt;
&lt;br /&gt;
=== Les &amp;quot;handlers&amp;quot; et les &amp;quot;dummy handlers&amp;quot; ===&lt;br /&gt;
&lt;br /&gt;
Nous allons commencer par la partie code.&lt;br /&gt;
Ce code peut être placé dans le même fichier que celui ou ce trouve notre fonction main, ou dans un autre fichier, cela n&#039;a pas d&#039;importance. Si vous vous référez au code du module GPIO-Démo disponible dans les dépôts git de Techno-Innov, vous trouverez ce code dans le fichier &amp;quot;core/bootstrap.c&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
[[Image:Vecteurs_interruption.png|350px|right]]&lt;br /&gt;
&lt;br /&gt;
 /* Cortex M0 core interrupt handlers */&lt;br /&gt;
 void Reset_Handler(void);&lt;br /&gt;
 void NMI_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 void HardFault_Handler(void) __attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)));&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void);&lt;br /&gt;
 &lt;br /&gt;
 void *vector_table[] = {&lt;br /&gt;
 	0,&lt;br /&gt;
 	Reset_Handler,&lt;br /&gt;
 	NMI_Handler,&lt;br /&gt;
 	HardFault_Handler,&lt;br /&gt;
 	0,&lt;br /&gt;
 	/* [......] */&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 void Dummy_Handler(void) {&lt;br /&gt;
     while (1);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Voici un petit morceau de code relativement court qui définit notre table de vecteur ainsi que les routines de gestion correspondantes.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, faisons un petit point sur certains éléments : les attributs utilisés pour la déclaration de deux de nos routines de gestion des exceptions : &amp;quot;__attribute__ ((weak, alias (&amp;quot;Dummy_Handler&amp;quot;)))&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Ces attributs permettent de définir un alias &amp;quot;faible&amp;quot; pour une fonction, ce qui veut dire que si le compilateur ne trouve pas de définition pour cette fonction, il pourra utiliser son alias, que nous avons défini plus bas. Au contraire, si dans un autre fichier (ou celui-ci) vous définissez l&#039;une de ces fonctions, c&#039;est votre définition qui sera utilisée.&lt;br /&gt;
&lt;br /&gt;
Note : je n&#039;ai pas mis la totalité de la table des vecteurs, cela n&#039;a pas d&#039;intérêt pour les explications, et notre programme fonctionnera sans, mais il faudrait la compléter pour un vrai programme, en faisant attention à l&#039;ordre, à partir des informations de la figure 68 déjà évoquée, et de la table 4 du chapitre 3 concernant le gestionnaire d&#039;interruptions (vous noterez la typo, il s&#039;agit des numéros d&#039;IRQ et non pas des numéros des vecteurs d&#039;exception).&lt;br /&gt;
&lt;br /&gt;
=== Appeler notre main() ===&lt;br /&gt;
Ce petit bout de code compile donc, puisque tout est défini, mais nous avons toujours l&#039;avertissement concernant le symbole d&#039;entrée &amp;quot;_start&amp;quot; qui n&#039;a pas été trouvé. Nous ne sommes pas plus avancé.&lt;br /&gt;
&lt;br /&gt;
Tout d&#039;abord, nous avons déjà indiqué que le point d&#039;entrée de notre code est la fonction main() (qui pourrait avoir n&#039;importe quel nom), mais pour notre micro-controlleur la fonction d&#039;entrée du programme est la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
La solution pour faire le lien est toute simple : il suffit d&#039;appeler la fonction main() depuis la routine de gestion de l&#039;exception &amp;quot;Reset&amp;quot;.&lt;br /&gt;
 int main(void);&lt;br /&gt;
 void Reset_Handler(void) {&lt;br /&gt;
 	/* Our program entry ! */&lt;br /&gt;
 	main();&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
=== Tisser des liens, c&#039;est important ===&lt;br /&gt;
Cela ne résout cependant aucun de nos problèmes, nous allons donc devoir donner plus d&#039;indications à l&#039;éditeur de liens, en créant un script pour l&#039;édition de lien (lpc_link_lpc1224.ld). Nous donnerons le nom de ce script à l&#039;éditeur de liens en utilisant l&#039;otion &amp;quot;-T&#039;&#039;lpc_link_lpc1224.ld&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Ce script d&#039;édition de lien (&amp;quot;linker script&amp;quot; en anglais) est en fait un fichier qui décrit la mémoire de notre micro-contrôleur, ainsi que l&#039;organisation que devra respecter notre binaire.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc commencer, toujours à partir des mêmes informations en provenance de la documentation technique, par définir quelle est la mémoire disponible, aussi bien la mémoire &amp;quot;vive&amp;quot; (SRAM) que la mémoire &amp;quot;morte&amp;quot; (FLASH).&lt;br /&gt;
&lt;br /&gt;
 MEMORY&lt;br /&gt;
 {&lt;br /&gt;
 	sram (rwx) : ORIGIN = 0x10000000, LENGTH = 4k&lt;br /&gt;
 	flash (rx) : ORIGIN = 0x00000000, LENGTH = 32k&lt;br /&gt;
 }&lt;br /&gt;
Nous définissons ainsi l&#039;adresse et la taille (et les droits d&#039;accès) de la sram et de la flash, qui deviennent deux blocs de mémoire disponibles pour l&#039;éditeur de liens, qui pourra donc y placer du code et des données.&lt;br /&gt;
&lt;br /&gt;
Il nous faut maintenant expliquer à l&#039;éditeur de liens comment organiser le code et les données dans ces blocs de mémoire, et tout particulièrement notre tableau de vecteurs d&#039;interruptions&lt;br /&gt;
&lt;br /&gt;
Le code d&#039;un programme est composé de &amp;quot;sections&amp;quot;, dans lesquelles le compilateur place chaque fonction et chaque variable en fonction de différents critères, que l&#039;on peut contrôler soit à partir de directives de compilation, soit d&#039;attributs ajoutés dans notre code C&lt;br /&gt;
&lt;br /&gt;
Nous allons donc modifier notre tableau de vecteurs d&#039;interruptions pour lui ajouter un attribut &amp;quot;section&amp;quot; qui forcera l&#039;éditeur de liens à le placer dans la section que nous avons défini.&lt;br /&gt;
: void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
&lt;br /&gt;
Et en parallèle, nous allons définir dans notre script quelles sont les sections que nous voulons trouver dans notre binaire, et dans quel ordre.&lt;br /&gt;
Commençons simple (si si, je vous assure), nous compliquerons plus tard :&lt;br /&gt;
 SECTIONS {&lt;br /&gt;
 	. = ORIGIN(flash);&lt;br /&gt;
 	.text :&lt;br /&gt;
 	{&lt;br /&gt;
 		KEEP(*(.vectors))&lt;br /&gt;
 		*(.text*)&lt;br /&gt;
 		*(.rodata*)&lt;br /&gt;
 	} &amp;gt;flash&lt;br /&gt;
 	.data :&lt;br /&gt;
 	{&lt;br /&gt;
 		*(.data*)&lt;br /&gt;
 		*(.bss*)&lt;br /&gt;
 	} &amp;gt;sram&lt;br /&gt;
 }&lt;br /&gt;
Pour commencer, nous définissons l&#039;adresse courante (.) comme étant l&#039;origine de du bloc de mémoire &amp;quot;flash&amp;quot; (le bloc de mémoire défini précédemment et auquel nous avons donné ce nom, bien qu&#039;un autre nom aurait pu faire l&#039;affaire).&lt;br /&gt;
Ceci est important pour que l&#039;éditeur de liens puisse définir les adresses des fonctions pour l&#039;exécution de notre code.&lt;br /&gt;
À partir de ce point nous définissons une section &amp;quot;text&amp;quot;, dans laquelle nous allons demander à l&#039;éditeur de lien de mettre plusieurs éléments, à commencer par notre fameuse table de vecteurs, en lui interdisant d&#039;en changer la position !&lt;br /&gt;
Après quoi, nous lui demandons de placer l&#039;ensemble du code, que le compilateur a placé dans des section &amp;quot;.text.*&amp;quot;, puis les données en lecture seule (Read-Only data = rodata), et de placer le tout dans le bloc de mémoire &amp;quot;flash&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
À la suite, nous créons une section &amp;quot;data&amp;quot;, dans laquelle nous lui demandons de placer les données initialisées à des valeurs non nulles (data), puis les données initialement nulles (bss [8]), et de placer cette section en RAM.&lt;br /&gt;
&lt;br /&gt;
Ne reste plus qu&#039;une information à donner à l&#039;éditeur de liens (pour l&#039;instant): le point d&#039;entrée de notre programme.&lt;br /&gt;
Ceci est relativement simple et explicite :&lt;br /&gt;
: ENTRY(Reset_Handler)&lt;br /&gt;
&lt;br /&gt;
Dans notre Makefile la variable LDFLAGS devient :&lt;br /&gt;
: LDFLAGS = -static -nostartfiles -Tlpc_link_lpc1224.ld&lt;br /&gt;
&lt;br /&gt;
Une compilation plus tard, sans avertissements cette fois, nous avons un binaire ... beaucoup trop gros : notre binaire fait maintenant plus de 66 Ko !&lt;br /&gt;
&lt;br /&gt;
Soyons un peu curieux et allons donc voir ce qu&#039;il contient, mais pas à la main, rassurez vous, utilisons un utilitaire fait exprès pour cela : &#039;&#039;objdump&#039;&#039;. attention, il faut bien entendu utiliser la version &amp;quot;ARM&amp;quot; de objdump, donc avec le préfixe &amp;quot;CROSS_COMPILE&amp;quot;, soit dans mon cas &#039;&#039;arm-linux-gnueabi-objdump&#039;&#039;, avec l&#039;option &#039;&#039;--disassemble-all&#039;&#039; (-D) :&lt;br /&gt;
: arm-linux-gnueabi-objdump -D mod_gpio &amp;gt; dump&lt;br /&gt;
Et là, surprise, la version &amp;quot;désassemblée&amp;quot; de notre binaire est plus petite que la version binaire (le fichier &amp;quot;dump&amp;quot; fait 2.2 Ko).&lt;br /&gt;
&lt;br /&gt;
Regardons tout de même son contenu.&lt;br /&gt;
La première ligne nous informe que le format du fichier est &amp;quot;elf32-littlearm&amp;quot; ... pas grand chose à voir avec ce que nous voulions, un &amp;quot;simple&amp;quot; binaire (Notre micro-contrôleur n&#039;a toujours pas appris à lire les exécutables au format ELF). Premier problème.&lt;br /&gt;
&lt;br /&gt;
Quelqu&#039;un est venu glisser une section &amp;quot;.note.gnu.build-id&amp;quot; avant notre section &amp;quot;.text&amp;quot;, que l&#039;éditeur de liens aimerait placer en début de RAM (&amp;quot;10000000 &amp;lt;_sram_base&amp;gt;&amp;quot;), ce qui n&#039;a pas d&#039;intérêt pour nous.&lt;br /&gt;
&lt;br /&gt;
S&#039;en suit tout de même notre section &amp;quot;.text&amp;quot;, qui commence bien par notre table (enfin ! on nous écoute un peu !), suivie de nos quelques maigres fonctions. Notez les adresses des fonctions dans la table des vecteurs, qui sont toutes impaires. Ceci indique que notre processeur exécutera ces fonctions en mode &amp;quot;thumb&amp;quot; qui est bien le mode que nous avions demandé (-mthumb).&lt;br /&gt;
&lt;br /&gt;
Et encore une fois, notre section &amp;quot;.text&amp;quot; n&#039;est pas suivie de nos données, mais d&#039;autres sections que nous n&#039;avions pas demandées !&lt;br /&gt;
Certes, nous n&#039;avons pas de variables, et l&#039;éditeur de lien n&#039;ayant rien à mettre dans notre section &amp;quot;.data&amp;quot;, il ne l&#039;a pas créée, mais au final nous sommes relativement loin de ce que nous voulions.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc demander à l&#039;éditeur de liens de générer un petit peu moins de choses en ajoutant l&#039;option &#039;&#039;-Wl,--build-id=none&#039;&#039; à nos directives de compilation (variable LDFLAGS de notre Makefile), ce qui nous donne un binaire moitié plus petit mais toujours trop gros.&lt;br /&gt;
&lt;br /&gt;
=== Un binaire vraiment binaire ===&lt;br /&gt;
Mais nous ne pouvons pas en demander bien plus à l&#039;éditeur de liens, dont le travail est de créer des exécutables au format ELF.&lt;br /&gt;
Pour créer d&#039;autres types de binaire, nous devrons utiliser l&#039;utilitaire &#039;&#039;objcopy&#039;&#039; (toujours la version ARM, donc en fait &#039;&#039;arm-linux-gnueabi-objcopy&#039;&#039;).&lt;br /&gt;
Le travail de cet utilitaire est de créer des binaires à partir des exécutables ELF, en ne conservant que les sections qui nous intéressent (du moins, c&#039;est l&#039;usage que nous en ferons).&lt;br /&gt;
&lt;br /&gt;
Nous allons demander à cet utilitaire de nous générer une image binaire à partir du résultat de notre compilation en ajoutant dans notre Makefile une cible &amp;quot;$(NAME).bin&amp;quot; qui deviendra notre cible par défaut et dépendra de la génération du fichier au format ELF :&lt;br /&gt;
&lt;br /&gt;
 all: $(NAME).bin&lt;br /&gt;
 &lt;br /&gt;
 $(NAME).bin: $(NAME)&lt;br /&gt;
 	$(CROSS_COMPILE)objcopy -O binary $^ $@&lt;br /&gt;
&lt;br /&gt;
Et notre objectif est enfin atteint, avec un binaire de ... 36 octets !&amp;lt;br /&amp;gt;&lt;br /&gt;
Rappelez vous, je n&#039;ai mis que 5 entrées dans ma table de vecteurs, soit 20 octets, suivis de quelques fonctions vides. Tout va bien.&lt;br /&gt;
&lt;br /&gt;
== Un programme un peu plus utile ==&lt;br /&gt;
&lt;br /&gt;
Nous allons désormais pouvoir nous occuper d&#039;allumer nos Leds, en quelque sorte le &amp;quot;Hello world&amp;quot; de l&#039;électronique.&lt;br /&gt;
&lt;br /&gt;
=== Entrées et sorties ===&lt;br /&gt;
Du point de vue de notre micro-contrôleur, allumer ou éteindre une Led revient à changer l&#039;état de la sortie correspondante.&lt;br /&gt;
&lt;br /&gt;
Les entrées/sorties du microcontrôleur peuvent avoir plusieurs fonctions, mais hormis quelques exceptions elles sont par défaut configurées en entrées/sorties (GPIO (general Purpose Input Output) en anglais) avec la résistance de pull-up interne activée. Pour simplifier, nous laisserons donc cette étape de la configuration de côté pour l&#039;instant, et reviendrons dessus lorsque nous attaquerons la programmation d&#039;interfaces plus complexes.&lt;br /&gt;
&lt;br /&gt;
: Note : Les exceptions sont les GPIO 13, 25 et 26 du port 0 (respectivement Reset, SWDIO et SWDCLK), qui permettent le reset et le debug, ainsi que quatre GPIO sur lesquelles la fonction &amp;quot;0&amp;quot; est réservée : les GPIO 30 et 31 du port 0 et les GPIO 0 et 1 du port 1.&lt;br /&gt;
&lt;br /&gt;
=== Les registres ===&lt;br /&gt;
Pour changer l&#039;état d&#039;une de ces entrées/sorties, il faut commencer par la configurer en sortie, puis définir sont état.&lt;br /&gt;
&lt;br /&gt;
Avant d&#039;aller plus loin, il est important de comprendre que le processeur de notre micro-contrôleur ne voit que de la mémoire autour de lui. Il n&#039;a pas accès directement aux signaux électriques.&lt;br /&gt;
Pour accéder aux fonctions spéciales comme l&#039;état électrique d&#039;une sortie le processeur doit donc modifier des données dans une zone mémoire spécifique, dédiée à cette sortie, que l&#039;on appelle un registre.&lt;br /&gt;
&lt;br /&gt;
Notre micro-contrôleur dispose d&#039;un grand nombre de registres qui ont tous une taille de 32 bits, même si souvent certains bits ne sont pas utilisés (ils sont alors &amp;quot;réservés&amp;quot;).&lt;br /&gt;
Ces registres particuliers, qui nous donnent accès aux fonctions spéciales du micro-contrôleur, comme la configuration et l&#039;état des entrées sorties, sont accessibles chacun à une adresse fixe dans l&#039;espace d&#039;adressage du micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Nous avons déjà eu besoin d&#039;informations sur cet espace d&#039;adressage lorsque nous avons cherché des informations sur le démarrage du micro-contrôleur, il se trouve représenté sur la figure 2 dans la section &amp;quot;2.3 Memory allocation&amp;quot; du chapitre 2 (LPC122x Memory map).&lt;br /&gt;
&lt;br /&gt;
L&#039;adresse qui nous intéresse dépend du port sur lequel les leds sont connectées.&lt;br /&gt;
La led bicolore étant connectée sur le port 1 ce sont les registres présents à l&#039;adresse 0x50010000 que nous devrons utiliser.&lt;br /&gt;
Cette adresse est aussi rappelée avec la description des registres dans le chapitre 8 (LPC122x General Purpose I/O (GPIO))&lt;br /&gt;
&lt;br /&gt;
À partir de cette adresse se trouvent une série de registres permettant de contrôler les entrées/sorties du port 1. La modification du contenu de la mémoire accessible ainsi modifiera donc le comportement des entrées/sorties correspondantes ou leur état lorsqu&#039;elles sont configurées en sortie.&lt;br /&gt;
&lt;br /&gt;
Très (trop) souvent, pour accéder à ces registres, les programmeurs utilisent des définitions selon le principe suivant:&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 #define PORT1_MASK  (LPC_GPIO_1_BASE + 0x00)&lt;br /&gt;
 #define PORT1_PIN   (LPC_GPIO_1_BASE + 0x04)&lt;br /&gt;
 #define PORT1_OUT   (LPC_GPIO_1_BASE + 0x08)&lt;br /&gt;
 /* [.....] */&lt;br /&gt;
Personnellement je trouve cette façon de faire très inefficace, et peu lisible (voire complètement illisible), et je préfère l&#039;utilisation de structures.&lt;br /&gt;
Cela me semble beaucoup plus lisible, plus adapté pour accéder à de la mémoire qui est structurée, et apporte aussi un très net avantage lorsqu&#039;il existe plusieurs ensembles de registres utilisant la même organisation, par exemple quand il y a plusieurs liaisons séries sur le micro-contrôleur, ou dans le cas qui nous intéresse pour l&#039;instant, plusieurs ports d&#039;entrées/sorties.&lt;br /&gt;
La définition se passe alors ainsi :&lt;br /&gt;
 #define LPC_AHB_BASE  (0x50000000UL)&lt;br /&gt;
 #define LPC_GPIO_0_BASE  (LPC_AHB_BASE + 0x00000)&lt;br /&gt;
 #define LPC_GPIO_1_BASE  (LPC_AHB_BASE + 0x10000)&lt;br /&gt;
 /* General Purpose Input/Output (GPIO) */&lt;br /&gt;
 struct lpc_gpio&lt;br /&gt;
 {&lt;br /&gt;
    volatile uint32_t mask;       /* 0x00 : Pin mask, affects data, out, set, clear and invert */&lt;br /&gt;
    volatile uint32_t in;         /* 0x04 : Port data Register (R/-) */&lt;br /&gt;
    volatile uint32_t out;        /* 0x08 : Port output Register (R/W) */&lt;br /&gt;
    volatile uint32_t set;        /* 0x0C : Port output set Register (-/W) */&lt;br /&gt;
    volatile uint32_t clear;      /* 0x10 : Port output clear Register (-/W) */&lt;br /&gt;
    volatile uint32_t toggle;     /* 0x14 : Port output invert Register (-/W) */&lt;br /&gt;
    uint32_t reserved[2];&lt;br /&gt;
    volatile uint32_t data_dir;   /* 0x20 : Data direction Register (R/W) */&lt;br /&gt;
    /* [.....] */&lt;br /&gt;
 };&lt;br /&gt;
 #define LPC_GPIO_0      ((struct lpc_gpio *) LPC_GPIO_0_BASE)&lt;br /&gt;
 #define LPC_GPIO_1      ((struct lpc_gpio *) LPC_GPIO_1_BASE)&lt;br /&gt;
À noter, l&#039;utilisation du mot clé &amp;quot;volatile&amp;quot; qui interdira au compilateur d&#039;optimiser les accès à ces registres en gardant des copies intermédiaires, forçant la lecture ou l&#039;écriture immédiate.&lt;br /&gt;
&lt;br /&gt;
Cette notation nous donne aussi l&#039;information de la taille des données présentes à ces adresses, dans ce cas là, des valeurs sur 32 bits.&lt;br /&gt;
&lt;br /&gt;
Pour l&#039;utilisation dans le code, c&#039;est ensuite très simple, il suffit de déclarer un pointeur vers cette structure, puis d&#039;accéder au champ qui nous intéresse :&lt;br /&gt;
 struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
 gpio1-&amp;gt;out = 0;&lt;br /&gt;
&lt;br /&gt;
=== Allumer les leds ===&lt;br /&gt;
&lt;br /&gt;
Reste à déterminer quels sont les champs qui nous intéressent et quelles valeurs nous devons écrire dedans.&lt;br /&gt;
Pour configurer les pins reliées à nos Leds en sortie nous devons modifier le registre &amp;quot;DIR&amp;quot; (appelé &amp;quot;data_dir&amp;quot; dans la structure), et mettre les bits 4 et 5 à &amp;quot;1&amp;quot; puisque chaque bit de ce registre permet de configurer une des pins du port correspondant, le bit 0 pour la pin 0, le bit 1 pour la pin 1, et ainsi de suite (attention, ici les numéros de pins ne sont pas les numéros des pattes du composant).&lt;br /&gt;
&lt;br /&gt;
Nous pouvons donc modifier notre main() pour obtenir le code suivant qui réalise cette opération de façon lisible, et positionne la Led verte à l&#039;état &amp;quot;allumée&amp;quot;, sans modifier l&#039;état des autres sorties du port 1 :&lt;br /&gt;
 /* The status LED is on GPIO Port 1, pin 4 (PIO1_4) and Port 1, pin 5 (PIO1_5) */&lt;br /&gt;
 #define LED_RED    5&lt;br /&gt;
 #define LED_GREEN  4&lt;br /&gt;
 int main(void)&lt;br /&gt;
 {&lt;br /&gt;
    struct lpc_gpio* gpio1 = LPC_GPIO_1;&lt;br /&gt;
    /* Micro-controller init */&lt;br /&gt;
    system_init();&lt;br /&gt;
    /* Configure the Status Led pins */&lt;br /&gt;
    gpio1-&amp;gt;data_dir |= (1 &amp;lt;&amp;lt; LED_GREEN) | (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    /* Turn Green Led ON */&lt;br /&gt;
    gpio1-&amp;gt;set = (1 &amp;lt;&amp;lt; LED_GREEN);&lt;br /&gt;
    gpio1-&amp;gt;clear = (1 &amp;lt;&amp;lt; LED_RED);&lt;br /&gt;
    while (1) {&lt;br /&gt;
        /* Change the led state */&lt;br /&gt;
        /* Wait some time */&lt;br /&gt;
    }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
[Encart : Décalages de bits] :&lt;br /&gt;
: La notation &amp;quot;&amp;lt;&amp;lt;&amp;quot; correspond à l&#039;opérateur logique &amp;quot;décalage de bits vers la gauche&amp;quot; (&amp;quot;&amp;gt;&amp;gt;&amp;quot; pour le décalage à droite). Voir l&#039;article wikipedia sur le sujet, en Anglais, la version Française étant catastrophiquement incomplète [9].&lt;br /&gt;
&lt;br /&gt;
== Mettre le code sur le micro-contrôleur : lpctools ==&lt;br /&gt;
&lt;br /&gt;
Je sais que vous êtes de plus en plus impatients et que vous voulez voir le résultat de tout ceci en vrai, nous allons donc passer à la mise en flash sur le micro-contrôleur pour tester tout cela.&lt;br /&gt;
&lt;br /&gt;
Je ne traiterais ici que le cas de la version 48 broches du micro-contrôleur LPC1224 (package LQFP48). A vous d&#039;adapter si vous utilisez un autre micro-contrôleur, le principe étant très similaire pour tous les LPC de NXP. Pour les autres gammes de micro-contrôleurs, référez vous à leurs docs techniques et aux informations sur Internet.&lt;br /&gt;
&lt;br /&gt;
=== Connexion ===&lt;br /&gt;
Si vous avez mis l&#039;adaptateur USB-UART sur votre module comme proposé dans les articles précédents, l&#039;étape de connexion au PC est simple, connectez votre module sur un port USB, directement ou via un câble en fonction du connecteur USB que vous avez choisi.&lt;br /&gt;
&lt;br /&gt;
Sinon, il vous faudra un adaptateur USB-UART (souvent vendus comme adaptateurs USB-série) fonctionnant en 3.3V, et relier les signaux Rx et Tx aux signaux TXD0 et RXD0 correspondant à l&#039;UART 0 du micro-contrôleur LPC1224 qui se trouvent sur le port 0, pins 1 et 2 (broches 16 et 17 du composant). Il est alors préférable d&#039;avoir rendu ces signaux accesssibles sur un connecteur de votre choix, sans quoi il vous faudra souder des fils directement sur les pattes du micro-contrôleur ... possible, mais pas conseillé du tout).&lt;br /&gt;
&lt;br /&gt;
=== Mode ISP ===&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite mettre le micro-contrôleur en mode programmation (ISP : &amp;quot;In System Programming&amp;quot; en anglais). Le chapitre 20 (LPC122x Flash ISP/IAP) indique qu&#039;il faut maintenir la pin 12 du port 0 (broche 27) à l&#039;état bas (0V) pendant au moins 3ms après avoir relaché le signal &amp;quot;Reset&amp;quot; (pin 13 du port 0, broche 28). La suite du chapitre décrit le protocole de programmation, uniquement utile si vous voulez créer votre propre utilitaire pour programmer le micro-contrôleur, ou si vous voulez réaliser des opérations très spécifiques.&lt;br /&gt;
&lt;br /&gt;
Puisque nous avons placé des boutons poussoir reliant ces signaux à la masse, avec des résistance de &amp;quot;pull-up&amp;quot;, cette opération est très simple : il faut appuyer sur les deux boutons en même temps, puis relacher le bouton reset avant de relacher le bouton ISP.&lt;br /&gt;
Lorsque tout c&#039;est bien passé, la led bicolore doit avoir deux petits points lumineux à peine visibles dans l&#039;obscurité (un rouge et un vert).&lt;br /&gt;
&lt;br /&gt;
=== Dialogue avec le micro-contrôleur ===&lt;br /&gt;
&lt;br /&gt;
La suite se passe sur le PC. Le paquet lpctools contient deux binaires : lpcisp et lpcprog.&lt;br /&gt;
Le premier donne accès aux opérations élémentaires du protocole de programmation, et ne nous sera pas utile. Le second permet de programmer le micro-contrôleur en utilisant une unique commande, bien que d&#039;autres commandes permettent d&#039;effectuer quelques opérations intéressantes.&lt;br /&gt;
&lt;br /&gt;
Nous allons d&#039;ailleurs commencer par une de ces autres opération : demander les identifiants de notre micro-contrôleur avec la commande &amp;quot;id&amp;quot;.&lt;br /&gt;
La syntaxe des commandes lpcprog est simple, il suffit de lui passer un nom de device, que l&#039;on passe comme argument de l&#039;option &amp;quot;-d&amp;quot;, une commande (argument de l&#039;option &amp;quot;-c&amp;quot;), et si besoin le nom du fichier à utiliser.&lt;br /&gt;
Dans l&#039;exemple suivant le module GPIO-Démo est identifié sur le poste de développement comme périphérique &amp;quot;ttyUSB0&amp;quot;, nous utiliserons donc le &#039;&#039;device&#039;&#039; &amp;quot;/dev/ttyUSB0&amp;quot;.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c id&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Part ID is 0x3640c02b&lt;br /&gt;
 UID: 0x2c0cf5f5 - 0x4b32430e - 0x02333834 - 0x4d7c501a&lt;br /&gt;
 Boot code version is 6.1&lt;br /&gt;
La première ligne nous indique que lpcprog a reconnu le micro-contrôleur et qu&#039;il sera donc possible de le programmer. (Si ce n&#039;est pas le cas, vous devrez compléter le fichier de description des micro-contrôleurs).&lt;br /&gt;
Ensuite, lpcprog nous donne les informations propres au micro-contrôleur, à savoir son identifiant unique et la version du &amp;quot;boot code&amp;quot; qui se trouve en rom sur le micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Si vous avez un affichage similaire, tout va bien.&lt;br /&gt;
Sinon, vérifiez la connexion et que le micro-contrôleur est bien en mode ISP.&lt;br /&gt;
&lt;br /&gt;
La programmation se fait ensuite très simplement avec la commande &amp;quot;flash&amp;quot;, en ajoutant le nom du fichier binaire à envoyer.&lt;br /&gt;
 $ lpcprog -d /dev/ttyUSB0 -c flash mod_gpio.bin&lt;br /&gt;
 Part ID 0x3640c02b found on line 26&lt;br /&gt;
 Flash now all blank.&lt;br /&gt;
 Checksum check OK&lt;br /&gt;
 Flash size : 32768, trying to flash 1 blocks of 1024 bytes : 1024&lt;br /&gt;
 Writing started, 1 blocks of 1024 bytes ...&lt;br /&gt;
lpcprog se charge d&#039;effacer la flash, de générer la somme de contrôle de l&#039;entête et de la placer au bon endroit dans le binaire, et d&#039;envoyer le tout au micro-contrôleur pour mise en flash.&lt;br /&gt;
&lt;br /&gt;
Pour tester, il suffit d&#039;appuyer sur le bouton Reset, et de constater qu&#039;il ne se passe rien, ce qui n&#039;est pas ce que nous attendions.&lt;br /&gt;
&lt;br /&gt;
Il y a plusieurs problèmes.&lt;br /&gt;
&lt;br /&gt;
=== Votre code s&#039;il vous plait ! ===&lt;br /&gt;
&lt;br /&gt;
Le premier vient de la génération de la somme de contrôle, ou plutôt de sa position dans notre binaire.&lt;br /&gt;
Tous les LPC de NXP utilisent (à ce jour de ce que j&#039;ai pu voir) le même mécanisme pour déterminer si la flash contient une image valide avant d&#039;essayer d&#039;exécuter son contenu : la vérification du checksum des 8 premiers vecteurs d&#039;interruption, qui doit être nulle.&lt;br /&gt;
&lt;br /&gt;
Pour que ceci soit possible, conformément à la documentation technique des micro-contrôleurs, lpcprog calcule le complément à 2 des 7 premiers vecteurs, et le place dans le huitième.&lt;br /&gt;
&lt;br /&gt;
Sauf que notre tableau ne fait pour l&#039;instant que 5 &amp;quot;cases&amp;quot; et que la huitième case contenait en fait notre code exécutable, qui a été écrasé.&lt;br /&gt;
&lt;br /&gt;
La première modification est donc de remplir au moins 8 cases de ce tableau, au pire avec des valeurs nulles, sinon, avec des valeurs correspondant à ce qui est attendu dans la documentation : les adresses des routines de gestion, ou au moins celle de notre routine &amp;quot;de remplacement&amp;quot; (Dummy_Handler()) lorsque la documentation indique que l&#039;emplacement est utilisé (table 363 et figure 68 pour les exceptions, et table 4 pour les interruption).&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    0, /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
    NMI_Handler,&lt;br /&gt;
    HardFault_Handler,&lt;br /&gt;
    0,&lt;br /&gt;
    0, /* 5 */&lt;br /&gt;
    0,&lt;br /&gt;
    /* Entry 7 (8th entry) must contain the 2’s complement of the check-sum&lt;br /&gt;
       of table entries 0 through 6. This causes the checksum of the first 8&lt;br /&gt;
       table entries to be 0 */&lt;br /&gt;
    (void *)0xDEADBEEF, /* Actually, this is done using an external tool. */&lt;br /&gt;
    0,&lt;br /&gt;
    /* [.....] voir le code du module GPIO-Demo pour la suite */&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
Cependant ceci n&#039;est pas suffisant (vous pouvez désormais le tester très simplement, je vous laisse faire).&lt;br /&gt;
&lt;br /&gt;
=== Un peu de place pour la pile ===&lt;br /&gt;
&lt;br /&gt;
Le dernier point un petit peu particulier est encore sur cette fameuse table des vecteurs, et concerne la première entrée.&lt;br /&gt;
Si vous regardez attentivement la figure 68, le vecteur &amp;quot;Reset&amp;quot; n&#039;est que la deuxième entrée de la table.&lt;br /&gt;
La première est la valeur initiale du pointeur de la pile (Stack pointer), qui correspond en fait à son sommet puisque cette pile est remplie en faisant décroître les adresses (cette information se trouve dans le chapitre 25, mais cette fois je vous laisse chercher un petit peu).&lt;br /&gt;
&lt;br /&gt;
Nous avons initialisé cette valeur à 0, ce qui forcément pose un soucis.&lt;br /&gt;
&lt;br /&gt;
Pour obtenir la bonne valeur, nous pourrions coder en dur l&#039;adresse du haut de notre sram, mais ce n&#039;est pas propre.&lt;br /&gt;
Pour que tout soit fait correctement et automatiquement, nous allons modifier le script de l&#039;édition de liens, et demander à &#039;&#039;&#039;ld&#039;&#039;&#039; de remplir cette adresse à notre place, en fonction de l&#039;adresse de la sram et de sa taille.&lt;br /&gt;
&lt;br /&gt;
Nous allons donc créer des variables dans notre script, juste après la définition de la mémoire disponible, et chose très importante, ces variables seront des variables externes utilisables dans notre code C !&lt;br /&gt;
: _sram_size = LENGTH(sram);&lt;br /&gt;
: _sram_base = ORIGIN(sram);&lt;br /&gt;
: _end_stack = (_sram_base + _sram_size);&lt;br /&gt;
Nous appelons le bas de la pile (la &amp;quot;fin&amp;quot; de la pile) &#039;&#039;&#039;_end_stack&#039;&#039;&#039;, et plaçons cette fin de pile tout en haut de la mémoire vive.&lt;br /&gt;
&lt;br /&gt;
Et pour l&#039;utilisation dans notre code C, tout simplement :&lt;br /&gt;
 extern unsigned int _end_stack;&lt;br /&gt;
 void *vector_table[] __attribute__ ((section(&amp;quot;.vectors&amp;quot;))) = {&lt;br /&gt;
    &amp;amp;_end_stack, /* Initial SP value */ /* 0 */&lt;br /&gt;
    Reset_Handler,&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Si vous compilez votre code avec ces modifications, vous obtenez enfin un binaire qui allume la Led !&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Nous avons enfin notre &amp;quot;Hello World !&amp;quot; version électronique, mais la route est encore longue.&lt;br /&gt;
&lt;br /&gt;
Vous pourrez voir dans le prochain article que cette première étape n&#039;était qu&#039;une étape, et qu&#039;il reste encore plusieurs étapes importantes avant de pouvoir vraiment commencer à écrire du code &amp;quot;fonctionnel&amp;quot;, comme la gestion du &amp;quot;watchdog&amp;quot;, la configuration de l&#039;horloge interne, l&#039;initialisation de la mémoire, et l&#039;écriture des drivers pour chaque bloc fonctionnel (liaison série, I2C, SPI, ADC, ....).&lt;br /&gt;
&lt;br /&gt;
Rendez-vous donc pour le second article dédié à la programmation de notre micro-contrôleur.&lt;br /&gt;
&lt;br /&gt;
Merci pour votre lecture attentive !&lt;br /&gt;
&lt;br /&gt;
== Les fichiers créés ==&lt;br /&gt;
Vous trouverez sur notre serveur le [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/Makefile Makefile], le fichier C [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/main.c main.c], et le script de lien [http://techdata.techno-innov.fr/Modules/GPIO_Demo/Code_LM/Article_5/lpc_link_lpc1224.ld lpc_link_lpc1224.ld]&lt;br /&gt;
&lt;br /&gt;
== Liens - Bibliographie ==&lt;br /&gt;
* [1] https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/Option-Summary.html&lt;br /&gt;
* [2] https://sourceware.org/binutils/docs/binutils/objdump.html&lt;br /&gt;
* [3] https://sourceware.org/binutils/docs/binutils/readelf.html&lt;br /&gt;
* [4] Page du module et Manuel utilisateur : http://www.techno-innov.fr/technique-module-gpio-demo/ - http://techdata.techno-innov.fr/Modules/GPIO_Demo/System_Reference_Manual_Module_GPIO_Demo_v03.pdf&lt;br /&gt;
* [5] Dépôt GIT lpctools : http://git.techno-innov.fr/?p=lpctools&lt;br /&gt;
* [6] Lien vers d&#039;autres outils pour programmer les LPC :&lt;br /&gt;
** mxli : http://www.windscooting.com/softy/mxli.html&lt;br /&gt;
** lpc21isp : http://sourceforge.net/projects/lpc21isp/&lt;br /&gt;
** nxpprog : http://sourceforge.net/projects/nxpprog/&lt;br /&gt;
** GLPC (GUI pour lpc21isp) : http://sourceforge.net/projects/glpc/&lt;br /&gt;
* [7] Manuel utilisateur du LPC1224 : http://www.nxp.com/documents/user_manual/UM10441.pdf&lt;br /&gt;
* [8] http://fr.wikipedia.org/wiki/Segment_BSS&lt;br /&gt;
* [9] http://en.wikipedia.org/wiki/Bitwise_operation&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:Vecteurs_interruption.png&amp;diff=106</id>
		<title>Fichier:Vecteurs interruption.png</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:Vecteurs_interruption.png&amp;diff=106"/>
		<updated>2020-09-02T20:57:45Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:14-Module_sur_USB.png&amp;diff=105</id>
		<title>Fichier:14-Module sur USB.png</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:14-Module_sur_USB.png&amp;diff=105"/>
		<updated>2020-09-02T20:57:20Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie4&amp;diff=104</id>
		<title>Articles/Nathael/Domotab et elec Libre partie4</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Articles/Nathael/Domotab_et_elec_Libre_partie4&amp;diff=104"/>
		<updated>2020-09-02T20:56:27Z</updated>

		<summary type="html">&lt;p&gt;Nathael : /* Génération des fichiers Gerbers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Électronique et domotique libre - partie 4 : Un module en vrai, FabLabs et fabrication maison}}&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:left; margin-right: 2.5em;&amp;quot;&amp;gt;__TOC__&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DomoTab.png|200px|right]]&lt;br /&gt;
Les trois articles précédents (parus dans les [http://boutique.ed-diamond.com/open-silicium/490-os7.html numéros 7] et [http://boutique.ed-diamond.com/open-silicium/497-os8.html 8] d&#039;[http://boutique.ed-diamond.com/16-open-silicium Open Silicium]) vous ont présenté la partie conception sur ordinateur d&#039;un module pour le projet DomoTab. Il est maintenant temps de passer de la conception à la réalisation, et de fabriquer le module que nous avons conçu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;par Nathael Pajani&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:right&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
Paru dans le [http://boutique.ed-diamond.com/open-silicium/791-open-silicium-13.html numéro 13] du magazine Open Silicium.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;clear:both&amp;quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Petite vérification ==&lt;br /&gt;
&lt;br /&gt;
Avant de rentrer dans le vif du sujet, une note pour ceux qui n&#039;ont pas réalisé le schéma proposé dans les articles précédant : vérifiez que vous avez prévu un moyen simple pour accéder à l&#039;interface de programmation du microcontrôleur choisi, si possible un bouton reset, et un moyen permettant de mettre le microcontrôleur en mode programmation si besoin.&lt;br /&gt;
&lt;br /&gt;
== Dernière étape sur ordinateur ==&lt;br /&gt;
&lt;br /&gt;
Les articles précédents nous ont permis de créer le schéma du module GPIO-Demo et de réaliser le routage pour préparer la réalisation des PCB (Printed Circuit Board, ou Circuits Imprimés (CI) en français).&lt;br /&gt;
Il reste une dernière étape avant la fabrication : la génération des plans de fabrication. &lt;br /&gt;
Cette étape dépendra grandement de la solution choisie pour la fabrication du PCB.&lt;br /&gt;
Certains sous-traitants acceptent directement le format natif KiCad, mais ils sont assez rares et la majorité des fabricants acceptent le format Gerber.&lt;br /&gt;
Cependant si vous souhaitez réaliser vos PCB vous même aucun de ces deux formats ne vous sera utile et nous verrons plus tard comment procéder.&lt;br /&gt;
&lt;br /&gt;
=== Fichiers Gerber et &amp;quot;layers&amp;quot; ===&lt;br /&gt;
[[Image:06-Gerbview-01.png|400px|right]]&lt;br /&gt;
Les plans de fabrication les plus utilisés sont au format Gerber. Il s&#039;agit d&#039;un ensemble de fichiers décrivant chacun une couche (&amp;quot;layer&amp;quot; en anglais) du circuit imprimé final : couches de cuivre, contours, perçages (trous métallisés et trous non métallisés sur deux couches différentes), sérigraphies, vernis épargne, et masques de soudure.&lt;br /&gt;
Toutes ces couches correspondent aux couches que l&#039;on a sous KiCad (pcbnew), rien de nouveau donc. Cependant, toutes ne seront pas forcément présentes en fonction de votre circuit et de la finition que vous désirez.&lt;br /&gt;
&lt;br /&gt;
Le nombre de couches de cuivre dépendra de ce que vous aurez choisi pour le routage de votre circuit, donc deux couches dans le cas du module que nous avons créé, mais cela peut aller de une seule couche de cuivre, à dix couches pour les circuits les plus complexes et les plus denses. Lorsqu&#039;il y a plus de deux couches la fabrication &amp;quot;maison&amp;quot; sur un seul PCB n&#039;est plus possible, et les prix grimpent.&lt;br /&gt;
&lt;br /&gt;
La couche de contour correspond aux découpes du circuit imprimé. Tous les fabricants n&#039;acceptent pas les découpes complexes, renseignez vous avant de payer si votre circuit comporte des découpes intérieures ou des découpes courbes.&lt;br /&gt;
&lt;br /&gt;
Les couches de perçage correspondent aux trous pour les composants &amp;quot;traversants&amp;quot; et aux vias (pour les trous métallisés) et aux trous de fixation ou de placement de certains connecteurs qui ont des picots de placement en plastique (trous non métallisés).&lt;br /&gt;
Lorsque vous visualisez les fichiers gerbers sous KiCad (gerbview) les trous sont représentés par des formes géométriques diverses, une par diamètre de perçage, mais les trous auront bien la forme que vous avez définie :)&lt;br /&gt;
&lt;br /&gt;
Les couches suivantes sont optionnelles, mais bien utiles.&lt;br /&gt;
&lt;br /&gt;
Les couches de vernis épargne (dessus et dessous) définissent un masque de vernis qui sera appliqué sur la carte pour recouvrir les zones ne nécessitant pas de soudures. C&#039;est cette couche qui définit la couleur de la carte. Dans certains cas le vernis vert est inclus dans le prix de fabrication, mais les couleurs moins habituelles (rouge, bleu, noir, ...) impliquent un surcoût parfois non négligeable.&lt;br /&gt;
Cette couche est générée automatiquement à partir des données des empreintes des composants et d&#039;un paramètre global sous KiCad qui se trouve dans le menu Dimensions --&amp;gt; Marge Masque des Pads ([RefCard-5.26]). Dans la majorité des cas il n&#039;est pas nécessaire de laisser de marge supplémentaire, et une valeur de 0 fait l&#039;affaire. Les cas particuliers peuvent être définis dans l&#039;empreinte du composant.&lt;br /&gt;
L&#039;utilisation des couches de vernis donne un rendu beaucoup plus propre et facilite grandement la soudure des composants CMS.&lt;br /&gt;
&lt;br /&gt;
Les couches de sérigraphie (dessus et dessous) définissent les textes et autres tracés imprimés en blanc (dans la très grande majorité des cas) sur votre PCB. Ces textes vous aideront à placer les composants lors de la fabrication et à repérer les connecteurs ou les broches qui vous intéressent lors de l&#039;utilisation.&lt;br /&gt;
Bien souvent une seule couche de sérigraphie suffit.&lt;br /&gt;
&lt;br /&gt;
Les masques de soudure (dessus et dessous) servent à la fabrication des pochoirs pour les composants CMS. Ils ne sont nécessaires que si vous désirez faire fabriquer un pochoir métallique en découpe laser. Ce pochoir est très utile si vous avez de nombreux composants CMS, et PCB-Pool le propose gratuitement pour les petites quantités (moins de 100 PCB), mais il est possible de le réaliser dans un FabLab en découpe laser avec une feuille de plastique (voir plus loin).&lt;br /&gt;
&lt;br /&gt;
=== Génération des fichiers Gerbers ===&lt;br /&gt;
[[Image:06-Trace_Gerbers-01.png|600px|right]]&lt;br /&gt;
Sous KiCad la génération des fichiers Gerbers se fait via le menu Fichiers --&amp;gt; Tracer ([RefCard-5.27]).&lt;br /&gt;
KiCad supporte plusieurs types de fichiers, il faut bien sélectionner &amp;quot;Gerber&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Je vous conseille de créer un dossier pour les fichiers gerbers, cela simplifiera la création d&#039;une archive pour envoyer les fichiers au sous-traitant qui fabriquera vos cartes.&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite sélectionner les bonnes couches à inclure dans l&#039;export.&lt;br /&gt;
Toutes les couches actives dans votre projet se trouvent dans la colonne de gauche, à vous de vérifier que celles qui vous intéressent sont bien cochées.&lt;br /&gt;
&lt;br /&gt;
Les couches de cuivres sont notées &amp;quot;*.Cu&amp;quot;, les couches de vernis épargne sont les &amp;quot;*.Mask&amp;quot;, les couches de sérigraphie correspondent aux &amp;quot;*.SilkS&amp;quot; (pour Silk Screen), les couches pour les pochoirs CMS sont les &amp;quot;*.Paste&amp;quot; (pour &amp;quot;Solder Paste&amp;quot;, ou &amp;quot;pâte/crème à souder&amp;quot; en français), et les contours du PCB sont sur la couche &amp;quot;Edge.Cuts&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Pour le reste des cases à cocher, il me semble que les cases cochées par défaut conviennent, sinon reportez vous à la capture d&#039;écran (Figure à droite).&lt;br /&gt;
&lt;br /&gt;
Il faut ensuite &amp;quot;Tracer&amp;quot; (ce qui génère les fichiers sélectionnés), puis &amp;quot;Créer les Fichiers de Perçage&amp;quot;.&lt;br /&gt;
Pour les fichiers de perçage, il faut bien sélectionner le format Gerber, et cliquer sur &amp;quot;Drill file&amp;quot; et &amp;quot;Plan de perçage&amp;quot;.&lt;br /&gt;
Je ne sais pas si les deux sont utiles, mais j&#039;envoie systématiquement les deux et je n&#039;ai pas eu de problème ni de retour ou remarques, donc je continue comme ça :)&lt;br /&gt;
&lt;br /&gt;
Pour la suite, il ne vous restera plus qu&#039;à faire une archive (zip le plus souvent) pour envoyer votre PCB en fabrication.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez vérifier les fichiers en utilisant l&#039;utilitaire gerbview qui est intégré à la suite KiCad, et qui vous permet d&#039;activer ou désactiver les couches une à une (après les avoir &amp;quot;chargées&amp;quot; une première fois), et ainsi vérifier que vous n&#039;en avez pas oublié une, ou qu&#039;il n&#039;y a pas d&#039;erreur par rapport à ce que vous attendiez (trop de textes sur la couche sérigraphie, plans de masse pas mis à jours, ....)&lt;br /&gt;
&lt;br /&gt;
=== Version &amp;quot;fait maison&amp;quot; : fichiers SVG ===&lt;br /&gt;
&lt;br /&gt;
Pour la version fait maison, les fichiers Gerbers ne sont pas utiles, mais KiCad permet l&#039;export au format SVG des différentes couches de fabrication.&lt;br /&gt;
&lt;br /&gt;
L&#039;interface d&#039;export se trouve dans le menu Fichiers --&amp;gt; Export SVG ([RefCard-5.28]). Dans la majorité des cas seules les couches de cuivre sont intéressantes, mais vous pouvez très bien ajouter des guides de placement sur une couche &amp;quot;utilisateur&amp;quot; (Eco*.User) et vouloir les imprimer aussi, ainsi que le contour du circuit, pour faciliter la découpe finale.&lt;br /&gt;
&lt;br /&gt;
De même, compte tenu de la difficulté d&#039;impression de la sérigraphie, vous pouvez imprimer une partie des textes sur la couche de cuivre, ce qui vous permet de disposer de quelques indications supplémentaires sur votre PCB sans devoir jouer du marqueur.&lt;br /&gt;
&lt;br /&gt;
Dans ce cas là, vous pouvez choisir de tout imprimer dans le même fichier, ce qui vous évite de devoir replacer les différents éléments correctement à partir de plusieurs fichiers.&lt;br /&gt;
&lt;br /&gt;
N&#039;oubliez pas de cocher le tracé en miroir, que ce soit pour la technique de l&#039;insolation (pour que l&#039;encre soit au plus près du cuivre et le protège mieux, permettant des tracés plus fins), ou la technique de décalcomanie (voir plus loin).&lt;br /&gt;
&lt;br /&gt;
Vous pouvez ensuite visualiser le résultat avec Inkscape, et éventuellement regrouper plusieurs PCB.&lt;br /&gt;
&lt;br /&gt;
Il est possible de faire des PCB double couche, quelque soit la technique utilisée, mais attention, l&#039;alignement doit être précis, il faudra donc penser à mettre des repères qui permettront de positionner les masques lors de la fabrication. Ces repères peuvent être placés sous KiCad ou sous Inkscape, mais il est préférable de le faire sous KiCad car ils resteront présents si vous faites des modifications, ce qui n&#039;est pas le cas pour la version Inkscape.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Attention&#039;&#039;&#039; : Dans le cas de la fabrication maison de circuits simple couches avec des composants traversants, ceux-ci doivent être placés de l&#039;autre côté du PCB lors du placement des composants sous KiCad pour pouvoir être soudés sur les pistes.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; : Il est possible, lorsqu&#039;il n&#039;y a que quelques pistes sur la couche de cuivre du dessous, de ne faire qu&#039;un PCB simple couche, et de remplacer les pistes manquantes par des morceaux de pattes de composants ou des fils.&lt;br /&gt;
&lt;br /&gt;
== Fabrication du PCB ==&lt;br /&gt;
&lt;br /&gt;
=== Home Made et FabLab/ElectroLab ===&lt;br /&gt;
&lt;br /&gt;
La fabrication maison de cartes électroniques n&#039;est pas très compliquée et peut être à la portée de tous ... ou presque.&lt;br /&gt;
&lt;br /&gt;
Pour ceux qui ont accès à l&#039;Electrolab de Nanterre (http://www.electrolab.fr/), ils vous donneront des indications bien plus précises et détaillées que celles que je pourrais vous donner ici, et surtout, en échange d&#039;une cotisation modique (comme pour tout FabLab) vous aurez accès à du matériel vous permettant de réaliser vos circuits imprimés.&lt;br /&gt;
&lt;br /&gt;
Mais pour le reste de la France ... il faut se débrouiller (renseignez vous tout de même, le FabLab le plus prêt de chez vous a peut-être une partie du matériel, ou sera intéressé pour s&#039;équiper).&lt;br /&gt;
&lt;br /&gt;
Il y a globalement trois techniques pour fabriquer des PCB sans faire appel aux services d&#039;un sous-traitant professionnel : La méthode classique &amp;quot;isolation / révélation&amp;quot;, la méthode &amp;quot;décalcomanie&amp;quot;, et la méthode usinage.&lt;br /&gt;
&lt;br /&gt;
Les trois méthodes ne diffèrent que par les premières étapes, je détaillerais les étapes suivantes dans la partie &amp;quot;finitions&amp;quot; qui sera commune aux trois méthodes.&lt;br /&gt;
&lt;br /&gt;
==== Insolation / révélation ====&lt;br /&gt;
Cette méthode nécessite l&#039;utilisation de plaques pré-sensibilisées, que vous allez &amp;quot;graver&amp;quot; en trois étapes. Je n&#039;ai personnellement pas re-testé cette solution, que j&#039;avais mise en œuvre à l&#039;école, car je n&#039;aime pas trop manipuler les produits chimiques dangereux, et que je n&#039;ai pas d&#039;insoleuse UV, mais vous trouverez de nombreux tutoriels sur internet, et je vais vous en présenter rapidement le principe.&lt;br /&gt;
&lt;br /&gt;
La première étape est l&#039;insolation, ou exposition. La plaque de cuivre pré-sensibilisée est recouverte d&#039;un film sensible aux UV. La plaque doit être exposée aux UV à travers un &amp;quot;typon&amp;quot; qui n&#039;est autre qu&#039;une impression du circuit imprimé sur film transparent. Il vous faudra donc disposer d&#039;une insoleuse à UV.&lt;br /&gt;
&lt;br /&gt;
L&#039;étape suivante, la révélation, utilise un premier produit dangereux, la soude, pour dissoudre les parties du film photosensible qui ont été exposées. Attention, j&#039;ai bien dit produit dangereux, utilisation de gants et de lunettes de protection obligatoire.&lt;br /&gt;
&lt;br /&gt;
La troisième étape, la gravure proprement dite, utilise un autre produit dangereux (mais moins) et surtout qui tache définitivement les tissus : le perchlorure de fer. Celui-ci va attaquer le cuivre qui n&#039;est plus protégé par le film photosensible, ne laissant du cuivre que pour les pistes, faisant apparaître le circuit imprimé.&lt;br /&gt;
Pour accélérer le processus et éviter de gaspiller une grande quantité de produit, il est possible d&#039;utiliser une éponge et de frotter délicatement la surface du PCB avec un coin de l&#039;éponge imbibé de perchlorure de fer.&lt;br /&gt;
Le film de protection est ensuite retiré avec de l&#039;alcool à bruler (il doit être possible de tester avec de l&#039;acétone ou de l&#039;alcool à 70°).&lt;br /&gt;
&lt;br /&gt;
==== Décalcomanies ====&lt;br /&gt;
[[Image:07-Decalco-01.png|400px|right]]&lt;br /&gt;
Il existe une première alternative à la solution &amp;quot;classique&amp;quot;, qui utilise le principe des décalcomanies.&lt;br /&gt;
&lt;br /&gt;
Cette solution est en deux étapes, et utilise des plaques de cuivre non pré-sensibilisées, une imprimante laser (obligatoire) et une plastifieuse pour la première partie et toujours du perchlorure de fer pour la gravure.&lt;br /&gt;
&lt;br /&gt;
Le dessin de votre carte doit être imprimé sur un papier à décalcomanie (je n&#039;ai testé que celui proposé par &amp;quot;PCB-Fab-In-A-Box&amp;quot; dans leur kit, mais je pense que d&#039;autres font l&#039;affaire), puis transféré à chaud avec une pression régulière sur le circuit imprimé.&lt;br /&gt;
C&#039;est cette étape qui est critique et qu&#039;il faut parfois reprendre plusieurs fois, surtout si vous ne pouvez pas vous procurer une des plastifieuses spécifiées par &amp;quot;PCB-Fab-In-A-Box&amp;quot;, que Amazon refuse de livrer en dehors des États-Unis.&lt;br /&gt;
&lt;br /&gt;
Pour améliorer les résultats, il faut frotter la plaque de cuivre avec une éponge abrasive type &amp;quot;tampongex&amp;quot; (éponges vertes) pour la nettoyer, puis la chauffer à l&#039;aide d&#039;un fer à repasser (attention, elle devient brulante) avant d&#039;y déposer le décalcomanie et de passer le tout dans la plastifieuse. Il est possible de se passer de la plastifieuse, mais le dosage de la pression avec le fer à repasser est alors critique.&lt;br /&gt;
&lt;br /&gt;
Le papier est ensuite décollé en faisant tremper le tout une minute dans l&#039;eau, et si tout c&#039;est bien passé, l&#039;encre est alors déposée sur le cuivre. Si il y a des pistes rompues, ou des parties qui n&#039;ont pas collé sur le cuivre, il est possible de recommencer en enlevant l&#039;encre qui s&#039;est déposée avec de l&#039;acétone.&lt;br /&gt;
&lt;br /&gt;
[[Image:07-Decalco-02.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Le site &amp;quot;PCB-Fab-In-A-Box&amp;quot; conseille ensuite d&#039;appliquer une couche de protection à l&#039;aide d&#039;un film plastique (fourni dans leur Kit), mais avec ma plastifieuse je n&#039;ai pas réussi à le déposer correctement, et la gravure se passe très bien sans.&lt;br /&gt;
&lt;br /&gt;
Ensuite il faut procéder à la gravure avec le perchlorure de fer, comme pour la méthode précédente, l&#039;astuce avec l&#039;éponge étant toujours valable.&lt;br /&gt;
&lt;br /&gt;
Cette méthode permet d&#039;obtenir des pistes assez fines, mais nécessite plusieurs essais pour prendre en main la technique d&#039;application des décalcomanies.&lt;br /&gt;
&lt;br /&gt;
==== Usinage ====&lt;br /&gt;
La troisième méthode utilise une fraiseuse numérique pour retirer le cuivre inutile par gravure mécanique et non plus gravure chimique.&lt;br /&gt;
&lt;br /&gt;
Il vous faut alors transformer votre fichier SVG en tracé de découpe et la machine fait le reste. Il doit être possible de faire percer les vias et autres trous au même moment ou avec un autre outil, mais je n&#039;ai pas pu tester cette solution car les pistes utilisées pour mes PCB ont été jugées trop fines par les personnes disposant d&#039;une fraiseuse qui auraient pu réaliser des essais.&lt;br /&gt;
&lt;br /&gt;
==== Finitions ====&lt;br /&gt;
Une fois le cuivre gravé, il reste encore deux étapes.&lt;br /&gt;
&lt;br /&gt;
La première étape est optionnelle, il s&#039;agit de l&#039;étamage chimique des pistes. Il suffit pour cela de faire tremper le circuit dans une solution d&#039;étain chimique jusqu&#039;à ce que les pistes aient changé de couleur.&lt;br /&gt;
&lt;br /&gt;
La deuxième étape est le perçage des vias et des différents trous pour les composants. L&#039;utilisation d&#039;une petite perceuse sur colonne permet un travail bien plus efficace et précis, mais reste que les trous des vias ne seront pas métallisés.&lt;br /&gt;
&lt;br /&gt;
La métallisation des trous des vias peut se faire de façon chimique, mais cela demande un peu (beaucoup) de matériel et une installation en conséquence, tandis que la deuxième consiste simplement à utiliser de pattes de composants que vous avez coupées lors de l&#039;assemblage d&#039;un autre circuit pour relier les deux côtés du circuit imprimé en les soudant de chaque côté sur les pastilles, et en coupant avec une pince coupante tout ce qui dépasse.&lt;br /&gt;
&lt;br /&gt;
==== Liens utiles ====&lt;br /&gt;
* http://wiki.jelectronique.com/realisation_de_circuits_imprimes&lt;br /&gt;
* http://alain.canduro.free.fr/circuits.htm&lt;br /&gt;
&lt;br /&gt;
=== FabLabs et mutualisation des ressources ===&lt;br /&gt;
Les trois techniques présentées précédemment sont très pratiques pour réaliser un prototypage rapide, mais nécessitent toutes un peu de matériel, qui, bien que peu coûteux pour les deux premières solutions, représente au final entre 50 et 300 euros, et prend de la place.&lt;br /&gt;
&lt;br /&gt;
Il peut être intéressant de trouver un FabLab qui dispose de toute ou partie de ce matériel, ou qui serait intéressé pour l&#039;acquérir, libérant de la place chez vous et permettant de mutualiser l&#039;ensemble des coûts, et éventuellement de tester les différentes solution.&lt;br /&gt;
&lt;br /&gt;
La dernière étape est l&#039;application d&#039;un vernis sur la totalité du circuit. Il faut choisir un vernis thermosoudable qui permettra de souder les composants malgré la couche de vernis. Je n&#039;ai personnellement jamais testé, je ne connais pas la tenue des ces vernis et leur comportement lors de la soudure autre qu&#039;au fer à souder.&lt;br /&gt;
&lt;br /&gt;
=== Services de fabrication en ligne ===&lt;br /&gt;
&lt;br /&gt;
[[Image:07-Fab_PCB-01.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;avez pas la fibre DIY jusqu&#039;au bout des doigts, ou que manipuler des produits chimiques potentiellement dangereux ne vous amuse pas plus que moi, il existe des services de fabrication un peu partout dans le monde pour faire fabriquer des circuits imprimés avec une qualité professionnelle (ce sont souvent ceux utilisés par les professionnels) à un coût raisonnable (voir défiant toute concurrence).&lt;br /&gt;
&lt;br /&gt;
Attention, je ne parle pas ici de personnes qui se proposent de faire des circuit imprimés en utilisant une des méthodes citées ci-dessus à votre place, pour un tarif souvent plus élevé que les fabriquant industriels, avec les même délais, et pour une qualité qui n&#039;a rien de comparable avec ce que proposent les fabricants industriels.&lt;br /&gt;
&lt;br /&gt;
Bien entendu, si vous êtes extrêmement pressés et que vous voulez pouvoir tester votre circuit dans l&#039;heure, ceci n&#039;est pas une solution.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai testé plusieurs services de fabrication en ligne, dont PCB-Pool, qui produit en Irelande, Dipoles Electroniques, qui produit en France, PCB Train, qui produit en Angleterre, et Seeed Studio qui produit en chine.&lt;br /&gt;
&lt;br /&gt;
Chaque fabriquant a ses avantages et inconvénients, que je vais essayer de vous présenter, mais qui n&#039;engagent que moi.&lt;br /&gt;
&lt;br /&gt;
* PCB-Pool (https://www.pcb-pool.com) : les plus chers (ou pas), mais avec un réel service ajouté de vérification du circuit imprimé, la possibilité d&#039;envoyer votre circuit au format natif KiCad (pas de possibilité d&#039;erreur sur la génération des Gerbers), et le pochoir CMS en métal découpé au laser ... disons inclus dans le prix de base sur les quantités inférieures à 100 pièces.&lt;br /&gt;
: Délai &amp;quot;standard&amp;quot; de 8 jours ouvrés, plusieurs modes de livraison, possibilité de livraison plus rapide en payant plus cher.&lt;br /&gt;
: Tarif : 140€ HT pour un circuit de 100mm x 160mm double face, vernis et sérigraphie double face, avec pochoir CMS en délai 5 jours, mais cela passe à 85€ HT sur le délai standard 8 jours avec une seule face de sérigraphie.&lt;br /&gt;
: SAV / Support en Français.&lt;br /&gt;
: Possibilité de réalisations plus techniques (pistes plus fines, perçages plus fins) ou de délais plus cours (jusqu&#039;à 2 jours).&lt;br /&gt;
&lt;br /&gt;
* Dipole Electronique (http://www.dipole-electronique.fr/) : même service que PCB-Pool, mais l&#039;envoi des fichiers se fait par mail au format Gerber, le format est fixe (ils font les découpes du contour, rassurez vous), et vous avez moins d&#039;options de fabrication sur l&#039;offre &amp;quot;prototypes taille fixe&amp;quot;.&lt;br /&gt;
: Délai &amp;quot;standard&amp;quot; de 5 jours ou 10 jours.&lt;br /&gt;
: Tarif : 60€ HT pour un circuit de 100mm x 160mm double face, vernis et sérigraphie double face, &#039;&#039;&#039;sans&#039;&#039;&#039; pochoir CMS, en délai 5 jours, et 45€ HT sur le délai de 10 jours.&lt;br /&gt;
: Pochoir CMS métal en découpe laser : forfait de 70€ HT.&lt;br /&gt;
: SAV / Support en Français.&lt;br /&gt;
&lt;br /&gt;
* PCB Train : j&#039;ai été très déçu par leur prestation, lorsque vous sélectionnez les délais rapides il faut lire les petits caractères pour comprendre qu&#039;il n&#039;y aura ni vernis ni sérigraphie, la sélection des produits est globalement incompréhensible, pour un prix équivalent à PCB-Pool sans le pochoir CMS gratuit.&lt;br /&gt;
&lt;br /&gt;
* Seeed Studio (http://www.seeedstudio.com/service/) : Low cost, mais haute qualité. Envoi des fichiers en ligne au format Gerber, et peu d&#039;options (obligatoirement vernis et sérigraphie double face pour les circuits double face), mais vu le tarif, difficile de se plaindre.&lt;br /&gt;
: Délai : variable, en général l&#039;envoi se fait sous 5 jours, et possibilité de livraison gratuite si vous n&#039;êtes pas pressés (en dessous d&#039;un certain poids)&lt;br /&gt;
: Tarif : à partir de 10$ pour 5 circuits de 5cm x 5cm, prix croissant par pas de 5cm, décroissants en volume (classique) et options payantes (finition, couleur du vernis), pour comparaison, 46$ pour 5 circuits imprimés de 10cm x 15cm&lt;br /&gt;
: Pochoir CMS en métal à partir de 70$&lt;br /&gt;
: SAV / Support en Anglais.&lt;br /&gt;
: Autre avantage : la possibilité de grouper votre commande avec plein de gadgets intéressants ou d&#039;outils ou de matériel de prototypage, comme une pince brucelle à pointe fine pour le placement des composants CMS si vous n&#039;en avez pas.&lt;br /&gt;
&lt;br /&gt;
Il en existe bien entendu beaucoup d&#039;autres, mais je ne les ai pas testés. J&#039;avais trouvé une liste avec des commentaires, mais je ne la retrouve pas.&lt;br /&gt;
&lt;br /&gt;
Personnellement j&#039;utilise PCB-Pool quand j&#039;ai des contraintes spécifiques (délais, taille des pistes et perçages, ou que j&#039;ai besoin d&#039;un pochoir CMS métallique pour une production en série), et sinon soit Dipoles Electroniques pour les productions en série (made in France :) et Seeed Studio quand le budget est serré.&lt;br /&gt;
&lt;br /&gt;
Ha oui, un point hyper important que j&#039;allais oublier pour PCB-Pool : le suivi des étapes de production, avec photo de votre PCB entre chaque étape ... quoi ? je suis le seul que ça intéresse ?&lt;br /&gt;
&lt;br /&gt;
== Achat des composants ==&lt;br /&gt;
&lt;br /&gt;
[[Image:07-Kit.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Maintenant que votre circuit est en cours de fabrication, plutôt que de trépigner d&#039;impatience en attendant les informations de suivi de fabrication par email, je vous propose de vous pencher sur la commande des composants (cela vous fera un deuxième sujet d&#039;impatience pour trépigner de plus belle).&lt;br /&gt;
&lt;br /&gt;
Cette étape devrait être rapide si vous avez bien noté les références des composants sélectionnés lors de vos recherches pour la conception du circuit, mais rien ne vaut une ultime vérification. Vérifiez bien les boîtiers sélectionnés (de nombreuses références sont disponibles en plusieurs boîtiers, qu&#039;il s&#039;agisse des condensateurs et résistances (0402, 0603, 0805, ...), des diodes, transistors, régulateurs (SOT-23, SOT363, SOT-223, TO-92, SOD, ...) ou même des microcontôleurs (QFN, TQFP, TSOP, SOIC, ...).&lt;br /&gt;
&lt;br /&gt;
Deux solutions s&#039;offrent à vous. Chercher à économiser chaque centime en écumant les sites de tous les revendeurs de France et de Navare, et payer plein plein plein (plein) de frais de port (après avoir perdu encore plus de temps), ou sélectionner un unique fournisseur au catalogue bien fourni, pour éventuellement avoir les frais de port gratuits car vous commandez plus qu&#039;une certaine somme.&lt;br /&gt;
&lt;br /&gt;
Je n&#039;ai pas d&#039;accords commerciaux avec les différents fournisseurs de composants (pas plus que pour les services de fabrication de circuits imprimés, malheureusement), mais je vous conseillerais tout de même ceux que j&#039;utilise courament, à savoir Farnell, Mouser et DigiKey. Je ne peux que déconseiller Conrad (chers, site mal foutu, et encore plus chers avec un compte pro !) et Electronique Diffusion (qui renvoie vers le site all-datasheets pour les documentations techniques sans donner le fabriquant des composants vendus !!!).&lt;br /&gt;
&lt;br /&gt;
Ma préférence va à Farnell dont j&#039;aime bien l&#039;interface et le système de recherche (et la livraison gratuite le lendemain pour les comptes pro sur le stock Europe), mais c&#039;est une question de préférence personnelle, et il m&#039;arrive de commander chez les deux autres fournisseurs cités quand je ne trouve pas un composant ou quand j&#039;ai besoin d&#039;un gros volume, les réductions en volume étant parfois plus intéressantes (mais pas toujours).&lt;br /&gt;
&lt;br /&gt;
(PS : Dans le cas du module GPIO-Demo, vous pouvez aussi acheter notre Kit.)&lt;br /&gt;
&lt;br /&gt;
== ... et du matériel ==&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;êtes pas équipé, il est aussi temps d&#039;acheter le matériel manquant, il vous sera de toutes façons utile pour plein de projets, il n&#039;y a rien de spécifique.&lt;br /&gt;
&lt;br /&gt;
J&#039;ai dressé une petite liste qui devrait vous permettre de vous en sortir avec votre circuit :&lt;br /&gt;
* Un fer à souder. (Je déconseille fortement les fers sans station permettant de régler la température, une station qui tient la route coûtant dans les 60 euros, ce n&#039;est pas un investissement déraisonnable. Lisez l&#039;article sur ce sujet dans le premier numéro de &amp;quot;Hackable Magazine&amp;quot; si vous êtes sceptiques.)&lt;br /&gt;
* De l&#039;étain. (Personnellement, je n&#039;ai pas trouvé d&#039;étain sans plomb utilisable, mais vous pouvez essayer.)&lt;br /&gt;
* De la tresse à dessouder.&lt;br /&gt;
* Une pince coupante. (De préférence avec la ligne de coupe au bord des mâchoires pour pouvoir couper à ras.)&lt;br /&gt;
* Une pince brucelle&lt;br /&gt;
* Un multimètre (Avec fonction &amp;quot;bip&amp;quot; pour tester la continuité des pistes ... ou les courts-circuits :( )&lt;br /&gt;
* Une plancha. (Si si, vous avez bien lu. Tout type de poêle électrique devrait faire l&#039;affaire.)&lt;br /&gt;
* Une petite loupe. (Toujours pratique pour vérifier les soudures.)&lt;br /&gt;
&lt;br /&gt;
== Masque de soudure ==&lt;br /&gt;
&lt;br /&gt;
[[Image:07-Pochoir-01.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Il y a heureusement une deuxième activité que vous pouvez pratiquer (trépigner ne sert à rien (si si, je vous assure), et ça fatigue (au moins votre entourage)) en attendant vos cartes électroniques (et vos composants maintenant). Si vous n&#039;avez pas commandé le pochoir CMS en métal et que vous choisissez cette solution pour la soudure, c&#039;est la fabrication du pochoir CMS en plastique (à condition d&#039;avoir accès à une machine de découpe laser, mais si ce n&#039;est pas le cas il y a une alternative ... qui vous fera trépigner d&#039;impatience une fois de plus).&lt;br /&gt;
&lt;br /&gt;
Le Pochoir CMS (ou masque de soudure) est habituellement une fine feuille de métal (120 à 175 microns d&#039;épaisseur) qui est utilisée par les fabricants de cartes électroniques pour mettre la soudure sur le circuit imprimé avant le placement des composants et le passage en four pour la soudure.&lt;br /&gt;
Cette plaque est percée de trous, un pour chaque &amp;quot;pad&amp;quot; de chaque composant CMS, délimitant un volume équivalant à la quantité de soudure nécessaire pour souder la patte du composant sans faire de pâté pour qu&#039;il n&#039;y ait pas de court circuit.&lt;br /&gt;
&lt;br /&gt;
Le soucis du pochoir CMS en métal c&#039;est son prix, impossible d&#039;en inclure un dans chaque Kit du module GPIO-Démo. Il me fallait une solution alternative, et j&#039;ai donc pensé à faire la même chose avec la machine de découpe laser du FabLab de Lyon (La Fabrique d&#039;Objets Libres). Le problème, c&#039;est qu&#039;elle ne peux pas couper le métal, j&#039;ai donc du me rabattre sur le plastique.&lt;br /&gt;
&lt;br /&gt;
L&#039;étape la plus compliquée est de trouver des feuilles de plastique dont l&#039;épaisseur est spécifiée par le commerçant, et de la même épaisseur que les pochoirs métalliques, donc de l&#039;ordre de 150 microns. L&#039;épaisseur est primordiale, car c&#039;est elle qui donnera la quantité de soudure déposée.&lt;br /&gt;
&lt;br /&gt;
Les premiers plastiques que j&#039;ai trouvé avec l&#039;épaisseur spécifiée sont des rhodoids alimentaires (175 microns et 130 microns), mais ils sont difficile à acheter autrement qu&#039;en ligne, et sont souvent de grande taille (60cm x 40cm), donc pas pratiques à manipuler, mais en cherchant bien on en trouve de dimension raisonnable (A4).&lt;br /&gt;
Et je suis tombé par hasard sur des feuilles plastiques pour premières pages de dossiers (ceux que l&#039;on relie, que l&#039;on doit rendre en quatre exemplaires pour nos projets et qui finiront au fond d&#039;une poubelle dans quelques années^W semaines) dont l&#039;épaisseur est spécifiée sur la pochette : 130 microns, pile ce qu&#039;il faut, et bien moins cher que le rodhoid alimentaire, si ce n&#039;est qu&#039;il faut en acheter 100 feuilles.&lt;br /&gt;
&lt;br /&gt;
Après quelques tests réalisés au FabLab, j&#039;ai fini par obtenir un pochoir plastique très convenable à partir de la couche &amp;quot;Solder Paste&amp;quot; de KiCad, mais il faut cependant faire quelques retouches du fait de la rétractation du plastique quand il est fondu par le laser. Pour obtenir un résultat correct en prenant en compte ce problème de rétractation du plastique qui donne des trous plus grands que prévu, il faut diminuer la taille de certaines pastilles.&lt;br /&gt;
&lt;br /&gt;
Pour le faire, j&#039;utilise Inkscape après avoir exporté la couche &amp;quot;Solder Paste&amp;quot; en SVG.&lt;br /&gt;
Il faut commencer par dégrouper toutes les pastilles, sans quoi leur position change quand on applique la réduction au groupe. Il faut ensuite ne laisser que les bords, qui seront les traits de coupe, car KiCad exporte des rectangles pleins.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez enfin sélectionner les pastilles &amp;quot;de taille moyenne&amp;quot; pour les réduire de 20 à 60% (selon l&#039;épaisseur du plastique que vous avez trouvé, le type de plastique, et la puissance du laser lors de la découpe, et le type de composant).&lt;br /&gt;
&lt;br /&gt;
Je sais que &amp;quot;de taille moyenne&amp;quot; ne veut rien dire du tout, et je vais donc l&#039;expliquer.&lt;br /&gt;
Il n&#039;est pas nécessaire de faire de modification pour les grandes pastilles comme les pattes de fixation de connecteurs ou les plans de masse des régulateurs de tension. Passé 3mm x 3mm, il faut laisser la pastille telle quelle.&lt;br /&gt;
Il en va de même pour les composants en boîtier 0402, car si le trou est trop petit la soudure colle au plastique et reste dans le trou du pochoir quand on le retire, ce qui n&#039;est pas l&#039;effet recherché.&lt;br /&gt;
Pour tous les autres trous, il faut appliquer une réduction, plus ou moins grande en fonction de la feuille de plastique, mais aussi du type de composant et de l&#039;espacement des broches. Pour les circuits intégrés comme le microcontrôleurs du module, mais aussi l&#039;EEPROM, la porte multifonction, ou le capteur de température, je fais une réduction plus importante (50% à 60%) que pour le reste des composants (20% à 40%), pour limiter ou supprimer les courts-circuits lors de la soudure qui se produisent quand il y a trop de soudure.&lt;br /&gt;
&lt;br /&gt;
Une fois les pastilles réduites (en veillant bien à conserver leur position), vous pouvez ajouter un contour pour que le pochoir se détache de la feuille. Veillez dans ce cas à le faire plus grand que le circuit imprimé, ce qui permettra de le fixer, et faites attention à ne pas faire un contour continu, sans quoi le plastique risque de se replier pendant la découpe du fait de l&#039;aspiration. Pour éviter cela, il suffit de laisser de petits espaces qui rattachent le pochoir au reste de la feuille (moins de 1mm de large), ce qui maintiendra le pochoir pendant la découpe et permettra de détacher le pochoir sans outils, juste en tirant dessus.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez maintenant aller au FabLab le plus proche si vous en avez un qui ait une machine de découpe Laser pour faire votre découpe.&lt;br /&gt;
Si ce n&#039;est pas le cas, vous pouvez demander à un FabLab qui en a une, si ils peuvent vous faire la découpe en leur envoyant le plastique et une enveloppe timbrée pour le retour, avec un petit quelque chose pour le travail, négocié avec eux au préalable (et tous les FabLab de France qui ont une découpe Laser vont me maudire).&lt;br /&gt;
Ou bien utiliser les services de Pololu, qui proposent cette solution depuis quelques temps, soit parce qu&#039;ils ont fait le même constat et eu la même idée que moi, soit parce que mon idée a voyagé (laissez moi croire en la deuxième solution svp), même si ils proposent ce service un peu cher à mon goût. http://www.pololu.com/product/446&lt;br /&gt;
&lt;br /&gt;
Et enfin, avant d&#039;utiliser le pochoir, je le &amp;quot;racle&amp;quot; avec une règle métallique pour enlever les surépaisseurs de plastique sur les bords des trous, du fait de la rétractation du plastique pendant la découpe.&lt;br /&gt;
&lt;br /&gt;
Vous voila avec un (joli) pochoir CMS à moindre frais (en tout cas normalement bien moins de 70 euros), même si il ne tiendra pas des centaines d&#039;utilisation, et ne peux pas être nettoyé à l&#039;acétone. J&#039;en ai utilisé certains une dizaine de fois, et je me sers d&#039;une petite épingle pour nettoyer les restes d&#039;étain une fois sec.&lt;br /&gt;
&lt;br /&gt;
== Assemblage ==&lt;br /&gt;
Après quelques (trop nombreux) jours d&#039;attente, vous avez enfin reçu votre circuit imprimé et vos composants, et vous allez pouvoir attaquer la suite des réjouissances :)&lt;br /&gt;
&lt;br /&gt;
Bien entendu, il existe des sociétés spécialisées dans la réalisation des étapes suivantes pour des prototypes, mais les coût sont souvent non négligeables, et le résultat pas toujours au rendez-vous (composants inversés, mal soudés, ...).&lt;br /&gt;
A noter que certaines sociétés de fabrication de PCB proposent ce service ... à condition que vous utilisiez un logiciel propriétaire pour envoyer les données d&#039;assemblage :(&lt;br /&gt;
&lt;br /&gt;
=== Dépose de l&#039;étain ===&lt;br /&gt;
&lt;br /&gt;
[[Image:07-Pochoir-02.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Mais attention, ne vous précipitez pas, il faut commencer par un petit check-up, il est encore temps.&lt;br /&gt;
Avant de mettre de l&#039;étain plein partout, vérifiez que vous avez bien reçu tous les composants, que vous n&#039;en avez pas oublié, et que les empreintes correspondent bien. Il est encore temps de commander les références manquantes, en revanche, une fois l&#039;étain appliqué avec le pochoir, il commence à sécher, et même si il est toujours possible de positionner les composants plus tard, c&#039;est bien plus sympa quand ils &amp;quot;collent&amp;quot; dans le &amp;quot;gel&amp;quot; qui compose l&#039;étain &amp;quot;en pâte&amp;quot; (ou crème à braser, ou étain &amp;quot;liquide&amp;quot;, qui n&#039;est autre que des micro billes d&#039;étain dans un gel).&lt;br /&gt;
&lt;br /&gt;
Vous avez tout ? Bien. Pas d&#039;erreur de miroir sur les pattes des composants ? Parfait ! (Et oui, c&#039;est du vécu).&lt;br /&gt;
&lt;br /&gt;
Mais avant de vous lancer, un dernier préparatif : vérifiez que vous avez accès à un schéma de votre carte, pour pouvoir placer les composants au bon endroit une fois l&#039;étain déposé sur le circuit.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; : Pour ceux qu&#039;un texte et quelques photos ne sauraient contenter, j&#039;ai fait une vidéo de l&#039;assemblage du module GPIO Demo, voir le lien en fin d&#039;article.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez enfin attaquer les choses sérieuses, et dans une petite heure (ou moins, parce que vous êtes très fort) vous aurez votre nouveau jouet rien qu&#039;à vous.&lt;br /&gt;
&lt;br /&gt;
La première étape, dégraisser le circuit imprimé, pour que le gel adhère bien. Frottez le légèrement avec un chiffon non abrasif et un peu d&#039;alcool, sans insister (normalement les circuits arrivent relativement propres, mais nos doigts ne le sont pas toujours).&lt;br /&gt;
&lt;br /&gt;
Ensuite, le plus simple pour fixer le circuit pour l&#039;application de l&#039;étain avec le pochoir (ou tout autre méthode en fait) c&#039;est la &amp;quot;patafix&amp;quot; (ou tout équivalent, je n&#039;ai pas d&#039;actions non plus). Cette matière semi collante permet de maintenir en même temps le circuit imprimé et le pochoir CMS que vous allez devoir aligner correctement. Pour cette opération, le pochoir en plastique transparent offre un très net avantage sur son homologue en métal opaque, mais on s&#039;en sort dans tous les cas. Veillez à ce que la patafix n&#039;empêche pas le pochoir d&#039;être parfaitement plaqué au circuit imprimé.&lt;br /&gt;
&lt;br /&gt;
Déposez un (tout petit) peu d&#039;étain sur le pochoir (si vous avez de l&#039;étain en seringue c&#039;est plus pratique), et étalez le avec une spatule (j&#039;utilise un morceau de pochoir métallique découpé dans un vieux pochoir inutile, et j&#039;ai mis un morceau &amp;quot;prédécoupé&amp;quot; sur les pochoirs en plastique du kit du module GPIO Demo, mais n&#039;importe quel morceau de plastique avec un bord droit fait l&#039;affaire).&lt;br /&gt;
Appuyez bien sur le pochoir pour qu&#039;il reste plaqué au circuit pendant toute l&#039;opération, mais sans le faire bouger.&lt;br /&gt;
Remplissez bien tous les trous, puis raclez l&#039;étain qui est en trop, pour qu&#039;il ne reste que la bonne quantité d&#039;étain dans les trous.&lt;br /&gt;
&lt;br /&gt;
Vous pouvez maintenant passer au plus délicat, retirer le pochoir sans le faire bouger, et en laissant l&#039;étain sur le circuit imprimé. Ne paniquez pas, vous pourrez recommencer plusieurs fois si besoin.&lt;br /&gt;
J&#039;ai constaté que pour bien laisser tout l&#039;étain sur le circuit il faut retirer le pochoir en le pliant, comme si il s&#039;enroulait autour d&#039;un rouleau.&lt;br /&gt;
&lt;br /&gt;
Vérifiez bien qu&#039;il ne reste pas (ou presque) d&#039;étain dans les trous du pochoir, et si vous êtes satisfaits du résultat vous pouvez passer à la suite. Vérifiez aussi que l&#039;étain ne se soit pas glissé sous le pochoir pendant l&#039;application pour former de gros pâtés. Sinon, nettoyez le pochoir (sommairement) et recommencez à l&#039;étape ... un peu plus haut quoi.&lt;br /&gt;
&lt;br /&gt;
=== Placer les composants ===&lt;br /&gt;
&lt;br /&gt;
[[Image:08-Placement-01.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Il ne vous reste que quelques étapes, mais celle-ci est peut-être bien la plus minutieuse, et la plus longue.&lt;br /&gt;
&lt;br /&gt;
Vous allez maintenant pouvoir placer les composants CMS sur votre circuit. Attention, ne placez pas les composants traversants, ils gêneraient pour l&#039;étape suivante.&lt;br /&gt;
&lt;br /&gt;
Personnellement je préfère commencer par les petits composants, car ils collent au gel quand celui-ci est bien frais, et ne bougent plus quand on tourne ou déplace le circuit imprimé.&lt;br /&gt;
Pour ce faire, j&#039;utilise une pince brucelle avec une pointe très fine, mais une simple pince à épiler peut faire l&#039;affaire.&lt;br /&gt;
&lt;br /&gt;
Une fois le composant positionné correctement, c&#039;est à dire avec toutes les pattes ou les extrémités au dessus d&#039;un plot de soudure, j&#039;applique une petite pression sur le composant pour qu&#039;il colle bien au gel et ne bouge plus par la suite. Cela évite notamment les composants qui se déplacent pendant que l&#039;étain fond et se retrouvent en l&#039;air, soudés par une seule patte ou d&#039;un seul côté.&lt;br /&gt;
&lt;br /&gt;
Attention à ne sortir qu&#039;une référence de composants à la fois, ils sont tellement petits qu&#039;il est difficile de lire les références sur les composants, ou même n&#039;ont pas de références imprimée du tout (les condensateurs et les inductances par exemple).&lt;br /&gt;
&lt;br /&gt;
Attention aussi au sens pour les composants polarisés (diodes, leds, certains condensateurs) ou avec plus de deux pattes. Il y a le plus souvent un indicateur, parfois sous le composant (pour les leds), parfois difficile à détecter, et il faut alors se référer à la documentation technique (ou utiliser une loupe, ou les deux).&lt;br /&gt;
&lt;br /&gt;
Continuez avec les références suivantes, pour finir par les plus gros composants, que je place en dernier pour qu&#039;ils ne gênent pas pour la pose des autres composants, mais aussi parce qu&#039;une fois que le gel a un peu séché il est possible de bouger le composant sans déplacer l&#039;étain, et de ne le &amp;quot;faire tenir&amp;quot; par une petite pression que lorsque le positionnement est bon.&lt;br /&gt;
&lt;br /&gt;
Allez, plus que quelques composants à placer, courage ! (Oui, on a créé des machines pour ça, mais elles ne sont pas dans nos budgets).&lt;br /&gt;
&lt;br /&gt;
=== Soudure CMS ===&lt;br /&gt;
&lt;br /&gt;
[[Image:08-Plancha-01.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Passons aux choses sérieuses : sortez la plancha !&lt;br /&gt;
&lt;br /&gt;
Pour souder des composants CMS il existe différentes méthodes, mais si l&#039;on en croit les tests que l&#039;équipe de Sparkfun a réalisé le plus efficace c&#039;est la plancha (ou toute surface chaude équivalente : poêle électrique, machine à crêpes, ou même une vieille poêle sur le gaz (attention aux problèmes conjugaux ...)).&lt;br /&gt;
&lt;br /&gt;
Cette étape est la plus simple : on pose le circuit imprimé sur la plancha (composants sur le dessus bien entendu), on la branche, et on attends.&lt;br /&gt;
C&#039;est aussi la plus dangereuse : la plancha va atteindre plus de 250°C ! Gare aux brulures, à ne faire qu&#039;accompagné d&#039;un adulte (responsable ? ça existe ?).&lt;br /&gt;
En fonction de la puissance de la plancha, cela dure entre 2 et 5 minutes, et l&#039;étain se met à fondre, soudant les composants.&lt;br /&gt;
On voit très bien quand l&#039;étain fond car il devient brillant.&lt;br /&gt;
&lt;br /&gt;
Une fois que le processus a commencé, cela va très vite, et il ne faut pas insister si quelques points ne veulent pas fondre tout de suite, car les autres composants sont entrain de cuire. Il faut retirer la carte de la plancha tout de suite, en faisant bien attention à la garder à l&#039;horizontal car ils ne sont plus tenus en place par le gel. Si vous inclinez la carte à ce moment la, les composants vont glisser (Il faut entre 4 et 10 secondes à l&#039;étain pour solidifier). Pour cela les plancha sont bien pratiques car elles ont généralement une zone sans rebord, ce qui permet de faire glisser la carte vers le bord et de la saisir avec une pince avant de la déposer sur une surface protégée (surtout pas sur du plastique, elle est autour de 200°C !)&lt;br /&gt;
&lt;br /&gt;
Ça y est, c&#039;est fait, c&#039;est soudé ! Enfin ...&lt;br /&gt;
&lt;br /&gt;
=== Reprise des faux contacts ===&lt;br /&gt;
&lt;br /&gt;
[[Image:08-Shorts-01.png|400px|right]]&lt;br /&gt;
&lt;br /&gt;
Bon, en théorie, tout c&#039;est bien passé et il n&#039;y a pas de faux contacts.&lt;br /&gt;
Malheureusement, même avec un pochoir CMS métallique certaines pattes de circuits intégrés peuvent être reliées par de l&#039;étain si il y en avait un petit peu trop.&lt;br /&gt;
&lt;br /&gt;
Dans ce cas là, pas d&#039;affolement, la première chose à faire : ne surtout pas prendre le fer à souder ou remettre la carte sur la plancha. La première étape est de reprendre le schéma de la carte.&lt;br /&gt;
&lt;br /&gt;
Et oui, j&#039;ai parfois passé près d&#039;une demie heure à tenter d&#039;enlever la soudure qui faisait contact entre deux pattes ... reliées par un fil sur le schéma.&lt;br /&gt;
&lt;br /&gt;
Si effectivement le schéma dit qu&#039;il ne devrait pas y avoir de contact, utilisez la tresse à dessouder et le fer pour enlever le surplus d&#039;étain, en mettant un morceau propre de la tresse à dessouder entre l&#039;étain à enlever et le fer à souder. Testez avec le multimètre pour vérifier que le court-circuit a bien disparu.&lt;br /&gt;
&lt;br /&gt;
Il faut aussi finir de souder les composants des bords de la carte qui n&#039;auraient pas été soudés sur la plancha.&lt;br /&gt;
Pour ceux-ci, pas besoin de rajouter de soudure, il suffit de poser le fer à souder (chaud) très proche de la pastille (ou sur la pastille) pour que l&#039;étain fonde et soude le composant.&lt;br /&gt;
&lt;br /&gt;
Profitez-en pour vérifier que tous les composants sont bien soudés des deux côtés.&lt;br /&gt;
&lt;br /&gt;
Attention, vous pourrez avoir l&#039;impression que certains composants sont mal soudés ou qu&#039;il n&#039;y a pas assez de soudure car la quantité de soudure utilisée avec cette méthode est très faible et que la soudure ne forme pas de pâté. C&#039;est normal. Pour vous rassurer, vous pouvez utiliser la même méthode que pour finir de souder les composants dont l&#039;étain n&#039;avait pas fondu à la plancha. Vous verrez alors l&#039;étain briller un peu plus, et re-solidifier lorsque vous retirez le fer.&lt;br /&gt;
&lt;br /&gt;
=== Soudure des composants traversants ===&lt;br /&gt;
&lt;br /&gt;
Avant dernière étape avant de jouer avec votre circuit : souder les composants traversants, et éventuellement ajouter de la soudure sur les pads de fixation des gros composants et des connecteurs.&lt;br /&gt;
&lt;br /&gt;
Pour cela rien de magique (quoique, voir l&#039;astuce qui suit). Mettez en place le composant (attention au brochage si il y en a un), positionnez votre fer à souder en contact avec le circuit imprimé et la patte du composant que vous voulez souder, puis apportez la soudure, et retirez la soudure et le fer (dans cet ordre).&lt;br /&gt;
&lt;br /&gt;
Petite astuce : utilisez de la patafix pour maintenir le composant en place et pour maintenir le circuit sur le plan de travail. Depuis que j&#039;utilise cette technique ma troisième main sert de support aux toiles d&#039;araignées ...&lt;br /&gt;
&lt;br /&gt;
== Tests ==&lt;br /&gt;
&lt;br /&gt;
Dernière étape avant de passer à la programmation, qui fera l&#039;objet du prochain article : les tests électriques.&lt;br /&gt;
&lt;br /&gt;
Ne mettez pas votre circuit sous tension tout de suite, certains composants ne tiennent pas longtemps en cas de court circuit, même alimentés par l&#039;USB.&lt;br /&gt;
&lt;br /&gt;
Utilisez le multimètre pour vérifier qu&#039;il n&#039;y a pas de court circuit entre le +5V et la masse, entre le +3V et la masse, et pour ne pas risquer d&#039;endommager les ports USB de votre PC/HUB (certains sont très fragiles), vérifiez aussi entre les deux pistes USB (D+ et D-) et la masse et le +5V.&lt;br /&gt;
&lt;br /&gt;
Si vous n&#039;êtes pas trop impatient, vous pouvez aussi tester entre chaque pattes consécutives des circuits intégrés, mais vérifiez bien le schéma en même temps, toujours pour éviter de passer des heures à vouloir enlever un court-circuit qui n&#039;en est pas un.&lt;br /&gt;
&lt;br /&gt;
Tous est bon ? et bien c&#039;est fini pour cette fois.&lt;br /&gt;
&lt;br /&gt;
Si vous avez réalisé le circuit du module GPIO Demo, vous pouvez le connecter sur un port USB de votre PC.&lt;br /&gt;
&lt;br /&gt;
Le microcontrôleur doit se mettre automatiquement en mode programmation (ISP) et la led bicolore doit faire apparaitre deux point lumineux très très faibles (vert et rouge).&lt;br /&gt;
&lt;br /&gt;
Si votre noyau a bien le support FTDI (suffisamment récent pour avoir le composant FT230XS, plus récent que 2.6.28 de mémoire), vous aurez alors un nouveau ttyUSB (présent dans /dev/, et annoncé dans les logs du noyau), et en envoyant le caractère &#039;?&#039; le microcontrôleur devrait répondre &amp;quot;Synchronised&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Rendez-vous dans l&#039;article suivant pour l&#039;écriture du code en C, la compilation, et la programmation avec l&#039;utilitaire lpcprog :)&lt;br /&gt;
&lt;br /&gt;
+++&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Liens ==&lt;br /&gt;
FabLabs :&lt;br /&gt;
* [http://www.electrolab.fr/ ElectroLab de Nantère]&lt;br /&gt;
* [http://www.fablab-lyon.fr/ Fabrique d&#039;Objets Libres] (FabLab de Lyon)&lt;br /&gt;
Informations sur la fabrication de circuits imprimés :&lt;br /&gt;
* http://wiki.jelectronique.com/realisation_de_circuits_imprimes&lt;br /&gt;
* http://alain.canduro.free.fr/circuits.htm&lt;br /&gt;
Fabricants de circuits imprimés :&lt;br /&gt;
* [https://www.pcb-pool.com/ PCB-Pool]&lt;br /&gt;
* [http://www.dipole-electronique.fr/ Dipole-Electronique]&lt;br /&gt;
* [http://www.seeedstudio.com/service/ Seeed Studio]&lt;br /&gt;
Module GPIO Demo :&lt;br /&gt;
* [http://www.techno-innov.fr/technique-module-gpio-demo/ Page du module sur notre site]&lt;br /&gt;
* [https://www.youtube.com/watch?v=dtVMRGIdkGQ Vidéo de l&#039;assemblage du module sur Youtube]&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
	<entry>
		<id>https://wikifr.techno-innov.fr/index.php?title=Fichier:08-Shorts-01.png&amp;diff=103</id>
		<title>Fichier:08-Shorts-01.png</title>
		<link rel="alternate" type="text/html" href="https://wikifr.techno-innov.fr/index.php?title=Fichier:08-Shorts-01.png&amp;diff=103"/>
		<updated>2020-09-02T20:55:57Z</updated>

		<summary type="html">&lt;p&gt;Nathael : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Nathael</name></author>
	</entry>
</feed>