How to compile and burn the code to AVR chip on Linux/MacOSX/Windows ?

This is a quick tutorial for beginners that aims to show how to install tools, compile the code with avr-gcc and send it to the MCU with avrdude. It also introduce basics of automation of this task by putting the all instructions into Makefile. The example files (main.c, main.bin, main.hex, Makefile) has been packaged as a .ZIP file and can be downloaded here.

1. Installing avr-gcc and tools

To compile C and/or C++ source code of your firmware you will need gcc-avr compiler, the avr-libc C library and avrdude. What is extremely useful, there are complete and easy to install packages for all major platforms.

Linux, Ubuntu

Ubuntu provides packages, so you can just install them using this command.

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

Mac OSX

Download AVR MacPack. The MacPack disk image has an installer that does everything for you.

Windows

Download WinAVR, which includes everything you need and has a nice installer.

2. Compiling and burning the code

Now that you have the compiler installed, a next step is to compile simple source code into a .BIN file, then generate Intel .HEX file and finally burn this .HEX file to AVR chip using USBasp programmer.

Example code

Here is an example content of main.c file. The code does nothing except getting stuck in an endless loop but it’s always something!

int
main(void)
{

        while (1);
}

Compiling

The command below will compile your code. It’s GCC so I assume it looks familiar to you and no additional explanations are needed. If you want perform compilation for some other MCU then you need specify appropriate -mmcu option.

$ avr-gcc -Wall -g -Os -mmcu=attiny13 -o main.bin main.c

After performing successful compilation, you can check program and data memory size with this command.

$ avr-size -C main.bin
AVR Memory Usage
----------------
Device: Unknown

Program:      40 bytes
(.text + .data + .bootloader)

Data:          0 bytes
(.data + .bss + .noinit)

Generating .HEX

Most programmers will not accept a GNU executable as an input file, so we need to do a little more processing. So the next step is about converting the information form .BIN into .HEX file. The GNU utility that does this is called avr-objcopy.

$ avr-objcopy -j .text -j .data -O ihex main.bin main.hex

Burning

The utility called avrdude can program processors using the contents of the .HEX files specified on the command line. With the command below, the file main.hex will be burned into the flash memory. The -p attiny13 option lets avrdude know that we are operating on an ATtiny13 chip. In other words – this option specifies the device. The full list of supported parts can be found here. Note that full-length names are also acceptable (i.e. t13 equals attiny13).

$ (sudo) avrdude -p attiny13 -c usbasp -U flash:w:main.hex:i -F -P usb

Voila! Chip is programmed.

3. Make and makefiles

Now, we can automate this process by creating a Makefile and putting our commands there. The structure of a Makefile is very simple, and more information about it can be found here. Utitlity make reads automatically a Makefile file in the folder where you launch it. Take a look at a ready-made example.

MCU=attiny13
F_CPU=1200000
CC=avr-gcc
OBJCOPY=avr-objcopy
CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
TARGET=main
SRCS=main.c

all:
        ${CC} ${CFLAGS} -o ${TARGET}.bin ${SRCS}
        ${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex

flash:
        avrdude -p ${MCU} -c usbasp -U flash:w:${TARGET}.hex:i -F -P usb

clean:
        rm -f *.bin *.hex

If you launch a simple make in the terminal, only label “all” will be executed. When you launch (sudo) make flash label “flash” will be executed, and so on.

$ make
avr-gcc -std=c99 -Wall -g -Os -mmcu=attiny13 -DF_CPU=1200000 -I. -o main.bin main.c 
avr-objcopy -j .text -j .data -O ihex main.bin main.hex    
$ sudo make flash
avrdude -p attiny13 -c usbasp -U flash:w:main.hex:i -F -P usb

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 = 0x1e9007
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: warning: cannot set sck period. please check for usbasp firmware update.
avrdude: reading input file "main.hex"
avrdude: writing flash (40 bytes):

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

avrdude: 40 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 40 bytes
avrdude: reading on-chip flash data:

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

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

avrdude: safemode: Fuses OK (H:FF, E:FF, L:6A)

avrdude done.  Thank you.

4. Summary

Essentially, assuming that our program is in main.c, only those three things are needed to compile and burn the code to AVR chip.

$ avr-gcc -Wall -g -Os -mmcu=attiny13 -o main.bin main.c
$ avr-objcopy -j .text -j .data -O ihex main.bin main.hex
$ (sudo) avrdude -p attiny13 -c usbasp -U flash:w:main.hex:i -F -P usb

It’s important to highlight that we can easily automate whole process with Makefiles. Sooner or later you will need it!

Attachments

2 thoughts on “How to compile and burn the code to AVR chip on Linux/MacOSX/Windows ?

  1. HI,
    I am getting an error while uploading it using the avrdude
    avrdude: error: program enable: target doesn’t answer. 1
    avrdude: initialization failed, rc=-1
    avrdude: AVR device initialized and ready to accept instructions
    avrdude: Device signature = 0x88dbe5
    avrdude: Expected signature for ATmega328P is 1E 95 0F
    avrdude: NOTE: “flash” memory has been specified, an erase cycle will be performed
    To disable this feature, specify the -D option.

    avrdude done. Thank you.

    It would be really nice if you could help me with it.

    • Hi, unfortunately a lot of things could happen here:

      • check connections MOSI and MISO.
      • check MCU power supply
      • maybe your programmer is in Slow SCK mode
      • check all GND are connected
      • invalid clock source / crystal (fuse flags)
      • many more..

Leave a Comment