L'arduino est devenu le microcontroleur[1](µC) à tout faire. De part sa communauté, de nombreuses bibliothèques et programmes sont proposés et disponibles pour nombre d'utilisations. Nous allons aujourd'hui en découvrir une un peu particulière. Nous allons apprendre à (re)programmer un autre microcontroleur à l'aide d'un arduino.
Charger un programme dans un arduino est très simple, cela grà¢ce au bootloader chargé dans l'ATmega. Basiquement, ce petit programme exécuté au démarrage de votre arduino récupère le code via la liaison usb et programme l'ATmega de la carte[2]. Si rien ne lui est envoyé, alors il démarre le programme déjà présent dans la mémoire flash. Le bootloader ou le programme à exécuter sont stockés dans 2 zones mémoires différentes.
Seulement il peut arriver que ce bootloader soit cassé[3] ou ne soit pas présent[4]. De plus, un certain nombre de µC ne peuvent pas héberger de bootloader. Dans ce cas, il faut les programmer autrement. On utilise alors un programmeur qui se charge de cette tà¢che.
Les µC d'atmel disposent en général d'une fonction très utile : l'ISP (In-System Programming). Celle-ci permet de les reprogrammer à l'aide de 4 fils, alors qu'ils sont déjà dans un montage. Nous allons utiliser cette fonction pour reprogrammer notre arduino.
Exemple avec un ATtiny45
Commençons par programmer un simple petit ATtiny45 (cible) à l'aide d'un arduino Duemilanove (programmeur).
Il nous faut d'abord utiliser le sketch ArduinoISP présent dans les exemples fournis avec l'IDE de l'arduino. Vous pouvez aussi le télécharger sur le site mega-isp. Compilez le et chargez le dans l'arduino.
Note: par défaut la vitesse utilisée lors de la (future) programmation de la cible est de 19200bps, vous pouvez changer cela dans le code, mais il faudra alors penser à reporter cette valeur dans les commandes de programmation.
Depuis la version Diecimila les arduino intègrent une fonction d'auto-reset qui permet de redémarrer la carte (et donc lancer le bootloader) quand une communication série débute[5]. C'est très utile pour programmer l'arduino, mais cela va nous poser problème ici. Nous devons donc le désactiver. Pour notre version Duemilanove, le plus simple et le moins intrusif est de relier le reset au +5V par une résistance de 120ohms, ce qui maintiendra le reset à l'état haut[6]. Je vous laisse voir le site officiel pour les autres méthodes.
Ensuite, nous relions les différentes pattes nécessaires pour la programmation ISP :
Arduino ATTiny45 Fonction 10 1 reset 11 5 MOSI 12 6 MISO 13 7 SCK
Référez vous à la datasheet de votre µC pour connaitre les pattes à relier.
Enfin, le sketch ArduinoISP utilise 3 leds d'état que vous relierez à la masse via une résistance adéquate[7].
Arduino led (anode) 7 jaune: programation en cours 8 rouge: erreur 9 vert : heartbeat
Voici le schéma du montage sur plaque à essai :
Vous pouvez ignorer la led verte de gauche, elle ne sert qu'a tester le programme chargé.
Enfin, vient le moment tant attendu, vous pouvez connecter l'arduino à l'USB et programmer votre ATtiny en utilisant avrdude :
avrdude -V -p t45 -c avrisp -b 19200 -P /dev/ttyUSB0 -U flash:w:led.hex
Quelques mots sur les options (voyez la doc pour les détails) :
- -p t45 : pour dire que l'on programme un ATtiny45
- -c avrisp : le type de programmeur utilisé
- -b 19200 : la vitesse de la liaison (à changer éventuellement en fonction du code de ArduinoISP)
- -P /dev/ttyUSB0 : le port sur lequel est connecté votre arduino
- -U flash:w:led.hex : on écrit (w) dans la flash le programme compilé led.hex
Et voila, selon votre programme de test, la led devrait commencer à clignoter.
Programmer un arduino à partir d'un arduino
Attention: Pour pouvoir programmer plus de 256 octets (ce qui va être nécessaire pour la suite), il vous faut utiliser ArduinoISP de l'IDE version 22 minimum, ou utiliser les sources prises sur mega-isp vues ci-dessus. C'est un bug connu de l'IDE 21
Nous allons reprogrammer le bootloader de l'arduino. On peut avoir de nombreuses raisons de faire cela: pour le réparer, pour préparer un nouveau µC, pour le remplacer par une version plus efficace. Dans mon cas, c'est cette dernière opération que je veux réaliser. Le bootloader du Duemilanove, empêche l'utilisation du watchdog dans les programmes. On trouve la correction dans des bootloader alternatifs[8] ou dans celui de l'arduino UNO (optiboot). Ce dernier étant compatible avec la majorité des versions précédentes, nous allons donc l'utiliser. Ceci impliquera de choisir Arduino Uno dans le menu Board de l'IDE lors des prochaines programmation, puisque le bootloader sera celui de l'Uno. Je vous conseille d'y coller une étiquette pour ne pas l'oublier.
Notre arduino programmeur sera préparé de la même manière que ci-dessus, c'est-à -dire qu'on lui chargera le sketch ArduinoISP. On le connecte alors vers les pattes ISP de notre arduino cible. On peut utiliser soit le connecteur ICSP soit relier directement aux connecteurs femelle sur lesquels on branche habituellement les shields.
Note: On peut aussi se contenter d'un seul arduino (programmeur) et utiliser une plaque à essai pour simuler le 2ème. Dans ce cas, les différentes options sont décrites sur le site officiel.
Voyez ci-dessous les connexions à établir.
La cible doit être alimentée. Vous pouvez faire cela via l'USB, mais je le déconseille ainsi, vous n'aurez qu'un seul /dev/ttyUSBx et c'est un risque d'erreur en moins. Utilisez plutôt l'entrée VIN de l'arduino à programmer.
Il ne nous reste plus qu'à utiliser l'IDE pour flasher la cible.
- choisir ce que vous allez programmer dans le menu Tools / Board :
- UNO pour avoir l'optiboot
- ou bien duamilanove avec atmega328
- ou autre chose suivant votre modèle d'arduino
- puis Tools / Burn Bootloader / w/Arduino as ISP
Note: Si vous avez changé la vitesse dans le sketch ArduinoISP, il vous faudra mettre à jour le paramètre arduinoisp.speed présent dans le fichiers programmers.txt[9], soit directement, soit en le surchargeant via votre fichier preferences.txt[10]
Nous pouvons aussi utiliser avrdude pour faire cela à l'ancienne. il suffit d'enchainer les 3 commandes suivantes, voir de les regrouper en une seule[11]
Vous trouverez les valeurs de fuses et les fichiers de bootloader dans le fichier texte boards.txt de votre installation[12]. Les différents fichiers hex du bootloader sont dans un sous répertoire bootloaders[13]. Rappelons que les commandes suivantes s'appliquent pour programmer un optiboot sur un arduino Duemilanove.
La 1ère action est de débloquer l'accès au bootloader :
avrdude -p m328p -P /dev/ttyUSB0 -c avrisp -b 19200 -e -U lock:w:0x3F:m
Ensuite, il faut flasher le bootloader :
avrdude -p m328p -P /dev/ttyUSB0 -c avrisp -b 19200 -D -U flash:w:optiboot_atmega328.hex
notons que vous pouvez relire le fichier flashé ainsi :
avrdude -p m328p -P /dev/ttyUSB0 -c avrisp -b 19200 -D -U flash:r:read.hex:i
et enfin rebloquer l'accès au bootloader :
avrdude -p m328p -P /dev/ttyUSB0 -c avrisp -b 19200 -U lock:w:0x0F:m
Programmer directement un arduino (Bitbang FT232)
Note: Je n'ai pas personnellement utilisé cette technique, ce que vous vous apprêtez à lire n'est donc que ma compréhension résultant de mes lectures. Cela-dit de nombreux témoignages existent sur sa viabilité et elle est visiblement beaucoup utilisée.
Une autre méthode pour reprogrammer le bootloader de votre arduino est la technique dite BitBang. Elle utilise un mode particulier du chipset FTDI présent sur les arduino. Ce mode permet de jouer directement avec les pattes de sorties du chipset et ainsi de l'utiliser pour simuler un programmeur ISP.
Le principe est donc de relier les pattes du FTDI au connecteur ICSP de l'arduino. pour cela il vous faudra souder une barette sur les trous 1 à 4 nommés X3 sur votre arduino. Puis d'établir les connexions nécessaires avec le connecteur ICSP dont nous avons déjà parlé.
La deuxième étape est de patcher avrdude pour lui ajouter un nouveau programmeur[14]. Et enfin de reprogrammer celui-ci avec avrdude en lui donnant le bon fichier .hex à manger.
L'énorme avantage de cette méthode est bien entendu que vous n'avez besoin que d'un seul arduino, et qu'il peut donc se reprogrammer lui-même. Les inconvénients sont que vous devez souder sur votre arduino et utiliser un autre avrdude que celui fournit avec l'environnement de programmation standard.
Pour plus de détails, je vous renvoi vers les liens suivants :
- les pointeurs du site officiel
- un pas-à -pas pour patcher avrdude 5.10
- le site et la vidéo de l'inventeur de la technique
Un vrai programmeur
Pour autant que ces techniques soient amusantes leur mise en place et utilisation devient vite assez lourde. Cela est très bien pour un besoin ponctuel, mais pour une utilisation régulière, je ne saurais trop vous conseiller d'acheter un vrai programmeur de µC. Pas besoin de dépenser des centaines d'€ pour cela. On trouve facilement des programmeur ISP pour pas cher. Notons en particulier le USBtinyISP de LadyAda[15]. Une simple recherche avec stk500 ou avrisp vous renverra aussi une foultitude de résultats sur un site d'enchères bien connu.
Ainsi, vous économiserez un arduino et vous vous simplifierez la vie. Plus rapides, plus sur et plus transportables, ils ont tout pour plaire. Il ne vous reste alors qu'à prévoir un connecteur ISP sur vos montages et hop. On peut aussi réaliser un petit adaptateur comme ci-dessous pour l'utiliser facilement sur une plaque à essais.
Voila, félicitations aux courageux qui sont arrivés jusqu'ici, et si vous avez des questions ou des remarques, les commentaires sont ouverts[16].
Notes
[1] oui, je sais c'est plus qu'un µC (régulateur, liaison usb ...)
[2] ie: charge le code dans la mémoire fash
[3] par une fausse manip
[4] cas d'un atmega neuf
[5] basé sur le passage de DTR au niveau bas
[6] il est actif à l'état bas, vous l'aurez compris
[7] 330ohms pour mes leds
[9] dans /usr/share/arduino/hardware/arduino/ chez moi
[10] dans ~/.arduino
[11] en gardant le même ordre pour les options -U
[12] chez moi dans /usr/share/arduino/hardware/arduino/
[13] soit /usr/share/arduino/hardware/arduino/bootloaders/ chez moi
[14] à utiliser via l'option -c
[15] je vous jure, que je n'ai pas d'actions chez AdaFruit !
[16] Je ne pouvais pas finir sans une dernière note de bas de page :)
Commentaires du post original