The Definitive Guide to AVRDUDE!

Have you used an Arduino recently? Do you absolutely love the whole experience – writing abstracted code, getting off-the-ground quickly and seeing that LED blink or that motor go wrrrrrr or know the temperature around you? Have you wondered what makes the whole process of getting your firmware into the AVR microcontrollers so breezy! It is AVRDUDE or AVR Downloader/UploaDEr!

AVRDUDE is an open-source, high-quality programming utility started by a fine gentleman called Brian S. Dean and has since then seen a lot of contributions from amazing people all around the globe. The best part is that supports almost all AVR microcontrollers, works with a lot of programming adapters that are used generally with these microcontrollers and also work with different file formats like Intel HEX, ELF or a raw binary. By the way, this utility is not just for programming the flash but also reading from it, verifying it, programming the fuses, verifying them, reading the device signature and so on! It is a one-stop shop to talk to your AVR.

This post tries to teach the most commonly used features of this amazing and lightweight tool.

How can I get AVRDUDE?

It is extremely simple to get AVRDUDE – choose the method below that applies to you.

If you are on a Windows machine…

Choose the release of interest from here: http://download.savannah.gnu.org/releases/avrdude/ – Easy peasy!

If you are on a Linux machine…

Most well-known linux distros have the avrdude present as a downloadable package in their package-managers!

For example: the terminal commands to install AVRDUDE on Ubuntu are:

$ sudo apt update
$ sudo apt install avrdude

If you are on a Mac…

Good news! AVRDUDE is available on home-brew…just pour it into your Mac! 😉

For example: the terminal commands to install avrdude in a Mac are:

$ brew update
$ brew install avrdude

How do I know my installation is OK?

The best way to check that your AVRDUDE installation went well is to fire up a terminal window and run the below command. You should get an output as shown.

NOTE: If you are on Windows and have not added the path to AVRDUDE to your PATH, then you will first need to navigate to the path where AVRDUDE is located and then do the below.

The below is the sample output as seen on an Ubuntu 20.04 installation done using apt.

$ avrdude -v
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 "/etc/avrdude.conf"
         User configuration file is "/home/shashank/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping


avrdude: no programmer has been specified on the command line or the config file
         Specify a programmer using the -c option and try again

If you get an output that looks anything other than the above, you may need to re-visit your installation steps!

How do I use AVRDUDE?

Avrdude expects a number of inputs in order to understand what you want to do. Some of the important ones are listed below.

  1. -p – This specifies the AVR devices that you want to program. To see a list of the devices that are supported, you can run:
    $ avrdude -p ?
    For example, if the device of interest is ATmega328p (same as that on Arduino Nano), then the selection would be m328p
  2. -b – This specifies the baud rate of the communication. This configuration is actually a part of the programmer configuration which will be passed to the AVRDUDE – however, if you wish to override that setting, then a value can be passed here
  3. -B – This specifies the JTAG bit clock period in microseconds – if you are not using a JTAG based programmer (eg: Arduino), then this setting is not relevant
  4. -C – This specifies the location of the configuration file. If not specified, this will be the default path. For eg: /etc/avrdude.conf in a linux installation
  5. -c – This is a very important configuration that tells avrdude what programmer the avrdude has to use to program the AVR chip. The programmer configuration contains other pertinent configurations like JTAG bit clock period, RS232 baud rate and any other relevant parameter. To see a list of supported programmers, just execute:
    $ avrdude -c ?
    In a typical Arduino installation, when the flash button is clicked, the avrdude is invoked with the programmer as -carduino
  6. -P – This is the connection port that the avrdude has to use to connect to the programmer. You should make sure that the user has the privilege to access the port. For example, on linux the port setting may be something like:
    $ avrdude -P /dev/ttyUSB0
  7. -U – This is a very important parameter for avrdude. It specifies the memory operation that you want avrdude to perform. The structure of the parameter is like this:
    -U <memtype>:r/w/v:<filename>[:format]
    The memtype specifies the type of memory that is to be programmed. This value can be calibration, eeprom, efuse, flash, fuse, hfuse, lfuse, lock, signature, fuseN (N is the fuse number), application, apptable, boot, prodsig, usersig. Note that some of these options will only work with devices that support them. For example: the apptable will only work with a small subset of AVR devices.
    The operation type can be r for read, w for write and v for read and verify from a file passed as input.
    The filename is the name of the file which has to be written or read from for read or verify operation.
    The optional input called format can be i for Intel HEX, s for Motorola S-record, r for raw binary, e for ELF, m for immediate mode where the filename is replaced with the actual values to write (0x<value> for hex, 0<value> for octal, else decimal), a for autodetect. If you do not plan to specify the format, DO NOT put a : after the filename. Default setting is to use autodetect for input file and binary for output file.
  8. -v –  Enable verbose output – this is very important to understand what and how avrdude does what it does. If -v is the only parameter passed, you get the version information of the avrdude.
  9. -V – Disable automatic verify check when uploading data – this will be slightly faster as the verify step is skipped.
  10. -F – Disable automatic signature check of the device that we want to connect to.
  11. -D – Disable full memory erase of the AVR chip – highly recommended
  12. -? – Get usage of avrdude

There are some other options like exitspec (-E) , quell (-q), logging (-l), etc. which are less commonly used. Let us now see some AVRDUDE commands in action on a real board!

Using AVRDUDE with an Arduino Nano board

If you already have a hex file ready, skip to the signature read section below. Else, do the steps below to get a blinky hex file for your use.

Getting a sample hex file

To do some basic programming using AVRDUDE, let us quickly write a blinky for Arduino Nano as below:

// A simple blinky - blinks the on-board LED at a frequency of 1 Hz

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

Say, the build output for this Arduino sketch is named blinky_arduinonano.hex.

PRO-TIP: If you want to locate the hex file that is generated when you compile the Arduino sketch, you should first enable “Show Verbose Output” in your Arduino preferences. The path to the hex file (and others) can be seen clearly in the avr-gcc, avr-objcopy and avr-size commands.

For example: below is the line that contains the path of the hex file during the compilation on an Arduino installation on a Mac.

...
...

/private/var/folders/q0/1wmxrlks63jg6qqh4_6nzxfw0000gn/T/AppTranslocation/F9FC15D6-93A7-4613-8BBF-A7E9F192B9F1/d/Arduino.app/Contents/Java/hardware/tools/avr/bin/avr-objcopy -O ihex -R .eeprom /var/folders/q0/1wmxrlks63jg6qqh4_6nzxfw0000gn/T/arduino_build_91871/sketch_oct28a.ino.elf /var/folders/q0/1wmxrlks63jg6qqh4_6nzxfw0000gn/T/arduino_build_91871/sketch_oct28a.ino.hex

...
...

Reading the AVR device signature using AVRDUDE

Let us read the device signature which is basically a confirmation that we are indeed talking to the right device. Unless signature check is explicitly disabled using the -F argument, the signature check is always done by AVRDUDE.

The command to read the device signature for the AVR chip on your Arduino Nano is as below. The expected output is also shown.

$ avrdude -p m328p -c arduino -P /dev/ttyUSB0 -U signature:r:file.bin
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading signature memory:

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

avrdude: writing output file "device_signature.bin"

avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done.  Thank you.

The signature bytes as reported by AVRDUDE are 0x1E, 0x95, 0x0F. These match the values given in the ATmega datasheet – so far, so good!

Signature Bytes for ATmega328P present on Arduino Nano (taken from ATmegaxx data sheet)

Programming the hex file using AVRDUDE

Let us now flash our blinky to the ATmega328p located on the Arduino Nano.

The command to do so is as below. The expected output is also shown.

$ avrdude -p m328p -c arduino -P /dev/ttyUSB0 -U flash:w:blinky_arduinonano.hex:i -D
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading input file "blinky_arduinonano_arduino.ino.hex"
avrdude: input file blinky_arduinonano_arduino.ino.hex auto detected as Intel Hex
avrdude: writing flash (924 bytes):

Writing | ################################################## | 100% 0.19s

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

Reading | ################################################## | 100% 0.16s

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

avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done.  Thank you.

In the above command we told AVRDUDE that it needs to write (w) to the flash a file called blinky_arduinonano.hex which is in the Intel hex (i) format. We also told it to not erase the entire chip (-D) – just the relevant areas.

Reading the flash memory using AVRDUDE

Let us now try to read back the contents of the flash inside the ATmega328p chip located on the Arduino Nano.

The command to do so is as below. The expected output is also shown.

$ avrdude -p m328p -c arduino -P /dev/ttyUSB0 -U flash:r:flash_read.bin
avrdude: AVR device initialized and ready to accept instructions

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

avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: reading flash memory:

Reading | ################################################## | 100% 5.01s

avrdude: writing output file "flash_read.bin"

avrdude: safemode: Fuses OK (E:00, H:00, L:00)

avrdude done.  Thank you.

Liked this post? Do share it with others who want to learn about AVRDUDE!

Leave a Reply