Étiquette : ide

  • Arduino, avr-gcc et avrdude

    Arduino.
    On ne le présente plus.
    C’est à la fois un package hardware et un package software. Il permet donc aux bidouilleurs de se mettre facilement au monde de l’embarqué, via un langage de programmation (processing) légèrement adapté.

    Oui, mais voilà, quand vous êtes déjà habitué par ce monde (aussi bien soft que hard), vous êtes vite un peu dépité par l’ide d’arduino. Vous avez envie de profiter du côté hardware de ce monde (cela reste des cartes d’évaluation, prototypage très bon marché)… Mais cela ne vous gène pas de garder votre bon vieux C… De garder votre éditeur préféré… Votre makefile maison qui automisera tout. Bref avoir un environnement de développement plus efficace, plus ouvert (plus technique). Avec aucun bout de soft caché.

     

    Bref, en gros, pour moi personnellement ça donne, « bref c beau on vient d’inventer l’arduino en 2005, mais je serais pas contre d’utiliser (directement) ce bon vieil avr-libc avec son compilo et ces lib, tout comme en 2001 avec mon AT90S8515. (souvenir d’un bout de code permettant de lire un disque dur…). Après tout pourquoi s’enfermer dans le monde arduino ? Le but du prototypage et de pouvoir aussi compiler directement ensuite sur une cible différente ?

    J’ai ajouté « directement » car au final l’IDE arduino s’appui sur cette chaine pour la compilation. Elle amène juste une surcouche fine au langage C (processing),  et des librairies supplémentaires pour des accès plus facile à certains périphériques (uart, spi) voir composant (shields) extérieurs (ex: ethernet).

    First Step : Compilation

    Ce premier article trouvé sur le net, partant du même constat, aborde ce sujet, avec les premiers arduino en cible (atmega8/168).
    Il cible avant tout le monde linux et m’a permis de re-trouver LA bonne page d’aide de l’avr-libc expliquant les étapes pour compiler un programme (qui reste après tout les étapes usuelles et classiques d’une compilation, bref un tuto qui s’adresse plus à ceux qui découvre ce processus).

    Ici, on peut donc voir comment générer ça à la mano, et le makefile nécessaire pour automatiser tout ça.

    Il faut savoir que l’avr-libc est disponible sous Windows via le package WinAvr. Ce dernier est d’ailleurs inclus dans le package arduino (et d’ailleurs semble plus à jour que le package officiel).  Dans la suite de ce tuto, on va donc faire avec tout ce qui provient du package arduino (ici dans sa version 1.0), installé sous D:\arduino-1.0.  Bref on retrouve donc le package winavr (updaté) sous D:\arduino-1.0\hardware\tools\avr. Et donc tous les compilos et autre sont dans le sous-répertoire bin. (structure linux classique ici).

    On va garder l’exemple fourni par notre tuto qui est l’équivalent d’un des exemples de base d’Arduino, le clignotement d’une Led.
    Voici donc le fichier blink.c :

    #include 
    #include 
    
    int main (void)
    {
      unsigned char counter;
      /* set PORTB for output*/
      DDRB = 0xFF;
    
      while (1)
      {
          /* set PORTB.2 high */
          PORTB = 0xFF;
    
          /* wait (10 * 120000) cycles = wait 1200000 cycles */
          counter = 0;
          while (counter != 50)
          {
    	  /* wait (30000 x 4) cycles = wait 120000 cycles */
    	  _delay_loop_2(30000);
    	  counter++;
          }
    
          /* set PORTB.2 low */
          PORTB = 0x00;
    
          /* wait (10 * 120000) cycles = wait 1200000 cycles */
          counter = 0;
          while (counter != 50)
          {
    	  /* wait (30000 x 4) cycles = wait 120000 cycles */
    	  _delay_loop_2(30000);
    	  counter++;
          }
      }
      return 1;
    }

    Et donc les commandes à la mano de compilation provenant de la page de win-avr :

    D:\arduino-1.0\hardware\tools\avr\bin\avr-gcc -g -Os -mmcu=atmega2560 -c blink.c
    D:\arduino-1.0\hardware\tools\avr\bin\avr-gcc -g -mmcu=atmega2560 -o blink.elf blink.o
    D:\arduino-1.0\hardware\tools\avr\bin\avr-objcopy -j .text -j .data -O ihex blink.elf blink.hex

    Pour automaiser tout ça, voici une version un peu plus clean du makefile que celui proposé par le tuto d’avr-libc. C’est le genre de makefile générique que j’utilise. Bien qui celui-ci soit modifié (simplifié) pour l’occasion (en effet habitullement, j’ai un sous-répertoire différent pour tout ce qui est source, header et .o). Avec ce genre de makefile, on peut avoir un makefile global simple (qui définie les variables utilisateurs, conceptuelles) qui inclus ce dernier plus générique. De plus j’ai jouté une variable TOOLSDIR pour nous éviter de modifier le PATH pour le moment.

    # GENERIC MAKEFILE EXAMPLE FOR AVR GCC
    
    # ================ Project name
    PROJECT_NAME=blink
    
    # ================ Working directory
    WORKDIR=.
    TOOLSDIR=D:\Projets\Hardware\Arduino\IDE\arduino-1.0\hardware\tools\avr\bin\\
    
    # ================ Compilation Tools
    COMMAND_PREFIX=avr-
    MCU_TARGET=atmega2560
    
    CC=$(TOOLSDIR)$(COMMAND_PREFIX)gcc
    OBJCOPY=$(TOOLSDIR)$(COMMAND_PREFIX)objcopy
    OBJDUMP=$(TOOLSDIR)$(COMMAND_PREFIX)objdump
    
    # ================ Common compilation flags
    DEBUG=-g -Wall
    OPTIM=-O2
    DEFS=
    
    CFLAGS+=$(DEBUG) \
    		$(OPTIM) \
    		-mmcu=$(MCU_TARGET) \
    		$(DEFS)
    
    # ================ Libs & link FIle
    LIBS=
    LINKER_FLAGS=
    
    # Default sources are all sources of sources directory
    SOURCES = $(wildcard $(WORKDIR)/*.c)
    OBJECTS = $(SOURCES:.c=.o)
    
    # ================ Main targets
    
    all: $(PROJECT_NAME).elf lst text
    
    $(PROJECT_NAME).elf: $(OBJECTS)
    		$(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LIBS) $(LINKER_FLAGS)
    
    $(OBJECTS): $(WORKDIR)/%.o : $(WORKDIR)/%.c
    		@echo BUILDING $@
    		$(CC) -c $(CFLAGS) $< -o $@	
    
    clean:
    		rm -rf *.o $(PROJECT_NAME).elf
    		rm -rf *.lst *.map
    
    lst:  $(PROJECT_NAME).lst
    
    %.lst: %.elf
    		$(OBJDUMP) -h -S $< > $@
    
    # Rules for building the .text rom images
    
    text: hex
    
    hex:$(PROJECT_NAME).hex
    
    %.hex: %.elf
    		$(OBJCOPY) -j .text -j .data -O ihex $< $@

    Second Step : Upload

    Alors là, on va devoir s’écarte de notre principal première source d’information.
    On a donc bien deux façon de charger notre programme dans l’arduino:

    • En gardant le bootloader « arduino » originale
    • Sans le bootloader, avec un programmeteur « classique »

    Pour ce deuxième cas, on va passer le coup du port parallèle cité dans notre premier tuto :-) Le monde évolue…. Et on va tout simplement passer ce second cas. En effet, dans ce cas il faut utiliser le connecteur officiel de programmation ICSP présent sur l’arduino. Il vous faut aussi un programmateur compatible, et donc la procédure à suivre sera différente selon ce dernier.

    Ici, on va se focaliser à rester un peu dans le monde arduino, en profitant de ce bootloader, qui apporte quand même une fonctionalié intéressante en mode proto/test. De plus personellement, j’ai bien un programmateur isp qui traine (depuis 2001…) mais je n’ai plus de foutu port paralléle sur mon pc… Et donc tant que je ne ma passe pas du bootloader (ou tant que je le modifie pas), je n’en ai pas réellement besoin.

    Donc en gros « Comment qu’on fait pour downloader de la même manière que l’Arduino IDE en ligne de commande ? »

    Et c’est là que ma 2ème grosse source d’inspiration arrive. En effet, mon arduino mega 2560 n’a plus le FTDI au niveau de son usb… je suis donc bien loin de notre premier tuto utilisé pour la compilation. C’est donc un atmega8u2 à la place. Ce dernier est donc une sorte de passerelle entre l’usb et le mode de programmation offert par le bootloader. Il est piloté suivant le protocol officiel stk500. (comme certains autres programmateur du commerce, qui sont alors un bridge entre le stk500 et le port de programmation isp de l’atmel).
    Ok, oui vous avez compris, avec l’arduino pas besoin de programmateur, car en gros, ce dernier est déjà dessus….  (ca reste vraiment une carte de prototypage). Enfin, en passant par ce dernier, on sait donc qu’on ne met pas en péril la zone dédié au bootloader.

    Au final, j’ai eu pas mal de problème, croyant que sa solution ne marchait pas, tout ça pour refaire exactement la même démarche que lui ! Cela m’aura au moins permis de savoir où trouver les traces d’exécution de l’IDE d’arduino. Et au final, la bonne solution est en commentaire de notre 2ème tuto.

    J’ai donc d’abord lancé une compilation/upload depuis l’IDE officiel, en activant les traces d’upload afin de voir la ligne de commande.

    Pour info voilà comment activer les traces :

        

    C’est également possible de le faire directement depuis le fichier de preferences ( http://arduino.cc/forum/index.php?topic=95254.0).Il est dans ce cas préférable de modifier le fichier spécifique à l’utilisateur (sous windows C:\Documents and Settings\<USER>\Application Data\Arduino)  et pas celui du répertoire arduino (arduino-1.0\lib).
    Une vue sur ce fichier (utilisateur) permet de voir, toutes les options réellement disponibles. 2 options vont d’ailleurs me mettre la puce à l’oreil pour la suite: console.error.file=stderr.txt & console.output.file=stdout.txt.

    En effet, une fois les traces activées, on n’a pas le temps de voir la ligne de commande tracée pour l’upload, d’autres traces suivent, et la fenêtre trace de l’IDE d’arduino n’offre pas un historique assez important (tu vois bien qu’il faut se défaire de cet IDE !). On se dit, il doit bien avoir un fichier… en plus certaines options ont l’air de le préciser !

    Après où sont-ils ? => http://forums.adafruit.com/viewtopic.php?f=25&t=23271#p121783.
    Ok , ils sont donc ici : C:\Documents and Settings\<USER>\Local Settings\Temp\console*******.tmp
    Suffit de trouver le dernier répertoire généré et vous aurez accès aux 2 fichier de traces de toute une session de l’IDE.

    On a donc dans le stdout.txt:

    Binary sketch size: 1602 bytes (of a 258048 byte maximum)
    D:\arduino-1.0\hardware/tools/avr/bin/avrdude -CD:\arduino-1.0\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega2560 -cstk500v2 -P\\.\COM3 -b115200 -D -Uflash:w:C:\DOCUME~1\Fabien\LOCALS~1\Temp\build8342149431938943132.tmp\Blink.cpp.hex:i

    Et dans le stderr.txt, les traces qui suivent :

    avrdude: Version 5.11, compiled on Sep  2 2011 at 19:38:36
    Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
    Copyright (c) 2007-2009 Joerg Wunsch
    System wide configuration file is "D:\arduino-1.0\hardware/tools/avr/etc/avrdude.conf"
    Using Port                    : \\.\COM3
    Using Programmer              : stk500v2
    Overriding Baud Rate          : 115200
    avrdude: Send: . [1b] . [01] . [00] . [01] . [0e] . [01] . [14]
    avrdude: Recv: . [1b]
    ......

    En retentant à la main, la ligne de commande détectée, on a les même traces mais un foireux Timeout à la place du premier Recv !!!
    Au passage contrairement au tuto, on voit bien que la différence ne vient pas d’avrdude, c’est la version 5.11 qui est maintenant livré avec la package Arduino. Ce n’est donc plus une version spécifique Arduino.

    En continuant de survoler le tuto et ces commentaires, voici les tentatives suivantes :

    • Essai en spécifiant un programmer de type « arduino » => même constat
    • Essai en plaçant en reset la board (via le bouton) jusqu’au moment où on lance la ligne de commande : Eureka ! En effet c’est ok. Par contre, c’est pas super top automatique ton truc ?
    • Heureusement qu’un commentaire du tuto nous résout tout ça. Il faut utiliser un programmateur de type wiring. C’est totalement accepté par l’avrdude 5.11 livré par le package arduino.

    C’est quand même étrange qu’on soit obligé de changer le type de programmateur par rapport à la ligne de commande faite par l’IDE arduino… C’est comme ci l’IDE arduino faisait un reset caché de la board avant de lancer avrdude.

    AU final :

    D:\arduino-1.0\hardware/tools/avr/bin/avrdude -CD:\arduino-1.0\hardware/tools/avr/etc/avrdude.conf -v -v -v -v -patmega2560 -cwiring -P\\.\COM3 -b115200 -D -Uflash:w:D:\Example\Blink.hex:i

    On pourra bien entendu enlenver tous les « -v » qui sont içi pour être en mode trace (full). Enfin pourquoi pas ajouter une option dans le makefile pour ajouter ça (bien que cette ligne de commande pourra devrait normalement pouvoir également être associé directement à un bouton dans votre IDE).

    Dans le makefile on pourrait ajouter :

    download : $(PROJECT_NAME).hex
    		$(TOOLSDIR)avrdude -CD:\arduino-1.0\hardware/tools/avr/etc/avrdude.conf -patmega2560 -cwiring -P\\.\COM3 -b115200 -D -Uflash:w:$(PROJECT_NAME).hex:i

    Ce qui nous donne dans la console DOS :

    D:\Example>D:\arduino-1.0\hardware\tools\avr\utils\bin\make.exe download
    D:\arduino-1.0\hardware\tools\avr\bin\\avrdude -CD:\arduino-1.0\hardware\tools\avr\etc\avrdude.conf -p
    atmega2560 -cwiring -P\\.\COM3 -b115200 -D -Uflash:w:blink.hex:i
    
    avrdude: AVR device initialized and ready to accept instructions
    
    Reading | ################################################## | 100% 0.02s
    
    avrdude: Device signature = 0x1e9801
    avrdude: reading input file "blink.hex"
    avrdude: writing flash (348 bytes):
    
    Writing | ################################################## | 100% 0.06s
    
    avrdude: 348 bytes of flash written
    avrdude: verifying flash memory against blink.hex:
    avrdude: load data flash data from input file blink.hex:
    avrdude: input file blink.hex contains 348 bytes
    avrdude: reading on-chip flash data:
    
    Reading | ################################################## | 100% 0.05s
    
    avrdude: verifying ...
    avrdude: 348 bytes of flash verified
    
    avrdude: safemode: Fuses OK
    
    avrdude done.  Thank you.
    
    D:\Example>

    Se passer de l’install de l’IDE officiel ?

    On a bien vue que pour le moment, j’ai tout fait via les packages installés avec l’IDE d’arduino. J’ai parlé aussi de légère différence (mise à jour) par rapport à l’installer simple de WinAvr. Regardons ce qu’il en est réellement.

    Le dernier package officiel de WinAvr date de Janvier 2010. C’est pas top comme impression pour le moment. Par default, il install donc tout sous C:\WinAVR-20100110. Personnellement, je n’ai pas demander à l’installer de ma changer le PATH. On verra ça ensuite.

    On va donc retrouver le même genre de contenu sous C:\WinAVR-20100110 que sous D:\arduino-1.0\hardware\tools\avr.
    D’ailleurs dans les 2 est présent le fichier qui permet de désinstaller WinAvr. On voit bien que le package arduino contient bien un gros copier/coller de l’install faire par WinAvr. Il aurait au moins pu enlever cet exécutable spécifique à la désinstallation de WinAvr !  On peut noter que d’un côté on a WinAVR-20100110-uninstall.exe et chez arduino WinAVR-20081205-uninstall.exe. Cette version 20081205 est également précisé dans le WinAVR-user-manual.txt.

    Ok donc arduino est basé sur la release 20081205 de WinAvr. Cela à l’air d’un pauvre copier coller (en gardant le désinstaller !) Mais on a bien vu qu’il contenait un avrdude tout neuf, le 5.11 qui est sortie le 27 Aout 2011 !!! Le répertoire livré par Arduino a donc bien était modifié.

    Pour une meilleur comparaison, on pourrait même ce baser sur cette release de WinAvr, elle est toujours dispo (merci google) : http://en.sourceforge.jp/projects/sfnet_winavr/downloads/WinAVR/20081205/WinAVR-20081205-install.exe/

    Me voilà donc avec un 3ème winavr (toujours pas de PATH modifié, on commence à comprendre pourquoi) sous C:\WinAVR-20081205.

    4111 fichier comparés plus tard (entre WinAVR-20081205 et sa version Arduino) on arrive à très peu de différence : WinAVR-20081205 vs arduino-1.0

    Les 3 principales :

    • avrdude.exe -> Qui l’aurait cru !
    • eeprom.h (pourtant aucune différence dans le copyright ;  les 3 différences sont bien annotées et semble concerner le 2560)
    • Enfin, avrdude.conf qui change aussi d’emplacement. Originalement dans bin il passe dans etc. Vous savez c’est celui qu’on passe en ligne de commande à avrdude plus haut. Les différences doivent venir de la différence de version d’avrdude.

    Tout le reste, c’est du fichier en plus du côté arduino.  C’est le contenu de tout le répertoire pn au final. Des fichiers xml, scheme et clips… Je sais pas trop à qui à quoi ça sert…. Surement pas à winavr en tout cas.

    Ce qu’on peut constater :

    C’est que déjà, winavr n’est plus mise à jour depuis 2010, mais en plus le outils utilisés par le package arduino sont ceux de winavr version 2008 ! On faisant une comparaison de winavr 2008 vs 2010 on voit bien que tout a évolué, tous les fichiers sont différents. EN regardant le manuel, on sait qu’on est passé de gcc 4.3.2 à 4.3.3, d’avr-libc 1.6.4 à 1.6.7, d’avrdude 5.5 au 5.8, d’avarice 2.7 au 2.9 de simulAVR 0.1.2.5 au 0.9… Il y a également d’autres petits outiles en plus…. A la fin il était donc précisait que c’était la dernière version de win-avr bien et que bien entendu tous les projets englobés continué à vivre (la version 2010 est donc elle aussi en retard….).

    On peut donc se dire que c’est dommage que la team arduino n’en est pas profité pour faire un gros update de ce package. Bien entendu, le problème ne doit pas se poser dans le monde linux.. vu que ce sont des outils développés pour ce monde. Il nous manque juste une mise à  jour de leur compilation dans l’environnement Windows. (via MinGw ou Cygwin).

    AU sujet de la différence du fichier eeprom.h, on peut juste voir que dans la version d’avr-libc 1.6.7 (fourni par le dernier winavr), il a bien évolué. Je pense donc que le patch arduino spécifique au 2560 n’est plus nécessaire.

    Au passage, en prenant la dernière version d’avrdude, qui est la 5.11.1, on se rend compte qu’on retrouve bien l’avrdude.conf fourni par le package arduino. PAr contre c’est un package source…  Le 5.11 avait un problème avec les FTDI pour la programmation.  Bien entendu on peut soit tenter de compiler ca en environnement windows, soit compter sur la magie du web : google -> avrfreaks -> helix.air.net.au :: AVRDUDE (par contre personellement j’ai des problèmes à l’exécuter…. la version fourni par le package arduino me suffisant (pas de programateur avec un ftdi) , je vais pas chercher plus loin)

    ==> C’est bon on a gagné.

    On se rend donc bien compte que chaque package a évolué depuis winavr 2010. Par exemple, en allant sur le site avr-libc on voit qu’on est en 1.8. Pour être à jour facilement, le plus simple est encore de travailler (ou du moins compiler) depuis linux. Si vous voulez pas quitter windows, une machine virtuelle est le tour est joué. J’ai pour ma part un linux très light (ubuntu-mini sans graphique, juste une console, pour des problèmes de pc un peu vieux) . Bref, en y installant tous les outils nécessaire, pas de problème.

    $ apt-get install gcc-avr avr-libc avrdude

    J’ai tenté ça dans ma machine virtuelle (ubuntu-mini), cela m’installe une libc plus récente (1.7.1-2), gcc-avr beaucoup plus récent (4.5.3-2), les binutils-avr en 2.20.1-2, et par contre un avrdude en 5.10-3. Ce dernier point est dommage, il me semble que seul le 5.11 marche dans notre cas. (m’enfin ca reste une marchine virtuelle, je peu softer depuis windows aussi).

    Pour faire simple sous windows, soit on peut faire confiance à mon tuto en se basant sur les outils délivrés par la package arduino, soit on se met un peu plus à jour en utilisant les outils délivré par WinAvr-20100110, auquel on lui met la dernière version d’avrdude (l’exe et le .conf) délivré par le package arduino.

    Utiliser WinAvr uniquement

    J’ai fait le test sur mon makefile, j’ai changé la ligne

    TOOLSDIR=D:\Projets\Hardware\Arduino\IDE\arduino-1.0\hardware\tools\avr\bin\\

    en

    TOOLSDIR=C:\WinAVR-20100110\bin\\

    La compilation a réussi. Le binaire passe de 995 octets à 946 octets.

    Ensuite, le download (via le makefile) :

    D:\Example>C:\WinAVR-20100110\utils\bin\make.exe download
    C:\WinAVR-20100110\bin\\avrdude -CD:\Projets\Hardware\Arduino\IDE\arduino-1.0\hardware\tools\avr\etc\avrdude.conf -patmega2560 -cwiring -P\\.\COM3 -b115200 -D -Uflash:w:blink.hex:i
    error at D:\Projets\Hardware\Arduino\IDE\arduino-1.0\hardware\tools\avr\etc\avrd
    ude.conf:332 unrecognized character: "w"
    make: *** [download] Error 1
    

    On s’y attendait…
    On va donc copier l’avrdude.exe d’Arduino dans C:\WinAVR-20100110\bin, pareil pour le avrdude.conf (dans le répertoire arduino-1.0\hardware\tools\avr\etc et on le met dans C:\WinAVR-20100110\bin). Au passage, on peut modifier la ligne de commande de download. Plus besoin de préciser où se trouve le .conf, car il est dans le même répertoire. On re-lance. C’est OK !