AVR on Linux

From STAB Resources

Jump to: navigation, search

This is a short HowTo to get the gnu-AVR Toolchain working on a linux machine.
It is primarily oriented at an Ubuntu audience. Although it should work with any distribution of linux.

Contents

Prerequisites

This is a HowTo on getting AVR working on Linux machine. Basic familiarity with both is assumed.

Before proceeding ensure that you know the following basics:

  1. Installing packages using Synaptic
  2. Basics of using the AVR Family devices

Basics of the AVR Toolchain

These are the items that make up the AVR-GCC toolchain:

gcc The actual C/C++ Compiler
binutils A collection of tools, including the assembler, linker and some other tools to manipulate the generated binary files.
libc-avr A subset of the standard C Library with some additional AVR specific functions. The libc-avr package also includes the AVR specific header files.
gdb The debugger. See the Debugging section for more information about this.
avrdude A Programm to download/upload/manipulate the ROM and EEPROM of an AVR MCU.

At the core of the avr-gcc toolchain and absolutely required to build AVR applications, are the compiler, the binutils collection and the libc library. While the last one is a dedicated project, the first two (and gdb) are part of the GNU Project.

Packages on Ubuntu

Install the following packages using synaptic:

Any dependencies will be automatically installed.

You can also do it from the terminal by typing:

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

Operation Not Permitted Error

In Ubuntu by default access to the USB port is restricted. As such you may encounter the following error:

avrdude: usb_open(): cannot read serial number "error sending control message: Operation not permitted"

There are 2 fixes to this problem.

  • Issue the command to burn the hex file as root using sudo.
  • Change the udev file to add rules for your programmer


Editing the udev file

Open the following file using sudo:

sudo gedit /etc/udev/rules.d/41-atmega.rules

Add the following lines to it

# Please test and place config for other programmers here
# USBasp
ATTR{idVendor}=="16c0", ATTR{idProduct}=="05dc", GROUP="users", MODE="0666"

Ensure that you are added into the "users" group:

sudo usermod -a -G users your_username

Makefile

Customizing the makefile

Edit lines 68, 72, 79, 106, 111 in the template given to customize the file for your project

Makefile Template

#########  AVR Project Makefile Template   #########
######                                        ######
######    Copyright (C) 2003, Pat Deegan,     ######
######            Psychogenic Inc             ######
######          All Rights Reserved           ######
######                                        ######
###### You are free to use this code as part  ######
###### of your own applications provided      ######
###### you keep this copyright notice intact  ######
###### and acknowledge its authorship with    ######
###### the words:                             ######
######                                        ######
###### "Contains software by Pat Deegan of    ######
###### Psychogenic Inc (www.psychogenic.com)" ######
######                                        ######
###### If you use it as part of a web site    ######
###### please include a link to our site,     ######
###### http://electrons.psychogenic.com  or   ######
###### http://www.psychogenic.com             ######
######                                        ######
####################################################


##### This Makefile will make compiling Atmel AVR 
##### micro controller projects simple with Linux 
##### or other Unix workstations and the AVR-GCC 
##### tools.
#####
##### It supports C, C++ and Assembly source files.
#####
##### Customize the values as indicated below and :
##### make
##### make disasm 
##### make stats 
##### make hex
##### make writeflash
##### make gdbinit
##### or make clean
#####
##### See the http://electrons.psychogenic.com/ 
##### website for detailed instructions


####################################################
#####                                          #####
#####              Configuration               #####
#####                                          #####
##### Customize the values in this section for #####
##### your project. MCU, PROJECTNAME and       #####
##### PRJSRC must be setup for all projects,   #####
##### the remaining variables are only         #####
##### relevant to those needing additional     #####
##### include dirs or libraries and those      #####
##### who wish to use the avrdude programmer   #####
#####                                          #####
##### See http://electrons.psychogenic.com/    #####
##### for further details.                     #####
#####                                          #####
####################################################


#####         Target Specific Details          #####
#####     Customize these for your project     #####

# Name of target controller 
# (e.g. 'at90s8515', see the available avr-gcc mmcu 
# options for possible values)
MCU=atmega16

# Name of our project
# (use a single word, e.g. 'myproject')
PROJECTNAME=blink

# Source files
# List C/C++/Assembly source files:
# (list all files to compile, e.g. 'a.c b.cpp as.S'):
# Use .cc, .cpp or .C suffix for C++ files, use .S 
# (NOT .s !!!) for assembly source code files.
PRJSRC=blink.c

# additional includes (e.g. -I/path/to/mydir)
INC=

# libraries to link in (e.g. -lmylib)
LIBS=

# Optimization level, 
# use s (size opt), 1, 2, 3 or 0 (off)
OPTLEVEL=s


#####      AVR Dude 'writeflash' options       #####
#####  If you are using the avrdude program
#####  (http://www.bsdhome.com/avrdude/) to write
#####  to the MCU, you can set the following config
#####  options and use 'make writeflash' to program
#####  the device.


# programmer id--check the avrdude for complete list
# of available opts.  These should include stk500,
# avr910, avrisp, bsd, pony and more.  Set this to
# one of the valid "-c PROGRAMMER-ID" values 
# described in the avrdude info page.
# 
AVRDUDE_PROGRAMMERID=usbasp

# port--serial or parallel port to which your 
# hardware programmer is attached
#
AVRDUDE_PORT=/dev/usb0


####################################################
#####                Config Done               #####
#####                                          #####
##### You shouldn't need to edit anything      #####
##### below to use the makefile but may wish   #####
##### to override a few of the flags           #####
##### nonetheless                              #####
#####                                          #####
####################################################


##### Flags ####

# HEXFORMAT -- format for .hex file output
HEXFORMAT=ihex

# compiler
CFLAGS=-I. $(INC) -g -mmcu=$(MCU) -O$(OPTLEVEL) \
	-fpack-struct -fshort-enums                 \
	-funsigned-bitfields -funsigned-char        \
	-Wall -Wstrict-prototypes                   \
	-Wa,-ahlms=$(firstword                      \
	$(filter %.lst, $(<:.c=.lst)))

# c++ specific flags
CPPFLAGS=-fno-exceptions            \ 
	-Wa,-ahlms=$(firstword          \
	$(filter %.lst, $(<:.cpp=.lst)) \
	$(filter %.lst, $(<:.cc=.lst))  \
	$(filter %.lst, $(<:.C=.lst)))

# assembler
ASMFLAGS =-I. $(INC) -mmcu=$(MCU)   \
	-x assembler-with-cpp           \
	-Wa,-gstabs,-ahlms=$(firstword  \
		$(<:.S=.lst) $(<.s=.lst))


# linker
LDFLAGS=-Wl,-Map,$(TRG).map -mmcu=$(MCU) -lm $(LIBS)

##### executables ####
CC=avr-gcc
OBJCOPY=avr-objcopy
OBJDUMP=avr-objdump
SIZE=avr-size
AVRDUDE=avrdude
REMOVE=rm -f

##### automatic target names ####
TRG=$(PROJECTNAME).out
DUMPTRG=$(PROJECTNAME).s

HEXROMTRG=$(PROJECTNAME).hex 
HEXTRG=$(HEXROMTRG) $(PROJECTNAME).ee.hex
GDBINITFILE=gdbinit-$(PROJECTNAME)

# Define all object files.

# Start by splitting source files by type
#  C++
CPPFILES=$(filter %.cpp, $(PRJSRC))
CCFILES=$(filter %.cc, $(PRJSRC))
BIGCFILES=$(filter %.C, $(PRJSRC))
#  C
CFILES=$(filter %.c, $(PRJSRC))
#  Assembly
ASMFILES=$(filter %.S, $(PRJSRC))


# List all object files we need to create
OBJDEPS=$(CFILES:.c=.o) \
	$(CPPFILES:.cpp=.o) \
	$(BIGCFILES:.C=.o)  \
	$(CCFILES:.cc=.o)   \
	$(ASMFILES:.S=.o)

# Define all lst files.
LST=$(filter %.lst, $(OBJDEPS:.o=.lst))

# All the possible generated assembly 
# files (.s files)
GENASMFILES=$(filter %.s, $(OBJDEPS:.o=.s)) 


.SUFFIXES : .c .cc .cpp .C .o .out .s .S .hex .ee.hex .h .hh .hpp


.PHONY: writeflash clean stats gdbinit stats

# Make targets:
# all, disasm, stats, hex, writeflash/install, clean
all: $(TRG)

disasm: $(DUMPTRG) stats

stats: $(TRG)
	$(OBJDUMP) -h $(TRG)
	$(SIZE) $(TRG) 

hex: $(HEXTRG)


writeflash: hex
	$(AVRDUDE) -c $(AVRDUDE_PROGRAMMERID)   \
	 -p $(MCU) -P $(AVRDUDE_PORT) -e        \
	 -U flash:w:$(HEXROMTRG)

install: writeflash

$(DUMPTRG): $(TRG) 
	$(OBJDUMP) -S  $< > $@


$(TRG): $(OBJDEPS) 
	$(CC) $(LDFLAGS) -o $(TRG) $(OBJDEPS)


#### Generating assembly ####
# asm from C
%.s: %.c
	$(CC) -S $(CFLAGS) $< -o $@

# asm from (hand coded) asm
%.s: %.S
	$(CC) -S $(ASMFLAGS) $< > $@


# asm from C++
.cpp.s .cc.s .C.s :
	$(CC) -S $(CFLAGS) $(CPPFLAGS) $< -o $@




#### Generating object files ####
# object from C
.c.o: 
	$(CC) $(CFLAGS) -c $<


# object from C++ (.cc, .cpp, .C files)
.cc.o .cpp.o .C.o :
	$(CC) $(CFLAGS) $(CPPFLAGS) -c $<

# object from asm
.S.o :
	$(CC) $(ASMFLAGS) -c $< -o $@


#### Generating hex files ####
# hex files from elf
%.hex: %.out
	$(OBJCOPY) -j .text -j .data -O $(HEXFORMAT) $< $@

%.ee.hex: %.out
	$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O $(HEXFORMAT) $< $@


#####  Generating a gdb initialisation file    #####
##### Use by launching simulavr and avr-gdb:   #####
#####   avr-gdb -x gdbinit-myproject           #####
gdbinit: $(GDBINITFILE)

$(GDBINITFILE): $(TRG)
	@echo "file $(TRG)" > $(GDBINITFILE)
	
	@echo "target remote localhost:1212" >> $(GDBINITFILE)
	
	@echo "load"        >> $(GDBINITFILE) 
	@echo "break main"  >> $(GDBINITFILE)
	@echo "continue"    >> $(GDBINITFILE)
	@echo
	@echo "Use 'avr-gdb -x $(GDBINITFILE)'"


#### Cleanup ####
clean:
	$(REMOVE) $(TRG) $(TRG).map $(DUMPTRG)
	$(REMOVE) $(OBJDEPS)
	$(REMOVE) $(LST) $(GDBINITFILE)
	$(REMOVE) $(GENASMFILES)
	$(REMOVE) $(HEXTRG)
	


#####                    EOF                   #####

Sample Project

Use the following test code to check your toolchain:

#include<avr/io.h>
#define F_CPU 16000000L
#include<util/delay.h>

int main(void){
  DDRC  = 0xff;
  PORTC = 0x3f;
  while(1){
	_delay_ms(1000);
	PORTC ^= 0x0f;
	}
  return 0;
}

Save the file in the same folder as the above Makefile. Use the following commands:

To compile the source code

 make hex 

To install the hexfile

 make install 

To delete all the object and output files

 make clean 

To get the memory usage stats

 make stats 

To get only the dis-assembly listing

 make disasm 

To generate debugging symbols

 make gdbinit 
Personal tools
Namespaces
Variants
Actions
Navigation
Clubs
Toolbox