AVR microcontrollers

Some might say 8 bit AVR microcontrollers are outdated since 32bit microcontrollers are available for the same price. However 32bit microcontrollers have an SMD package and need to be reflow soldered to a PCB. A PCB with a 32bit microcontroller is not much cheaper to the hobbyist than a small Linux device as a raspberry.

Therefore a AVR in a DIL case is really a nice device to have something small running.

My strategy for a hobbyist is use AVR (preferably in DIL case) for the real tiny stuff attaching other hardware as sensors and Linux (as Raspberry) for where SW is required. And have them communicate with each other via virtual serial link over USB that does both in one cable as supply power and exchange data.

The following concentrates on the AVR micro controllers from https://www.microchip.com/ and the C development environment http://www.nongnu.org/avr-libc/, since there is a good Linux, chip and development hardware support.

gcc stands for gnu compiler collection and therefore a straight forward way is adding the avr gcc cross compiler to the list, so gcc-config -l will show it.

Alternatively there is also a tested tool chain from microchip (formerly Atmel) where registration is required. There is a 32bit or 64bit version. Since everything is included the 32bit version runs as well on a 64bit machine if the kernel is setup correctly. Those compiler versions will create all in a separate directory apart from the systems gcc. There is no need to fiddle around to get a working cross compiler and AVR development can start immediately. To have the command line find the command the <installed directory>/bin should be added to the path PATH="<installed directory>/bin:${PATH}"some IDE's as Code::Blocks allow to set the path too.

Building Avr crosscompiler under Gentoo Linux

On Gentoo Linux a good way is following the first section of the Arduino installation guide that explains how to get gcc https://wiki.gentoo.org/wiki/Arduino

In the cross compilation section the preparatory steps are explained, after that the last stable -S gcc compiler can be get by crossdev -S -t avr

Note

The warning about !!! WARNING - Cannot auto-configure CHOST avr !!! can be ignored, since a generic CHOST definition will be made.

The installation goes in /usr/avr and the ebuilds that crossdev created and executed are (when followed the above steps) in /usr/local/portage/local-overlay/cross-avr . Since there are ebuilds (or exactly links to ebuilds) their version can be observed using emerge -s avr-libc

To get rid of what crossdev -t avr did:

crossdev -C avr

gcc-config -l should now also show the gcc-avr among the list of gcc's.

Note

Having avr-gcc up and running is one thing. Having it produce runnable code is unfortunately something else.

Setoutput

To make first steps in programming, the first program puts "hello world" on the screen. Since micro controllers do not have a screen, the first program has to do something more simple, just activation of pins. Here the sample program:

Example 3.2. setoutput

#include <avr/io.h> 
int main (void) {
  char i;
  DDRB = 0xff;
  PORTB = 0xaa; 
 
  while(1) {
    PORTB= i++;
  }
  return (0);
}

The program sets the Data Direction Register of port B to have outputs on all 8 pins. Then it writes 10101010 binary or hex aa to it and goes to hang in a endless while loop where the variable i gets incremented and put to port B.

Compiling and linking

Additional to the above sample program there are other same programs available as for gcc, but with the prefix: avr-gcc -mmcu=atmega8 setoutput.c this does both compiling and linking and produces the a.out file.

Example projects can be found in /usr/share/doc/avr-libc-1.4.6/examples

Include files are in /usr/avr/include

If it does not work then

ln -s /usr/i686-pc-linux-gnu/avr/lib/ldscripts /usr/avr/lib/ldscripts might be have done for x86 or for amd64

ln -s /usr/x86_64-pc-linux-gnu/avr/lib/ldscripts /usr/avr/lib/ldscripts

see also https://wiki.hacdc.org/index.php/Installing_AVR_Toolchain

Manual compilation and linking

Manually two commands have to be executed.

To compile:

avr-gcc -g -Os -mmcu=atmega16 -c<program name>.c

To link

avr-gcc -g -mmcu=atmega16 -o<program name>.elf <program name>.o

And you get the binary output file <program name>.elf that is now ready to program into the micro controller.

Linker scripts are used to tell the linker how to put the files together to match the physical memory.

Options:

-mmcu the cpu type and is mandatory. It adds the cstart up routine to the program. If it is missing compilation and linking might pass without an error but then an unpredictable program is created.

-c do not link

-g produce debugging information

-Os optimize for size, however this gets almost impossible to debug its source code, so do -O0

-o define other output file name than the default name a.out

Makefile

As usual, the program gets big and needs to be separated in different files. Creating a makefile as usual with gcc and therefore not further explained here will resolve the handling of the project. Compilation and linking is done with the command

make

that performs sequentially all all necessary steps.

make clean

should delete everything that has automatically produced.

Observing the result

The output file <program name>.elf can not be observed directly since it is binary, but it can be observed by:

avr-objdump -h -S <program>.elf

Options:

-h show the section headers in the elf file

-S show source code with disassembly

Since this generates a big output it can be deviated into a list file that can be observed using an editor (check also for a lss file since this might be the same and already generated): avr-objdump -h -S <program>.elf > <program>.lst

Or the regular objdump -h <program>.elf can be used when no disassembly is required. To see all the bytes objdump -s <program>.elf .

An other way is readelf -all <program>.elf to get a readable form of the binary elf file.

For embedded CPU's just the memory contents in the non volatile memory is important. However this has to be already be divided into two blocks, when using a CPU with Harvard architecture as the avr has. A part goes a program instructions into the instruction memory, the other part is static data and goes into the data memory. The Harvard architecture has both separated, whereas the Von Neumann architecture have one memory area for both, data and instructions. The elf format is quite flexible and groups the result of the compilation into sections. The main sections are:

Segment

Holds

.text

Is the flash contents starting from 0 with the reset vector, following all other interrupt vectors, then following the boot code including a routine for uninitialized interrupts causing reset and finally following the compiled and assembled C instructions. At the end of it the code of the libraries is added. Since the memory starts from 0, size of .text is the last address used plus 1.

.data

Is the SRAM content for initialized variables. Since the addresses starting from 0 are used for the IO's, the internal SRAM starts usually at address 0x100. Since avr use an Harvard architecture (program memory and data memory in two separate address spaces) an offset of 0x800000 is added to mark that.

.bss

Is SRAM used for not initialized variables

.eeprom

Is data initialized in EEPROM. Again EEPROM has its own address space and theerfore it is marked in the elf file with the offset of 0x810000.

To produce a linker map file (if not automatically already created) avr-gcc can be called as

avr-gcc -g -mmcu=atmega16 -Wl,-Map,<program>.map -o <program>.elf <program>.o

Note

avr-libc provides also the startup code required for the micro controller. Regular Linux programs make use of Linux and therefore do not need anything to initialize the CPU. Some small avr micro controller are restricted to assembly programming only.

The avr-libc library contains the modules as <math.h> that can be included in the C program. And there are also the necessary header files. The libraries are in /usr/avr/lib and have to be told to the linker either by -l<name without the 3 characters lib> or -L<path>.

Stackpointer

Each time a subroutine is called or an interrupt is handled temporary data such as current program counter and local variables are saved on the stack. There is the stack pointer that points into regular SRAM where the next save is done. Two normally accessible 8bit registers are reserved for that SPH and SPL The stackpointer is initialized after reset with the highest SRAM address and decrements when data is stored and increments when data is removed.

The stack grows therefore down from the highest SRAM address. A stack overflow occurs when it hits the highest SRAM address used by the application for data storage. This is quite a dynamical and therefore hardly prediction event. Also it impact is hardly predictable, it can result in a program crash causing a reset or watchdog trigger, but it can also just cause that unpredictable data occurs (especially with memory space consuming strings operations).

Since it is a dynamical process a stackoverflow can not be easily detected. Since it depends on asynchronously events, it can happen that it works well in the laboratory but then it crashes in the field. There are basically the following methods:

  • Observe SP during debugging

  • If supported in-circuit emulator setting a breakpoint to SRAM, when the stack hits it triggers.

  • Fill the empty SRAM space with a data pattern and see where the stack went. This can also be done manually by writing into SRAM in the debug environment. Both sides of the SRAM can be observed, the area above the last variables in SRAM (top of .bss) and the stack itself, since SRAM is initialized with zero and the stack does not clean up where it was, it can be observed on the top addresses of SRAM where it wrote.

  • Create a variable that is updated by interrupts to the lowest value the stackpointer gets (maybe use a timer interrupt for that)

avr-objdump -h <program>.elf | grep .bss will produce something as

2 .bss 0000021d 008002fc 008002fc 00001dfe 2**0

Adding together the first two hex numbers (Size and start address of .bss) gives the top of of SRAM used for the variables 0x21d + 0x2fc = 0x519 = 1305

To reduce amount of required SRAM, it could be considered to move the constant data (as strings) from SRAM to FLASH. However since a Harvard architecture with separate memory spaces for FLASH and SRAM is used accessing data in teh program memory space is tricky.

Assembler

There are reasons why to deal with assembly language:

  1. The gcc calls avr-as the assembler therefore a basic understanding of assembler is useful.

  2. There are also micro controllers that are simply too small and too little memory to run C.

  3. Assembler programs are usually faster than C programs.

  4. With assembly language and a low complexity you know exactly what is going on. This is an advantage in certification of safety related applications.

Some links other than man as:

http://www.avr-asm-tutorial.net/

Figure 3.5. Attiny

at tiny


Program the chip

The Avr chips go from 8 pin devices to chips having a couple of hundred pins. The bigger option would be a JTAG interface for programming (and debugging) the chip. But on a low cost chip (having just 8 pins) the additional pins and the JTAG functionality on the chip itself would cost too much. Therefore the Avr chips have different programming modes. Obviously not all chips and programmers support all of them.

programming/debugging mode

description

programmer

high voltage serial

programming

A high voltage applied, tells the chip to go into programming mode. It is the only way to program 8 pin devices that have the reset pin disabled and used for an application io.

Not supported by most programmers

STK500 supports it

ISP

Serial programming mode (6 pin connector)

AVRISP-MKII

JTAG-ICE-MKII

PONYPROG

STK500

JTAG

Can be used to program, debug and for boundary scan in the production. Available just on larger chips (10 pin connector)

JTAG-ICE-mkII

debugwire

Small devices do not support JTAG and ISP does not allow to debug them. On some devices Debug wire exchange ISP with debug wire for debugging. It should be noted that once debug wire is enabled ISP will not work. Fuse bits need to be set to revert it.

Caution

Resetting debugwire can not be done using ISP since ISP is disabled, High voltage programming or a special sequence is required (in Avrstudio4 go to debugging and then disable debugwire in jtag ICE mkII Options, is really hidden). Some people say this is also possible with avrdude.

JTAG-ICE-mkII

The Atmel programmers have a firmware inside, this firmware must match with the version in the AvrStudio, you might have to up (or even downgrade) it.

Avr devices have different memories inside:

flash

It is the program memory this is what you need to program

eeprom

Holds non volatile data, usually it will not be programmed, since the application will write and read here

fuses

This is the tricky part, here you can configure stuff.

Often the fuses have to set manually by instructions of the programmer. Often here is the problem when the chip not behaves as desired. Some samples for fuses and what happens if they are set wrong:

  1. divide clock by 8 => effect baud-rate might be wrong

  2. configure oscillator => chip is dead

  3. use reset pin as io => chip can not be programmed anymore (except high voltage programming modes)

Luckily the elf file format can combine all those settings to a single file and AVR studio can deal with it.

Many different hardware is supported see:

http://www.avrfreaks.net

As avr-objdump -h -S <program>.elf shows, the elf file holds much more additional stuff than a programmer requires. ELF is the standard format under Linux and produced by the GCC, but unfortunately many chip programmers do not understands it. Therefore it has to be converted to Intel hex format (ASCII file), to create Intel hex from elf:

avr-objcopy -j .text -j .data -O ihex<program name>.elf<program name>.hex

The hex file is also ASCII and can be observed by cat <program name>.hex

To bring the program and the static data into the micro controller chip you need a programmer. There are many programmers available, including standalone devices. But more interesting are the ones that use a simple hardware attached to the PC.

Since the Intel hex format is ASCII it can be observed in a text editor:

Every line starts with :

  1. All other characters have to be read as a pair of two characters representing a byte written as hexadecimal value.

  2. The first byte is the number of data bytes contained in the line.

  3. The second and third byte is the start address where those bytes are written

  4. When the fourth byte is zero then it is a regular line contains data. If it is 01 then it marks end of file

  5. Then the data bytes are present

  6. At the end there is a checksum byte

Avrdude

Avrdude is a command line tool to program avr's. For Gentoo Linux make sue you set the ftdi useflag to get usb support and then emerge avrdude. The user should be in the usb and uucp group to have access. Type avrdude -v and see that there is a global configuration file that should not be edited but contains all definitions as programmer names /etc/avrdude.conf and a custom user configuration file ~/.avrduderc can be created.

See: http://savannah.nongnu.org/projects/avrdude

avrdude -c ? lists all programmer hardware supported as jtag2 = Atmel JTAG ICE mkII in jtag mode.

avrdude -p ? lists all microcontroller supported as m324p = ATMEGA324P

Now it has to be known how the avrdude tackles to the programmer. Since all kinds of hardware interfaces are supported the -P parameter sets the port. Details are described in the sections of the programmers. For the following examples -P usb:4945 selects a programmer on the USB with a serial number that ends to 4945. The number can be found by lsusb or usbview and then when knowing the USB bus number and the device number, the verbose option can be set lsusb -v -s 6:5 | grep Serial

avrdude -p m324p -c jtag2 -P usb:4945 -t for the JTAG ICE using JTAG

avrdude -p m324p -c jtag2isp -P usb:4945 -t for the JTAG ICE using ISP

avrdude -p m168p -c avrispmkII -P usb:7866 -t for the AVR ISP mkII

to start the terminal mode where you can

type help to know what you can do:

part

To see what part you have including memory types and size

erase

Chip erase

dump flash 0 32

Dump 32 byte from the flash beginning at address 0

Note

If the above command fails try it as root. It might be that regular users have no access right. Making sure the user belongs to the uucp group and putting in /etc/udev/rules.d/10-local.rules something as

# Atmel JTAG ICE mkII
SUBSYSTEMS=="usb", 
ATTRS{idVendor}=="03eb",
ATTRS{idProduct}=="2103", 
MODE="660", 
GROUP="uucp"

and then udevadm control --reload-rules should fix it. lsusb -v or usbview will print out the values idProduct and idVendor that correspond to Atmel JTAG ICE mkII and Atmel.

The more common options use the command line:

To erase the chip:

avrdude -p m16 -c jtag2 -P usb:4945 -e

To erase and program the flash memory of the chip:

avrdude -p m16 -c jtag2 -P usb:4945 -e -U flash:w:<program>.hex

-P usb:0e:d8

The last 4 digit of the Jtag ICE mk-II serial number to find the device on the usb. See Jtag ICE mk-II section for the details.

-e

Erases chip

-U flash:w:<program name>.hex

Writes the file in the flash memory inside the chip.

There is a GUI for it gnome-avrdude, however it seems to be outdated (devices and programmer missing)

to /etc/portage/package.keywords.

See https://sourceforge.net/projects/gnome-avrdude/. The gui is straight forward. Click the Configure button and do the settings. For the Port type in usb:0e:d8 as previously found.

https://www.mikrocontroller.net/articles/Burn-o-mat

Note

Some smaller devices do not support jtag, but ISP. The JTAG ICE mkII can handle that using jtag2isp device, but the bit clock timing must be increased by factor 10 using -B10 option. So the following command should do it: avrdude -p m168p -c jtag2isp -B10 -P usb:40fb -vv -e -U flash:w:<prgm name>.hex

JTAG ICE mk-II

Two modes are supported the JTAG mode that allows full functionality but occupies 4 pins on the avr device and the debugwire with limited functionality, but uses just a single pin on the avr device.

Figure 3.6. JTAG ICE

avr emulator


It is recommendable to attach it via USB, so no serial connector is occupied and no power supply is required (The target seems to have been powered separately, otherwise an power error occurs). If the emulator is plugged in udev does not know what to do. Therefore no dev file with a meaningful name is produced (except udev rules would be written). Avrdude finds the dev file automatically when the last couple of digits of the serial number of the Jtag ICE mk-II is known. However, how to find the serial number? Type

avrdude -c jtag2 -p m128 -P usb:xx -v

Obviously this can also be easier by using usbview.

Once the number is known, type:

avrdude -c jtag2 -p m16 -P usb:4945 -v

PonyProg

A universal programmer with a GUI supporting many kind of chips (not just avr's) is PonyProg that can be easily installed by: emerge ponyprog. Checkout the home page of PonyProg where you get also the information about the necessary hardware: http://www.lancos.com/prog.html

Since PonyProg is universal, it's universal hardware has a base board connecting to the serial port of the PC and offering a 10 pin header, where the different adapters specific to the particular chips can be plugged in. This 10 pin header is defined by PonyProg and with a high probability incompatible to other 10 pin headers to program individual chips.

After successful installation PonyProg can be started as ponyprog2000

Debugging AVR micro controllers

Although C code can be tested on a regular Linux PC, certain problems occur when it is ported to an other hardware (other peripherals, 8 instead 64 bit address bus, timing). Debuggers are required for that. Debugging micro controllers is possible with the Gnu Debugger avr-gdb that has a front and a back end. The front end interacts with the user and the back end with the micro controller. Front end and back end can communicate via an TCP/IP port and could therefore be on different machines.

Since Avr have Harvard architectures with two memories, one for data and one for instructions and gdb has just one memory to watch, a trick has been implemented, an offset of 800'000 has been added to the data memory addresses and been put to the instruction memory. PortB can not be observed at 0x18 it has to be observed at 0x800018.

Back end avarice for the In-Circuit Emulator

Programming micro controller means accessing hardware directly. Modern avr', have a JTAG interface that allows to access via the PC the internal registers of an actual physical attached micro controller. To control such an attached micro controller an other device like the Atmel JTAG In-Circuit Emulator (ICE) can be used. avarice connects to avr-gdb via a TCP socket and communicates via avr-gdb's "serial debug protocol" and on the other side it communicated via /dev/avrjtag to the ICE.

See: http://avarice.sourceforge.net/ and is man page.

To start avarice must find the emulator (usb:<serial number>) and the TCP/IP port to be used:

avarice --jtag usb:0ed8 --mkII :4242

avarice then waits to be connected. Once connected, a disconnect closes the program. --debug add more info to the console

Some devices not having JTAG but having debug wire can also be debugged setting the debugwire fuse and calling avarice with --debugwire

Back end Avr Simulator

Instead of using a real device with an emulator a simulated device can be used and attached to avr-gdb. The packet for that is simulavr.

Unfortunately there are many issues to build simulavr on a modern Linux distribution. It also looks to be no more well maintained. Alternatives are using binary packages (64bit is missing) or the active fork https://github.com/Traumflug/simulavrthat has been done since the SIMINFO extension got not accepted but http://reprap.org/wiki/Teacup_Firmware simulations requires it.

simulavr is more than just a back end to avr-gdb it is also a standalone simulator that can run an application simulavr -d atmega168 -f <app>.elf Unfortunately the number of supported devices is not so long.

There is also support to simulate the simulated avr's peripherals with scripts and create trace files of signals that can be explored with gtkwave.

For debugging the simulation needs to be run with the -g option simulavr -d atmega168 -g it is common to not pass a file to be simulated, since the avr-gdb debugger can load it.

When done Ctrl+C will stop it

See http://reprap.org/wiki/SimulAVR

Front end

The gnu debugger gdb is available for the avr's under that name avr-gdb ( for gentoo emerge cross-avr/gdb).

Important

Check if you have a ~/.gdbinit in your home directory. If you have one and you do not know why, remove it.

Even it is no more state of the art, but using the command line to check if debugging is possible is a good start before using a nice GUI tool and not understand why it does not work.

The <program>.elf to be debugged must be compiled with -g parameter to get the debug information.

Debug with simulavr

simulavr needs to get the program and avr-gdb needs to have the symbol table. This is best done by starting simulavr -d atmega168 -g in debug mode knowing the microcontroller but not the program.

Then start avr-gdb the elf file can be passed at command line or later by file <program>.elf

target remote localhost:1212 connects avr-gdb to the simulavr simulator

load downloads the program in simulavr, (simulavr might not accept the load command due to fuse data that it can not handle).

Now everything is ready for the avr-gdb debug commands

Debug with avrice

With avarice the microcontroller being debugged needs to have the program therefore programming needs to be done first using avrdude.

After that avrice can be started.

Then start avr-gdb the elf file can be passed at command line or later by file <program>.elf

Note

Do not use the avr-gdb load command since avrdude has already loaded the program into the chip.

target remote localhost:4242 connects avr-gdb to the emulator via avarice

Now everything is ready for the avr-gdb debug commands

Debug the avr program

At (gdb) command prompt type in the following:

b main sets a breakpoint at main

c runs

n single step not entering functions

s single step but entering functions

p <var> prints value of variable <var>

jump main jumps to main

Ctrl+C exits from running

q quits

As GUI there was in the past avr-insight and avarice came even with support for it as or ice-insight that starts avr-insight and avarice. There is also ice-gdb that starts avr-gdb and avarice. Checkout man pages for ice-gdb and ice-insight. Avr-insight seems to be disappeared and the pure insight supports not avr's. Also Code:Blocks and eclipse are solutions with a gui.

Codeblocks

CodeBlocks projects

CodeBlocks creates xml project files with the cbp file extension.

Code::Blocks knows projects having targets. Targets are usually:

Release having the target to program the binary in the chip

Debug to develop and debug the source code

Code::Block allows to make setting on Project level as well as on target levels.

When Code::Blocks gets installed after the avr-gcc then support for avr processors is enabled. A wizard pops up when selecting new avr project and have you made selections as CPU type and frequency. This is nice but then gets complicated to find where the wizard has made the settings. The settings are done on project level not per target level:

CPU frequency is done in Project-> Compiler settings -> #defines

CPU type is done in Project-> Compiler settings -> Other options.

This might be not what is desired when as when a bigger avr device having JTAG is used for the development and a smaller device then for the production. Or the simulator is used that has a limited set of AVR devices but then an other device is used.

Important

It is therefore important to have a concept what is defined per project and what per target.

~/.config/codeblocks holds the user configuration that is not in the projects. Since the project files cbp are xml they can be observed to find out where the settings are.

Codeblocks setup and install

Prior installing Code::Blocks it is recommended to test all required functionality on the command line as:

avr-gcc

avr-dude

avr-gdb

avarice

simulavr

The Tools and the Complier, Debugger settings have to be adjusted and are not part of a Code::Blocks project.

In general Code::Blocks need to known all the path and location of the avr-gcc.

If the tool chain as gcc-avr is not included in the systems gcc (gcc-conf -l does not show it) as when the toolchain from Atmel is used then the settings for the GNU GCC Compiler for AVR needs to be edited. This requires to change:

the "Search directories" for the compiler /usr/include

the linker /usr/lib

the "Toolchain executables" "Compiler's installation directory" /usr

The debugger executable /bin/avr-gdb

Also the package srecord is required to get srec_cat and xterm to have the external tools running in a separate window.

Good links how to use Code::Blocks with avr are

http://www.johnhenryshammer.com/WOW2/pagesHowTo/atmelPage.php#index http://www.avrfreaks.net/sites/default/files/Howto%20Code_Blocks%20and%20AVR1_3.pdf

To get the arduino library the linker setting needs to known the path where core.a is. Additionally the header files must be made available to keep the c compiler happy.

CodeBlocks programming the chip

The preferred way to program the chip is to add the previously tested avrdude command from the command line into Code::Blocks as new tool see also https://www.mikrocontroller.net/articles/Code::Blocks. At the beginning it is the best to have it run in a separate window and requiring to press a key to stop.

Figure 3.7. Codeblocks and AVR dude

avr dude


The command can then be made more flexible by using variables (or macros) as $(PROJECT_NAME). To find out what values they have add to the builds pre or post steps.

        echo PROJECT_NAME $(PROJECT_NAME)
echo TARGET_OUTPUT_DIR $(TARGET_OUTPUT_DIR)

Alternatively it would be possible to add the avrdude command to the post-build steps to have the chip automatically programmed on build.

Codeblocks to debug

To debug a program without emulator and chip requires a simulated chip and therefore simulavr. simulavr needs to be started by Code::Blocks including the program to be loaded and debugged as elf file. After that Code::Blocks needs to start avr-gdb

Alternatively simulavr could be started without elf file. Then avr-gdb could be started with the avr-gdb commands

        target remote localhost:<nnnn> 
load

to have the file loaded.

There are various ways of setting up Code::Blocks for that. simulavr could be set up as tool and avr-gdb can have its commands in the settings as "Additional GDB commands" and "Additional shell commands".

Prior doing it the desired commands and steps should be tested in consoles. It is also a good way to start simulavr in a console and have then Code::Blocks start the debug without automatically start simulavr.

The first setup should have much user interaction, if everything works then it should be modified to be as automatic as possible.

Working on such low level, really helps understanding how debugging with gdb works.

Codeblocks to debug the chip

avr-gdb as front end and avarice as back end is used. avarice and avr-gdb communicate via TCP/IP typically port 4242 with each other.

Figure 3.8. CodeBlocks and avarice

avr rice


As avrdude it is best to add avarice as tool to Code::Blocks. At the beginning it is also here the best to have it running in a separate window.

Important

The chip needs to be programmed first as by using avrdude before it can be debugged. avarice does not do that.

Codeblocks troubleshooting

Observing the logs & others is the first point for troubleshooting since there all commands appear.

Pre and post steps is also a place where commands as

        echo TARGET_OUTPUT_FILE $(TARGET_OUTPUT_FILE)

can be placed to see what values the variables carry.

If the settings do not appear as desired than There might be a mess with the settings since

Important, those location exist more than one time:

For all build targets and for each individual build target. Different rules exist where it is done best. As example when having just one hardware then the top location is best. Having multiple hardware with different CPUs and speed than a per target definition is best. If it is messed up the same but contradictions definition can pop up more than once in the Log & others window. Open the xml project file <project>.cbp in an editor might be a way to find out where the settings have been made.

AVR eclipse plugin

Eclipse does not run well under Gentoo. A better way is therefore using Code::Blocks.

Before the AVR plugin can be installed the CDT the C development Tools need to be installed.

Via eclipse marketplace there is the AVR eclipse plugin.

Eclipse uses perspectives to work. There are two perspectives for the avr development:

The C/C++ perspective where code is developed

The Debug perspective to test it.

Perspectives are basically just different views. They modify the menu bar and the windows.

To work with it create a new C project and then select AVR Cross Target Application

Figure 3.9. AVR Project

eclipse avr project


Under Project>Build Configurations the build configuration Release and Debug can be found. Depending what configuration is active the compilation creates the subdirectories Debug or Release that contain the results of the compilation.

Release contains the hex, elf files and is therefore suitable to do program it into a device using the programmer or program it into the device and debug it with an emulator.

Debug contains just the elf file that can be used for debugging using the AVR microcontroller simulator. The name Debug is misleading, since debugging can also be done using the emulator and a real microcontroller, but for this the not existing hex file would be required.

Note

Debug can not be used for debugging using the emulator. To not create confusion the build configuration Debug should be renamed to something as Simulator.

Existing source and header files can be simply copied to the eclipse workspace project directory directory. File > Refresh (or F5) makes them visible to the project.

Project > Make target is ambiguous and could therefore be misleading. Make in this context is not a verb it is the name of the program make, since Eclipse makes use of and creates automatically makefiles. Targets are targets for the program make. The targets automatically created are all and clean and allowing eclipse to do make all and make cleanTherefore Project > Make target allows to add new targets for the program make.

Eclipse uses the workspace to group all projects together and showing them on the Project window. If too many projects appear, they can be grouped using Working sets. Alternatively different workspaces can be made and File>Switch Workspace selects what is desired.

Tools like doxygen and git work well together with eclipse.

Place a Doxyfile into the top directory that e.g. creates html pages in /html and uses pictures from /pic. Add a .gitignore file to exclude automatically generated files from version control. The .gitignore file might contain the following

# ignore eclipse files
*.cproject
*.project
Release/*
Debug/*
.settings/*
# ignore doxygen files
html/*
pic/*

Programmer and hardware setup

Project>Properties>AVR>TargetHardware must be adapted to the avr controller and its oscillator used.

In Project>Properties>AVR>AVRDude (or standalone AVRdude) two programmer configurations need to be created, one for Release and one for Debug. Alternatively a single configuration for both can be selected. The programmer configuration defines what programmer hardware is used. The same command line options as using avrdude in a console can be set. So t he -P port setting must match, the ID of the programmer on the USB e.g. usb:4945. In the GUI there is a window where the command line is shown, this can be used to confirm the setting.

Some programmers support different methods to program the chips, but the chips are less flexible and support just a few, so select the programmer with the correct programming mode for the target microprocessor. Example: Use ISP and not JTAG if the target microprocessor does not support JTAG.

The factory settings of Avr micro-controllers is hardly the configurations that is desired. So the fuses need to be modified. The fuses most probably to be changed are:

Disable DIV8 fuse to run the same speed as the oscillator

Select something other than the internal RC oscillator

Per default just the Build Configuration > Release (but not Debug) will produce the hex file for the programmer.

Compiling and programming

Compiling and programming the microprocessor is done in the C/C++ perspective and having selected the Release build configuration.

Project>Bulid Configuration > Set Active > Release is probably the first thing to do instead to have the default setting Debug.

Eclipse starts avrdude and its command line is shown, so check its settings and if it still doesn't run try it out without eclipse in the regular Linux console.

This allows a fist compilation without configuring in-circuit debugger or simulator. If successful and more is desired it can be switched back to build configuration Debug where the program can be tested and developed.

Debugging AVR with eclipse

Debugging is more complex, since a couple of extra things need to be configured

Verify that the elf file has some debug info with it Project>Properties>C/C++ Build>Settings>AVR Compiler>Debugging

Figure 3.10. avr debug settings

eclipse debug info


It is strongly advisable that no code optimizations are done (otherwise single step through the code gets confusion), so verify Project>Properties>C/C++ Build>Settings>AVR Compiler>Optimization

A debug back-and a front end for avr-gdb needs to be configured

The back end avarice (or simulavr) needs to be configured as external tool. Run > External Tools > External Tools Configurations and click on Program.

Location is /usr/bin/avarice

For the Working directory click on Variables and set workspace_loc to get ${workspace_loc}

Where to find it on the usb and what TCP/IP port is used needs to be set, so add the arguments:--jtag usb:40fb --mkII :4242

This allows to run avarice.

Now the front end avr-gdb needs to be configured. This is done by creating a debug configuration where C/C++ Remote Application has to be set (since it runs remote on the avr processor and communicates over TCP/IP). Settings as use /usr/bin/avr-gdb and the port number 4242 to find avarice must be set. In the Debug perspective open Run>Debug Configuration. For the C/C++ Application press button Search Project and select the elf file in the Debug subdirectory. The debugger gdb needs to be exchanged with /usr/bin/avr-gdb and the port number of the connection needs to be adapted to find the back end avarice, 4242 is commonly used for that. Delete also the gdb command file, except if you have one for avr-gdb.

When debugging fails, close windows as disassembly, since this give a lot of stress to the data link towards the emulator.

Troubles with the avr plugin

When updating the avr-gcc, the eclipse plugin will still remember old paths and create warnings since they are no more present. To get rid of this warning delete the following file: ${workspace}/.metadata/.plugins/org.eclipse.cdt.make.core/${projectname}.sc

If AVR symbols can no be resolved, try to select other microprocessor, compile and switch back to correct microprocessor. There seems to be sync problems between avr-gcc and eclipse GUI.

AvrStudio and WinAvr

AvrStudio is Atmels a very nice environment to develop programs for their microcontrollers running under Windows.

When AVR microcontrollers became popular AVRstudio had version 4 and I did a lot of work with it. I still use a version under Windows XP having installed in Virtual box. Newer versions see to be to heavy for my PC and Virtual Box.

A draw back is that using an old version of AVRstudio means:

Avrlib 1.6.7

GCC 4.3.3

No support for very new AVR devices

According http://www.avrfreaks.net/ avrstudio4 runs well under Linux using Wine.

Warning

You could run into a badly and confusing CR/LF problem when editing source in Linux and then use it under Windows. The effect is that the debugger jumps around randomly and even stops on commented lines, additionally even the watches for variables seem to not work. To get rid of it the source has to be cleaned line breaks for Windows. It is also recommended to replace tab character with blank characters.

Finally I use it under virtual box where windows XP is installed.

My experience is, the AvrStudio version 4 runs well under Microsoft XP. AvrStudio 4 supports just assembler programming but a very nice package WinAvr can be plugged in to get the gcc compiler (Newer version do not make use of WinAvr anymore so its development stopped in 2010). Using WinAvr under Linux means, having the Linux C Compiler gcc ported to Windows, then using the Windows emulator Wine to have the Windows version of the Linux C compiler running again under Linux. Installation worked but did not start due to a lot of missing dlls and other warnings. I could not manage to find and install those dlls. Win AVR crashed badly my computer? And how to connect to the emulator, since Wine seems not to support USB? The hint that it seemed to require at least wine 0.9.57 did not help either.

Arduino

Downloading an arduino binary unpacking it and running it from its installation directory is the easiest way. The arduino-<xxx>/hardware/tools/avr includes the avr-gcc compiler arduino tries to hide the details about the compilation, linking and programming. This might be nice but for a professional it can be annoying when it is unknown where all the compiled output files go. The first thing to be done is go to File Preferences and click the two boxes at Verbose output during compiling and upload. If arduino is started in a console then all text appears there so it can be more easily captured when deviating it into a file. Interesting things to see is where the hex file and other compilation output goes and what command is used to program it into the micro-controller. All goes into a folder like /tmp/arduino_build_796905 and <name>.ino.hex is that what should be saved for later programming.

File preferences points to the file preferences.txt is the place where additional settings are. Setting

      preproc.save_build_files=false

to true looks promising.

Arduino uno has a USB to serial device built in. Since there are two implementation FTDI chip or second AVR processor the appropriate kernel driver must be installed.

Some arduino verson fail due to a missing library when calling /home/......../arduino-1.8.1/hardware/tools/avr/bin/avrdude to program the chip. This can be fixed by installing avrdude separately as to /usr/bin/avrdude and then going into the /home/<........>/arduino-1.8.1/hardware/tools/avr/bin directory where arduino has its avrdude. Simply replace it with a symlink ln -s /usr/bin/avrdude avrdude.

An other issue is that uploading the code to the avr fails since you as regular user has no access to the serial port used.

In case of having a second AVR, this has the Communication Device Class Abstract Control Model interface implemented therefore select Device Drivers > USB support > USB Modem (CDC ACM) support that results in CONFIG_USB_ACM and its driver is called cdc-acm. When the arduino is plugged in then dmesg should tell that /dev/ttyACM0 got created.

Finally emerge arduino.

Arduino is a open source hard and software platform. It mainly runs on AVR processors and makes therefore use of avr-gcc. However it uses a hardware abstraction layer, so accessing the micro controllers peripherals does not require to read the microcontrollers data sheet and makes also the code to be portable, Additional there is also a boot loader , so programming the chip works via USB connection without the need of any special hardware. To start the ide type arduino

Figure 3.11. Arduino

arduino


The source files have the extension ino.

Since arduino is an ide and a library, it is also possible to use the arduino library under an other ide as eclipse or Code::Blocks.

For eclipse the work is already done since there are arduino eclipse plugins and Code::Blocks has its Codeblocks Arduino IDE http://arduinodev.com/codeblocks/.

For Gentoo Linux there is a guide at http://playground.arduino.cc//Linux/Gentoo. However it installs an old arduino IDE without avr tool chain since the Gentoo way is installing the avr tool chain separately and this is big work with the risk that it will not end up successfully.

Interfacing AVR devices to Linux via USB

Some basic USB device implementations that need to exchange just a couple of bytes, make use of EP0 only. They can use standard micro-controller without USB interface. The USB part is done entirely in SW see: https://www.obdev.at/products/vusb/index.html. Earlier versions where called avrusb and not vusb. The name had to be changed since Atmel the avr manufacturer uses avrusb for their avr chips with hardware USB support. The software package is called usbdrv. Download latest version from https://www.obdev.at/products/vusb/download.html, extract it and change to to examples/usbtool. Type make and you get the executable that can be started as ./usbtool -w list , so you will see everything attached to your PC.

Or even use a more stripped down version http://dicks.home.xs4all.nl/avr/usbtiny/ that fits in 8pin chips. Here the software package is called usbtiny.


Linurs Servernest startpage