AVRDude

Programmeer Atmel AVR Microcontrollers

AVRDude is een programma waarmee je programma's in .hex formaat naar een AVR Microcontroller kunt schrijven. Hiervoor heb je wel een programmer nodig (USBAsp, USBTinyISP, STK500/STK600, AVR910, …).

Nu hoor ik jullie al denken "Maar Patrick, dat is toch veel te gespecialiseerd voor de 'gewone' Linux gebruiker", en dat klopt, maar als je weet dat de populaire Arduino werkt met een AVR Microcontroller en dat de Arduino een ingebouwde "programmer" heeft, dan wordt het misschien toch wel wat interresanter. Het is zelfs zo dat de Arduino IDE ook gebruik maakt van AVRDude, dus als je niet met deze software wil werken dan kan het ook zonder.

Een andere reden kan zijn dat voor je project een volledige Arduino niet nodig (of te duur is), je kunt dan bijv. een ATTiny microcontroller gebruiken op een breadboard of een experimenteer printplaat en deze voorzien met een 6-pin header zodat je de software in de microcontroller altijd kunt aanpassen (bugfix, feature toevoegen, …), Dit kan natuurlijk ook via de Arduino IDE (al-dan-niet met enkele aanpassigen), maar aangezien deze site zich richt op het gebruik van de commandoregel gaan we hier niet verder op in.

Laten we beginnen, Wat hebben we nodig om met AVRDude te werken?
  • Een Atmel (nu microchip) AVR microcontroller. (Ik gebruik in mijn voorbeeld een ATMega328P)
  • Een programmer (de Atmel/Microchip programmers zoals de STK600 is redelijk duur, mar gelukkig heb je voor zo'n 5 euro al een USBASP programmer, nadeel is dat deze soms (in mijn geval) geleverd wordt met verouderde firmware, en deze moet je eerst updaten, wat niet bij iedere USBASP even gemakkelijk is. Dit is een Open Hardware programmer en je kunt deze zelf maken (maar je hebt een programmer nodig om er een te maken, dit noemt men in het engels een Catch 22). Een andere goedkope oplossing is een USBTinyISB van Adafruit (bouwpakket met alle nodig hardware en voorgeladen microcontroller, deze is iets duurder (zo'n 25 euro), deze kun je ook goedkoper maken mits je enkele 3,6Volt (500mA) Zener Diodes hebt en een ATTiny45/85, en weer een programmer (ook een Catch 22 dus).
  • Heb je geen Programmer maar een Arduino dan kun je deze als isp (In System Programmer) gebruiken, je moet dan wel een speciale sketch in je Arduino laden en opletten dat je de microcontroller programmeert en niet de microcontroller van de Arduino
  • Een manier op je programmer aan te sluiten op je microcontroller. Hiervoor kun je een breadboard gebruiken met enkele patch-cables of een zelfgemaakte "Programming-Station" met bijvoorbeeld enkele ZIF-Sockets zodat je gemakkelijk een IC kunt omwisselen (zie foto) of je voorziet een 6-pin header op de print van je project zodat je de IC nooit meer moet verwijderen om het programma aan te passen (bugfix, update, …).
Figuur 1. USBTinyISP Programmer
USBTinyISP Programmer

Op deze foto zien we een zelfgemaakte USBTinyISP met een ATTiny45 microcontroller als programmer. De programmer zelf is voorzien van een 8-pin IC voet (deze zijn niet in ZIF, of Zero Insertion Force, formaat beschikbaar) en een 14 en 28-pin ZIF IC voet. De 6-polige flatcable aan de onderkant kan gebruikt worden om een microcontroller die voorzien is van een 6-polige ICSP (In Circuit Serial Programmer) header (zoals de Arduino UNO) te programmeren zonder de IC te moeten verwijderen. De 10-polige header kan gebruikt worden om een extra print aan te sluiten (in dit geval een print met 4 extra ZIF sockets (14, 20, 28 en 48 pins) of om met een flatcable met 10 polen aan te sluiten om een IC met een 10-polige ICSP header te programmeren (Arduino gebruikt uitsluitend 6-polige headers en bij een 10-polige zijn er gewoon 4 polen niet aangesloten.

Genoeg theorie over de Hardware, laten we AVRDude eens gaan gebruiken.

Als eerste hebben we een programma nodig om naar de AVR te schrijven, ik gebruik hiervoor het bekende "Hello World" programma, maar omdat een microcontroller niet standaard wordt aangesloten op een beeldscherm kunnen we dus niet zoals met het programmeren van software voor een desktop/laptop computer gebruiken. In de electronica is het alternatief van "Hello World" een knipperende LED (je kunt stellen dat deze apparaten communiceren met de gebruiker door middel van het knipperen van 1 of meerdere LEDs).

Het programma in C:
#include <avr/io.h>        // Voor gebruik van namen voor poorten
#include <util/delay.h>    // Voor gebruik van timers

int main(void)
{
    DDRB = 0xff;            // Stel alle poorten van "Data Direction Registry B" in als "output"
    PORTB = 0b00000001;     // Zet pin 0 of PB0 (de eerste) van DDRB op hoog (5 volt)

    while (1)               // eeuwigdurende lus
    {
        PORTB ^= (1 << 0);  // schakel pin 0 om
        _delay_ms(1000);    // wacht 1000 miliseconden (1 seconde)
    }
    return (0);             // deze regel wordt nooit bereikt.
}

Een andere manier om erachter te komen welke pin waar zit is het zoeken naar "ATmega328P pinout" in een zoekmachine, maar let wel op dat je dit voor de correcte AVR doet, zo hebben de ATTiny26 en de ATTiny2313 beide 20 pinnen maar is de pinout volledig anders!

Vervolgens gaan we het programma compileren, hiervoor gebruiken we avr-gcc:

avr-gcc -Os -g -std=gnu99 -Wall -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -DF_CPU=8000000UL -DBAUD=19200UL -I. -I../../AVR-Programming/AVR-Programming-Library/ -mmcu=atmega328p -c -o hello-world.o hello-world.c

Nu hebben we een .o (object-file) maar nog geen .hex binary die we naar de MCU kunnen "branden", hiervoor moeten we eerst nog een .elf bestand maken met het volgende commando:

avr-gcc -Wl,-Map,avrdude.map -Wl,--gc-sections -mmcu=atmega328p hello-world.o -o avrdude.elf

en met avr-objcopy dit .elf bestand converteren naar een .hex bestand:

avr-objcopy -Oihex -R .eeprom avrdude.elf avrdude.hex

Nu hebben we een .hex bestand met als naam avrdude.hex

Dit programma gaan we nu naar de MCU branden met avrdude:

avrdude -c usbtiny -patmega328p -U flash:w:avrdude.hex:i

Figuur 2. AVRDude
AVRDude
Het programma is nu met success geschreven naar de AVR. De USBTinyISP en USBasp programmers zijn de gemakkelijkste om te gebruiken, deze hebben namelijk geen extra parameters nodig. Het enige wat we moeten opgeven is:
  1. -c : De programmer (usbtiny, usbasp, stk500, avr910, etc.)
  2. -p : De processor (mega328p of m328p, t48, t85, etc.)
  3. -U : Het geheugen-type (flash, eeprom, fuse, …)
  4. flash : als parameter van -U, we geven dus aan dat we naar het flash geheugen willen schrijven.
  5. :w: of :r: of :v:
    • w: Write, schrijf naar het flashgeheugen
    • r : Read, lees uit het flashgeheugen (niet altijd mogelijk)
    • v : Verify, lees zowel het flashgeheugen als het bestand en vergelijk deze 2 om te controleren of het branden successvol was (avrdude doet dit automatisch na het branden).
  6. avrdude.hex : het programma dat we willen branden.
  7. :i : Hiermee geven we aan dat het .hex bestand als Intel Hex geformateerd is.

Als je de AVR nu op een breadboard plaatst en 5V aansluit op pin 7, GND (0V) op pin 8 en een led met de anode aan pin 14 (PB0) en de kathode aan GND (0V) dan begint deze te knipperen. Vaak wordt er wel aanbevolen om een condensator van 0.1µF (100nF) tussen VCC (5V) en GND te plaatsen.

Indien je alles correct hebt gedaan, maar het werkt niet dan is het mogelijk dat je een microcontroller hebt die is ingesteld om gebruik te maken van een externe oscillator (crystal). Dit is het geval als je een ATMega328P koopt die is voorgeprogrammeerd met de arduino UNO Bootloader. Om deze microcontroller te laten werken heb je 2 opties:

  1. De microcontroller omschakelen naar de interne oscillator, maar hiervoor heb je een oscillator of resonator nodig, deze kun je dan monteren op je programmer.
  2. Je plaatst de oscillator op je printplaat (deze sluit je aan op pin 9 en 10 en op GND met een condensator van 22pF).

Als je een ATMega328P koopt met UNO Bootloader komt er meestal wel een oscillator van 16MHz en 2 condensatoren bijgeleverd (maar let hier dus op); De meeste andere AVR's komen standaard van de fabriek met de interne oscillator en hiervoor heb je geen externe oscillator nodig.

Heb je een andere programmer dan heb je eventueel andere parameters nodig, hier zijn enkele veel gebruikte:

  • -P : poort (bijv. dev/ttyUSB0)
  • -b : snelheid in baud (bijv. 19200)
  • -n : schrijf niet modus (om te testen)

Voor een volledige lijst met ondersteunde programmers kun je het volgende commando gebruiken: avrdude -c ?

Tot zover het basisgebruik van AVRDude kijkje in de manpages of infopages van AVRDude als je meer wil leren over deze tool.