Bootloader Arduino

De Les Fabriques du Ponant
Aller à : navigation, rechercher

Sur une carte ARDUINO UNO ou NANO par exemple, lorsque l'on appuie sur le bouton RESET, le bootloader fait clignoter la LED de la sortie D13 trois fois. Si ce n'est pas le cas, pas de doute à avoir, le bootloader est absent.

Le bootloader est un composant logiciel ayant deux fonctions principales :

  • chargement d'une application dans la mémoire FLASH du microcontrôleur à partir de la ligne série
  • lancement de l'application

fonctionnement de ce bootloader.

Au démarrage le bootloader attend pendant un certain temps la réception d'un caractère sur la ligne série. Si aucun caractère n'est reçu l'application est démarrée. Cela a donc une conséquence directe : le démarrage est ralenti par cette attente.

1.1. Le protocole Le logiciel PC en charge du chargement de l'application se nome AVRDUDE. Le protocole utilisé pour le chargement est le STK500 (STK500V2 pour une carte MEGA). Qu'est ce qu'un protocole ? C'est un ensemble de règles qui permettent la compréhension mutuelle d'une conversation entre deux logiciels en vis-à-vis, reliés par un canal de communication : ligne série, Ethernet, radio, etc. Le protocole fixe la grammaire à utiliser pour la conversation :

  • démarrage de la conversation
  • envoi d'une adresse de chargement
  • effacement d'une page de FLASH
  • envoi des données binaires
  • etc.

Dans le cas du STK500 le caractère utilisé pour démarrer la conversation est : GET_SYNCH : 0x0F Le bootloader répond : STK_INSYNC : 0x14.

Cet article (j'aime le titre : Everything You Always Wanted to know about Arduino Bootloading but Were Afraid to Ask) explique en détail le déroulement d'un chargement : https://baldwisdom.com/bootloading/

Celui-ci donne quelques explications concernant le code source : https://www.electronicwings.com/arduino/basics-to-developing-bootloader-for-arduino

1.2. Les différentes versions La conversation entre AVRDUDE et le bootloader n'est pas identique pour toutes les cartes, ce qui explique que si l'on choisit le mauvais type de carte dans le menu de l'IDE il peut arriver certaines mésaventures :


        Using Port                    : /dev/ttyUSB1
        Using Programmer              : arduino
        Overriding Baud Rate          : 115200
        avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x4f

Ce message est une erreur signifiant : le bootloader a envoyé un caractère inattendu. Sa réponse ne correspond pas à la demande.

Cela arrive en particulier lorsque l'on essaie de charger une application dans une carte ARDUINO NANO ayant été chargée avec un bootloader nouvelle génération alors que l'on a sélectionné "ATmega328p (Old Bootloader)" dans le menu Outils / Processeur, ou l'inverse.

L'explication se trouve dans le fichier boards.txt, situé sous dans un répertoire local de l'utilisateur : LINUX : /home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/ username étant notre identifiant utilisateur WINDOWS : C:\Program Files (x86)\Arduino\hardware\arduino\avr

Dans ce fichier, pour chaque type de carte, un paramètre permet de fixer le nom du bootloader utilisé :


uno.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex
nano.menu.cpu.atmega328.bootloader.file=optiboot/optiboot_atmega328.hex
nano.menu.cpu.atmega328old.bootloader.file=atmega/ATmegaBOOT_168_atmega328.hex

On voit bien que les cartes n'utilisent pas toutes le même bootloader. Cela explique aussi pourquoi, si l'on choisit la carte "Arduino / Genuino UNO" dans le menu Outils, le chargement d'une application est possible sur une NANO, et vice-versa. En effet le bootloader est le même, et de plus cela ne pose aucun problème.

2.2. Programmateur utilisant une UNO ou NANO On peut utiliser une carte additionnelle pour charger le bootloader sur une carte quelconque, c'est à dire que la deuxième carte va être utilisée en tant que programmateur. Cette page explique les raccordements à effectuer entre les deux cartes : https://www.arduino.cc/en/tutorial/arduinoISP

On peut donc charger un bootloader dans une carte nommée TARGET en utilisant une carte nommée PROGRAMMER. Toutes les combinaisons sont possibles : - UNO et UNO - UNO et NANO - MEGA et UNO - NANO et UNO - etc.

Voici le cas le plus courant (2 UNOs) :

C'est très simple comme on peut le voir. Les raccordements sont effectués à l'aide de classiques fils DUPONT. Il peut arriver qu'un fil DUPONT soit défectueux. Il vaut mieux les tester à l'ohmmètre avant de les utiliser. Le bus SPI n'est pas si facile à déboguer, à moins de disposer d'un analyseur de signaux.

La carte appelée PROGRAMMER (celle qui va servir de programmateur) doit être reliée au PC à l'aide d'un cordon USB.

La carte TARGET (celle qui va recevoir le bootloader) est reliée à la première à l'aide de 6 fils. Ensuite un sketch spécialement prévu doit être chargé dans la carte PROGRAMMER. Cette application permet donc de transformer une carte quelconque en programmateur ISP :

Menu Fichier / Exemples / 11. ArduinoISP / ArduinoISP

Avant de compiler et charger ce sketch il faut d'abord sélectionner le type de carte (Outils / Type de carte).

Important : il s'agit ici de sélectionner le type de la carte PROGRAMMER, pas celui de la carte TARGET.

Il faut aussi sélectionner le bon port Série dans le menu Outils / Port.

Compiler et charger ce sketch (bouton Téléverser).

2.3. Charger le bootloader Pour ce faire il faut procéder comme suit :

Sélectionner le bon programmateur :

  • USBasp si vous possédez un programmateur USBASP
  • USBtinyISP si vous possédez un programmateur USBTINY
  • Arduino As ISP si vous utilisez une carte ARDUINO comme programmateur
  • etc.

Sélectionner le type de carte cible.

Important : il s'agit ici de sélectionner le type de la carte TARGET.

Cela permet à avrdude d'envoyer le bootloader adéquat pour la carte en question (TARGET).

Pour envoyer le bootloader il faut utiliser le menu Outils / Graver la séquence d'initialisation.

avrdude va donc envoyer les informations binaires à la carte PROGRAMMER qui les transmettra via le bus SPI à la carte TARGET.

2.4. Vérification On peut ensuite raccorder la carte TARGET au PC à l'aide d'un cordon USB et charger le sketch Blink :

Menu Fichier / Exemples / 01. Basics / Blink

Compiler et charger ce sketch (bouton Téléverser).

Un oubli courant : il est indispensable de débrancher le fil de RESET de la carte TARGET avant de charger le sketch.

2.5. Ça marche pôôô Si cela ne fonctionne pas, tout dépend de l'étape à laquelle on détecte un problème :

2.5.1. Chargement du sketch ArduinoISP Ce cas ne devrait pas arriver. Il faut avant tout vérifier que l'on utiliser comme PROGRAMMATEUR une carte qui fonctionne, en chargeant un sketch Blink par exemple.

Si le problème persiste, la cause peut être :

  • câble USB défectueux
  • carte défectueuse
  • bootloader absent
  • mauvais choix du port série
  • etc.

Voir cet article : Problèmes de téléversement

2.5.2. Chargement du bootloader Si le programmateur refuse de charger le sketch le problème provient certainement d'un défaut de branchement du connecteur ICSP :

Si un programmateur du genre USBASP est utilisé, s'assurer du bon sens de branchement du connecteur ICSP. Attention ce connecteur n'est pas soudé dans le même sens sur une UNO ou sur une NANO. Si le branchement a été fait à l'envers, que l'on se rassure, ce n'est pas destructeur.

Si une carte ARDUINO est utilisée comme programmateur, vérifier et revérifier les connexions. remplacer éventuellement les fils DUPONT.

2.5.3. Vérification Après avoir chargé le bootloader, si l'on rencontre un problème de chargement d'une application quelconque, cela peut avoir pour origine le même problème qu'en 2.5.1. Chargement du sketch ArduinoISP.

Il y a une cause possible supplémentaire : avoir sélectionné le mauvais port série, en particulier avoir sélectionné le port de la carte PROGRAMMER en croyant avoir choisi le port de la carte TARGET ce qui revient à charger le sketch Blink dans la carte PROGRAMMER. Dans ce cas, recommencer depuis le début.

2. Cas particulier : l'ARDUINO NANO Comme on l'a dit précédemment la NANO a un historique perturbé et elle a été équipée de deux bootloaders différents :

  • atmega (old bootloader)
  • optiboot (new bootloader)

Lorsque l'on commande des cartes NANOs chez de revendeurs différents, on peut très bien à la longue se retrouver avec dans ses tiroirs des cartes "Old Bootloader" et des cartes "New Bootloader". Dans ce cas il est possible, si l'on trouve cette situation ennuyeuse, d'harmoniser ses cartes.

Un deuxième cas de figure peut se présenter : le bootloader a été corrompu et il faut le recharger. Cela arrive ...

Il suffit donc de refaire l'opération décrite au paragraphe 2. Le chargement. On sélectionnera dans Outils :

  • Type de carte : Arduino Nano
  • Processeur :
    • ATmega328P si l'on désire charger le nouveau bootloader
    • ATmega328P (Old Bootloader) si l'on désire charger l'ancien

Ensuite : menu Outils / Graver la séquence d'initialisation.

Une fois que la manipulation a été testée avec succès sur la première carte, il est très rapide de la répéter sur 10 ou 20 exemplaires.

2.1. Aïe Aïe Aïe Cela ne se passe pas comme prévu. Le chargement du bootloader affiche un vilain message pas sympathique du tout :


avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: Expected signature for ATmega328P is 1E 95 0F
        Double check chip, or use -F to override this check.
Erreur lors de la gravure de la séquence d'initialisation.

Explication : beaucoup de cartes NANO sont équipées d'un microcontrôleur ATMEGA328PB au lieu d'un ATMEGA328P et avrdude ne reconnaît pas la signature(0x1e9516 au lieu de 0x1E950F).

Il convient donc de forcer le chargement avec l'option -F comme dit dans le message, autrement dit : avec l'option -F avrdude ne vérifiera pas la signature.

Mais comment faire ? Il existe certainement d'autres méthodes, mais l'utilisation d'avrdude en ligne de commande est une option facile.

Comment récupérer cette ligne de commande ?

La première chose à faire est d'afficher les préférences : Menu Fichier / Préférences :

   Afficher les résultats détaillés pendant :
       cocher "téléversement"

Cocher "compilation" peut être également utile si l'on désire plus de diagnostic pendant la compilation des sketches.

A partir de ce moment il va falloir considérer le type de système d'exploitation installé sur la machine.

2.1.1 Machine LINUX J'ai réalisé les opérations suivantes sur un IDE version 1.8.5. Cela sera très peu différent avec une autre version.

Dans l'exemple suivant j'ai utilisé un programmateur USBASP. Si l'on désire réaliser la même opération avec une carte ARDUINO comme PROGRAMMATEUR il suffit de remplacer :

* cusbasp

par :

  • carduino -P/dev/ttyUSBX -b19200 (ttyUSBX : le port série)

Essayons une nouvelle fois : Outils / Graver la séquence d'initialisation.


/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/bin/avrdude -C/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m
// ...
// ... ICI un tas de messages inutiles
// ...
avrdude: auto set sck period (because given equals null)
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude: Device signature = 0x1e9516 (probably m328pb)
avrdude: Expected signature for ATmega328P is 1E 95 0F
        Double check chip, or use -F to override this check.
avrdude done.  Thank you.
Erreur lors de la gravure de la séquence d'initialisation.

Nous obtenons donc beaucoup plus de détails et en particulier la ligne de commande utilisée pour lancer avrdude.

La méthode est de recopier la première ligne affichée par l'IDE :

/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/bin/avrdude -C/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m

On pourrait croire qu'il suffit d'ajouter -F pour arranger les choses :

/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/bin/avrdude -C/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F

Le chargement du bootloader a l'air de bien se passer mais en examinant les messages on se rend vite compte qu'avrdude se contente de charger les fuses. Il est évident que le bootloader n'est pas chargé. Il faut ajouter le chemin du bootloader avec l'option -U flash:w:

/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/bin/avrdude -C/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F -U flash:w:/home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex

La version 6.3.0-arduino14 ou 1.6.207 n'est pas forcément correcte et dépend forcément de la version de l'IDE.

Si l'on désire charger l'ancien bootloader il faut remplacer : optiboot/optiboot_atmega328.hex par : atmega/ATmegaBOOT_168_atmega328.hex

Personnellement j'ai choisi optiboot.

2.1.2 Machine WINDOWS J'ai réalisé les opérations suivantes sur un IDE version 1.8.8. Cela sera très peu différent avec une autre version.

Dans l'exemple suivant j'ai utilisé un programmateur USBASP. Si l'on désire réaliser la même opération avec une carte ARDUINO comme PROGRAMMATEUR il suffit de remplacer : -cusbasp par : -carduino -PCOMX -b19200 (COMX : le port série)

Si l'on utilise un programmateur USBASP sous Windows, un driver est nécessaire : https://protostack.com.au/2015/01/usbasp-windows-driver-version-3-0-7/

L'utilisation des clones de cartes ARDUINO NANO avec convertisseur USB / série CH340 nécessite également l'ajout d'un driver : https://cdn.sparkfun.com/assets/learn_tutorials/8/4/4/CH341SER.EXE

Essayons une nouvelle fois : Outils / Graver la séquence d'initialisation.

Voici le résultat :

 /home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/bin/avrdude -C/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F -U flash:w:/home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex

 avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/home/username/.arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf"
         User configuration file is "/home/username/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : usb
         Using Programmer              : usbasp
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : usbasp
         Description     : USBasp, http://www.fischl.de/usbasp/

 avrdude: auto set sck period (because given equals null)
 avrdude: warning: cannot set sck period. please check for usbasp firmware update.
 avrdude: AVR device initialized and ready to accept instructions

 Reading | ################################################## | 100% 0.00s

 avrdude: Device signature = 0x1e9516 (probably m328pb)
 avrdude: Expected signature for ATmega328P is 1E 95 0F
 avrdude: safemode: lfuse reads as FF
 avrdude: safemode: hfuse reads as DA
 avrdude: safemode: efuse reads as F5
 avrdude: erasing chip
 avrdude: auto set sck period (because given equals null)
 avrdude: warning: cannot set sck period. please check for usbasp firmware update.
 avrdude: reading input file "0x3F"
 avrdude: writing lock (1 bytes):

 Writing | ################################################## | 100% 0.00s
 
 avrdude: 1 bytes of lock written
 avrdude: verifying lock memory against 0x3F:
 avrdude: load data lock data from input file 0x3F:
 avrdude: input file 0x3F contains 1 bytes
 avrdude: reading on-chip lock data:

 Reading | ################################################## | 100% 0.00s

 avrdude: verifying ...
 avrdude: 1 bytes of lock verified
 avrdude: reading input file "0xFD"
 avrdude: writing efuse (1 bytes):

 Writing |                                                    | 0% 0.00s ***failed;
 Writing | ################################################## | 100% 0.03s

 avrdude: 1 bytes of efuse written
 avrdude: verifying efuse memory against 0xFD:
 avrdude: load data efuse data from input file 0xFD:
 avrdude: input file 0xFD contains 1 bytes
 avrdude: reading on-chip efuse data:

 Reading | ################################################## | 100% 0.00s

 avrdude: verifying ...
 avrdude: WARNING: invalid value for unused bits in fuse "efuse", should be set to 1 according to datasheet
 This behaviour is deprecated and will result in an error in future version
 You probably want to use 0xf5 instead of 0xfd (double check with your datasheet first).
 avrdude: 1 bytes of efuse verified
 avrdude: reading input file "0xDA"
 avrdude: writing hfuse (1 bytes):

 Writing | ################################################## | 100% 0.00s

 avrdude: 1 bytes of hfuse written
 avrdude: verifying hfuse memory against 0xDA:
 avrdude: load data hfuse data from input file 0xDA:
 avrdude: input file 0xDA contains 1 bytes
 avrdude: reading on-chip hfuse data:

 Reading | ################################################## | 100% 0.00s

 avrdude: verifying ...
 avrdude: 1 bytes of hfuse verified
 avrdude: reading input file "0xFF"
 avrdude: writing lfuse (1 bytes):

 Writing | ################################################## | 100% 0.00s

 avrdude: 1 bytes of lfuse written
 avrdude: verifying lfuse memory against 0xFF:
 avrdude: load data lfuse data from input file 0xFF:
 avrdude: input file 0xFF contains 1 bytes
 avrdude: reading on-chip lfuse data:

 Reading | ################################################## | 100% 0.00s

 avrdude: verifying ...
 avrdude: 1 bytes of lfuse verified
 avrdude: reading input file "/home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex"
 avrdude: input file /home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex auto detected as Intel Hex
 avrdude: writing flash (32768 bytes):

 Writing | ################################################## | 100% 0.00s

 avrdude: 32768 bytes of flash written
 avrdude: verifying flash memory against /home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex:
 avrdude: load data flash data from input file /home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex:
 avrdude: input file /home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex auto detected as Intel Hex
 avrdude: input file /home/username/.arduino15/packages/arduino/hardware/avr/1.6.207/bootloaders/optiboot/optiboot_atmega328.hex contains 32768 bytes
 avrdude: reading on-chip flash data:

 Reading | ################################################## | 100% 0.00s

 avrdude: verifying ...
 avrdude: 32768 bytes of flash verified

 avrdude: safemode: lfuse reads as FF
 avrdude: safemode: hfuse reads as DA
 avrdude: safemode: efuse reads as F5
 avrdude: safemode: Fuses OK (E:FD, H:DA, L:FF)

 avrdude done.  Thank you.

Voilà c'est terminé. Le chargement d'une application (Blink par exemple) se fera dorénavant en choisissant l'option par défaut :
Outils / Processeur / ATmega328P
et non pas :
Outils / Processeur / ATmega328P (Old Bootloader).

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m
// ...
// ... ICI un tas de messages inutiles
// ...
avrdude: auto set sck period (because given equals null)
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e9516 (probably m328pb)
avrdude: Expected signature for ATmega328P is 1E 95 0F
         Double check chip, or use -F to override this check.

avrdude done.  Thank you.

Erreur lors de la gravure de la séquence d'initialisation.

Nous obtenons donc beaucoup plus de détails et en particulier la ligne de commande utilisée pour lancer avrdude.

La méthode est de recopier la première ligne affichée par l'IDE :

C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m

Sous Windows il sera nécessaire d'ajouter des quotes (à cause des espaces dans "C:\Program Files (x86)" - ce nom de répertoire est vraiment une mauvaise idée - et de remplacer les '/' par des '\' :

"C:\Program Files (x86)"\Arduino\hardware\tools\avr\bin\avrdude -C"C:\Program Files (x86)"\Arduino\hardware\tools\avr\etc\avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m

On pourrait croire qu'il suffit d'ajouter -F pour arranger les choses :

"C:\Program Files (x86)"\Arduino\hardware\tools\avr\bin\avrdude -C"C:\Program Files (x86)"\Arduino\hardware\tools\avr\etc\avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F

Le chargement du bootloader a l'air de bien se passer mais en examinant les messages on se rend vite compte qu'avrdude se contente de charger les fuses. Il est évident que le bootloader n'est pas chargé. Il faut ajouter le chemin du bootloader à charger avec l'option -U flash:w:

Sous Windows si l'on exécute la ligne suivante le chargement ne se fait pas non plus :

"C:\Program Files (x86)"\Arduino\hardware\tools\avr\bin\avrdude -C"C:\Program Files (x86)"\Arduino\hardware\tools\avr\etc\avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F 0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F -U flash:w:"C:\Program Files (x86)\Arduino\hardware\arduino\avr\bootloaders\optiboot\optiboot_atmega328.hex"

La ligne de commande est peut-être trop longue : 272 caractères. J'ai été obligé de raccourcir celle-ci en changeant de répertoire courant :

cd "\Program Files (x86)\Arduino\hardware\arduino\avr\bootloaders\optiboot"

Si l'on désire charger l'ancien bootloader il faut remplacer :optiboot par : atmega

"C:\Program Files (x86)"\Arduino\hardware\tools\avr\bin\avrdude -C"C:\Program Files (x86)"\Arduino\hardware\tools\avr\etc\avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F -U flash:w:optiboot_atmega328.hex

Si l'on désire charger l'ancien bootloader il faut remplacer : optiboot_atmega328.hex par : ATmegaBOOT_168_atmega328.hex

Avec cette méthode cela fonctionne enfin.

Personnellement j'ai choisi optiboot.

Voici le résultat :

"C:\Program Files (x86)"\Arduino\hardware\tools\avr\bin\avrdude -C"C:\Program Files (x86)"\Arduino\hardware\tools\avr\etc\avrdude.conf -v -patmega328p -cusbasp -Pusb -e -Ulock:w:0x3F:m -Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xFF:m -F -Uflash:w:optiboot_atmega328.hex

avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr\etc\avrdude.conf"

         Using Port                    : usb
         Using Programmer              : usbasp
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : usbasp
         Description     : USBasp, http://www.fischl.de/usbasp/

avrdude: auto set sck period (because given equals null)
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.06s

avrdude: Device signature = 0x1e9516 (probably m328pb)
avrdude: Expected signature for ATmega328P is 1E 95 0F
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DA
avrdude: safemode: efuse reads as F5
avrdude: erasing chip
avrdude: auto set sck period (because given equals null)
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file "0x3F"
avrdude: writing lock (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lock written
avrdude: verifying lock memory against 0x3F:
avrdude: load data lock data from input file 0x3F:
avrdude: input file 0x3F contains 1 bytes
avrdude: reading on-chip lock data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lock verified
avrdude: reading input file "0xFD"
avrdude: writing efuse (1 bytes):

Writing |                                                    | 0% 0.00s ***failed;
Writing | ################################################## | 100% 0.05s

avrdude: 1 bytes of efuse written
avrdude: verifying efuse memory against 0xFD:
avrdude: load data efuse data from input file 0xFD:
avrdude: input file 0xFD contains 1 bytes
avrdude: reading on-chip efuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: WARNING: invalid value for unused bits in fuse "efuse", should be set to 1 according to datasheet
This behaviour is deprecated and will result in an error in future version
You probably want to use 0xf5 instead of 0xfd (double check with your datasheet first).
avrdude: 1 bytes of efuse verified
avrdude: reading input file "0xDA"
avrdude: writing hfuse (1 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0xDA:
avrdude: load data hfuse data from input file 0xDA:
avrdude: input file 0xDA contains 1 bytes
avrdude: reading on-chip hfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: reading input file "0xFF"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.00s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xFF:
avrdude: load data lfuse data from input file 0xFF:
avrdude: input file 0xFF contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.01s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified
avrdude: reading input file "optiboot_atmega328.hex"
avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
avrdude: writing flash (32768 bytes):

Writing | ################################################## | 100% 0.05s

avrdude: 32768 bytes of flash written
avrdude: verifying flash memory against optiboot_atmega328.hex:
avrdude: load data flash data from input file optiboot_atmega328.hex:
avrdude: input file optiboot_atmega328.hex auto detected as Intel Hex
avrdude: input file optiboot_atmega328.hex contains 32768 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.03s

avrdude: verifying ...
avrdude: 32768 bytes of flash verified

avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DA
avrdude: safemode: efuse reads as F5
avrdude: safemode: Fuses OK (E:FD, H:DA, L:FF)

avrdude done.  Thank you.

Voilà c'est terminé. Le chargement d'une application (Blink par exemple) se fera dorénavant en choisissant l'option par défaut : Outils / Processeur / ATmega328P et non pas : Outils / Processeur / ATmega328P (Old Bootloader).

Si l'on a choisi l'ancien bootloader, ce sera le contraire.

3. Se passer de bootloader On peut parfaitement se passer de bootloader et utiliser un programmateur pour charger une application. Dans ce cas on utilisera le menu Croquis / Téléverser avec un programmateur, en ayant choisi le programmateur au préalable dans le menu Outils / Programmateur.

On récupèrera du même coup l'espace occupé par le bootloader (2Ko). Ce n'est pas énorme, mais cela peut aider.

On pourra aussi conserver l'affichage sur le terminal (Moniteur Série) à travers le cordon USB.

4. Conclusion J'espère avoir apporté ma petite contribution à la résolution des problèmes de bootloader que certains utilisateurs rencontrent. Je suis bien conscient que le cas particulier de l'ARDUINO NANO n'est pas évident, mais il est difficile d'expliquer de manière plus simple, spécialement lorsque l'on travaille sous Windows.

Une dernière remarque : travailler sur ARDUINO avec une machine WINDOWS était une première pour moi, et cette première expérience n'a fait que confirmer mes (mauvaises) impressions :

- lenteur remarquable - utilisation des '\' à la place de '/' dans le noms des répertoires, une option débile datant des années 1980, alors que sous UNIX le '/' était utilisé depuis 1969 - installation nécessaire de drivers supplémentaires (USBASP, CH340, etc.), absolument inutiles sous LINUX. - installation de l'IDE ARDUINO dans C:\Program Files (x86), un nom avec espaces qui ne facilite pas les choses. Je recommande plutôt d'installer l'IDE à l'aide de la version ZIP, dans votre répertoire personnel, cela évitera bien des désagréments.


Cordialement Henri

Le mois dernier Arduiblog a présenté le chargement de l'ARDUINO NANO, bootloader y compris.

https://arduiblog.com/2020/01/20/flashez-larduino-nano/

L'auteur ne parle pas de ATMEGA328PB mais il y a pas mal de copies d'écran.

Source : https://forum.arduino.cc/index.php?topic=661881.0