AVR Development Tools

Read time: 26 minutes (6722 words)

The AVR processors can be programmed using a version of the Gnu C/C++ tools we have been using for projects on the PC. We need a version of those tools that generates code for the AVR chips, not the Pentium!


It is possible to just install the Arduino IDE and get the needed tools. However, the compiler and other needed files live deep inside that code, and finding the right directory to add to your system PATH variable is a bit difficult. We will skip that idea here.

You can add these tools easily, on any system by doing the following steps:


On Linux systems (like Ubuntu) you install the tools as follows:

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


Install the Win-AVR tools from this link:


When I ran this installer on a new PC, I let it modify the system PATH. After doing that, all the old PATH settings were gone, and only the new WinAVR settings were present. For now, make sure you unckeck this option during the install, and add the new PATH setting yourself. I installed this in C:\tools\WinAVR and the executable files are in C:\tools\WinAVR\bin.

C:\> set path


The tools we need here (and just about anything else you might need as a developer) can be installed using Homebrew:

$ brew tap osx-cross/avr
$ brew install avr-gcc
$ brew install avrdude
 This entry may not be the first in the list you see.

Testing Your Build Tools

Test the installation by doing this:

C:\> avr-gcc --version

Of course, make should also be installed!

The CPUfactory3 project has all the components needed to get Make to build AVR projects using your new tools.


To add these required Make components, copy the Makefile and the entire mk folder from CPUfactory3 into your lab2 repository, replacing what is there now. You should be good to go after that.

Run make help in your lab2 project and you should see entries for working with the AVR chip as follows:

$ make help

avr-load:            Load hex file using avrdude
avr-clean:           remove build artifacts
avr-build:           Build AVR project

The avr-build target will create a hex file from any code you create in an AVR project. That includes C++, C and AVR assembly code.

AVR Projects

I set this system up so you can work on any AVR project you like, as long as you create a folder for that project, with some suitable name, and place that project folder inside of a folder named avr at the top-level of your project repository (right beside src, lib, and other directories we are using).

You need to edit the top level Makefile, and change the lines that looks like this:
AVRPROJ := blink
MCU     := attiny85
FREQ    := 16000000L
PGMR    := arduino

The AVRPROJ variable needs to name the AVR project you are working on. This line says we are working on a blink folder, so we will set up that folder for our first project.

$ cd avr
$ mkdir blink

The MCU needs to identify the exact processor you are working with. The example line is for projects we build for use in our simulator. FOr projects you intend to run on the Arduino board, change that line so it looks like this:

MCU := atmega328p

That is the processor on the Arduino UNO boards.

The FREQ variable tells the compiler how fast the processor is running. On the Arduino boards, the processor runs at 16 MHz, just what this line says. Leave this one alone.

Finally, the PGMR line is used by the loader program so it can transfer your hex file to the Arduino board you are using.

Configuring VM For Arduino

We have one more setup task to work through. IN order to program the AVR chip, we need to get your VM to hook onto the USB port you end up using when you plug the board into your host machine. VirtualBox can be told to pass that connection through to the VM, but doing so was a bit of a struggle to figure out.


These steps have worked for me. If you have problems getting your system to recognize the Arduino, let me know and we will work through fixing the issues.

Enable USB Support

You probably did not set up USB when you initially constructed your VM. To fix that, make sure your VM is powered down (not sleeping) and do this:

Open up the VirtualBox control panel, and select your machine name. Then click on Settings -> Ports -> USB``. Click on Enable USB Controller, and make sure USB 2.0 is selected.

Identify your Board

To get VirtualBox to automatically grab the Arduino board when you plug it in, we need to set up a “filter”. On your host machine, with the Arduino board plugged in, run this command:

$ vboxManage list usbhost

UUID:               a9c46813-f01b-4879-bf7a-15574552029d
VendorId:           0x2341 (2341)
ProductId:          0x0043 (0043)
Revision:           0.1 (0001)
Port:               2
USB version/speed:  0/Full
Manufacturer:       Arduino (www.arduino.cc)
Product:            IOUSBHostDevice
SerialNumber:       95333353836351516142
Address:            p=0x0043;v=0x2341;s=0x00003d07c4d9d44b;l=0x14200000
Current State:      Busy


I saw a lot of entries on my Mac. This one specifically mentioned the Arduino.

Now open up the VirtualBox control panel, and get back to the settings area for the USB port. Click on the Add FIlter icon on the right side of the USB Filters panel. Then click on the icon that says Edit Filter. Make these changes:

  • NAME: Arduino
  • Vendor ID: 2341
  • Product ID: 0043
  • Manufacturer: Arduino
  • Serial No: 95333353836351516142


Change the settings for your specific board.

Now, unplug the Arduino board and power up your VM.

Once you are logged in, plug in the board. On the VirtualBox menu, select Devices -> USB. Click on the Arduino board entry.

Next, verify that your VM can see the board:

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

The Arduino entry says everything is fine.

Next, we need to make sure we really can communicate with the Arduino.

$ ls /dev | grep ttyACM0

That command is strange. What we are doing is listing all of the entries in the /dev folder. There are lots of entries there, one for each physical device Linux can work with. Somewhere in that listing is the entry I should see with my Arduino board plugged in. Your system should see it on ttyACM0. The grep command tells the system to lok for that string in the input it receives. We are using a command line “pipe” character to send the output from the ls command into the input to the grep command. grep will only show us the lines where that pattern was seen (if any!) If you see that name as a respnse, you know your board is attached, and ready to go!

Finally,, we need to make sure your user can access the USB port:

$ sudo usermod -a -G dialout $USER

Reboot Your VM

After doing all of this, reboot your VM.

Install Arduino

We are going to install the latest Arduino IDE inside of your VM, so you can use any Arduino project code you find on the INternet to experiment with this board.


We will not be building our applications using this tool in this class.

If your VM is running the latest Ubuntu LTS release (18.04 on my system). You can install the IDE by doing this inside of your VM:


If you are running Ubuntu 16.04 or earlier, see me for help.

$ sudo apt-get update
$ sudo apt-get install ubuntu-make

This installs a new application build file for programs set up specifically to run in the Ubuntu OS.

Install the IDE

Run this command next:

$ umake ide arduino

Now, fire up the IDE. Under Boards, select your board (UNO if using one of mine). Under Port, select ttyACM0`. Now, try out the standard "Hello, World"" Arduino_ project. Click on ``Files -> Examples -> Basic -> Blink. Once that code is loaded, click on the button with a check mark on it. This will compile the program. Then click on the button with the right-arrow on it. This will load the program on the board. You will see lights flash on the Arduino board as the code is loaded. Once loading completes, the LED on the board should be blinking at a steady rate.

If you get this running, you are in good shape. (If not, see me for help!). Now we can go back to building our assembly language code!