Some might say 8 bit AVR microcontrollers are outdated since 32bit microcontrollers are available in the same price range. 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 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.
A strategy 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) https://www.microchip.com/mplab/avr-support/avr-and-arm-toolchains-c-compilers. There are 32bit or 64bit versions available. 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. As a consequence gcc-config -l will not show it. 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
should be added to the path PATH="<installed directory>
/bin<installed directory>
/bin:${PATH}"some IDE's as Code::Blocks find the compiler in the <installed directory>
when having told where it is.
To have the avr gcc cross compiler appearing under gcc-config -l it has to be built. The built might end up having lots of bugs or a compiler that does not compile well. In most cases it is therefore not recommended to go this path and use a tested compiler instead.
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
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.
Having avr-gcc up and running is one thing. Having it produce runnable code is unfortunately something else.
Example projects can be found in
/usr/share/doc/avr-libc-1.4.6/examples
Include files are in /usr/avr/include
see also https://wiki.hacdc.org/index.php/Installing_AVR_Toolchain
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.
Check your hardware if outputs on Port B can be activated.
Here the sample program:
Example 3.1. 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.
Since the changes occur fast an oscilloscope is required to observe the result.
Additional to the above sample program there are other same programs available.
As for
gcc, but with the prefix: avr-gcc -mmcu=<device>
setoutput.c this does both compiling and linking and produces the a.out
file. http://www.nongnu.org/avr-libc/user-manual/index.html shows the supported devices as atmega8, atmega324p
Some small avr micro controller are restricted to assembly programming only.
Manually two commands have to be executed.
To compile:
avr-gcc -g -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 would optimize for size but then it might become impossible to use the debug information
-o define other output file name than the default name a.out
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.
The output file <program name>
.elf can not be observed directly since it is binary.
To see just the header to know how much memory is occupied objdump -h <program>
.elf
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
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
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.
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>
.
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 the program memory space is tricky.
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. CautionResetting 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 needs to be programmed |
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 the chip can be configured. |
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:
divide clock by 8 => effect baud-rate might be wrong
configure oscillator => chip is dead
use reset pin as io => chip can not be programmed anymore (except high voltage programming modes)
Many different hardware is supported see:
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
To bring the program and the static data into the micro controller chip a programmer is required.
Since the Intel hex format is ASCII it can by cat <program name>
.hex or in a text editor:
Every line starts with :
All other characters have to be read as a pair of two characters representing a byte written as hexadecimal value.
The first byte is the number of data bytes contained in the line.
The second and third byte is the start address where those bytes are written
When the fourth byte is zero then it is a regular line contains data. If it is 01 then it marks end of file
Then the data bytes are present
At the end there is a checksum byte
Avrdude is a command line tool to program avr's.
The user should be in the usb and uucp group to have access.
For Gentoo Linux make sure you set the ftdi useflag to get usb support and then emerge avrdude.
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.
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 unfortunately this is not the same as avr-gcc uses.
Now it has to be known how the avrdude connects 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
To start the terminal mode:
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
Type help to know what can be done.
part |
To see what part you have including memory types and size |
erase |
Chip erase |
quit |
quits from terminal mode (and shows the fuse settings on exit) |
dump flash 0 32 |
Dump 32 byte from the flash beginning at address 0 |
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 and usb group.
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. |
Setting the fuses to have an external oscillator;
avrdude -p m324p -c jtag2 -P usb:4945 -U efuse:w:0xff:m
avrdude -p m324p -c jtag2 -P usb:4945 -U hfuse:w:0x19:m
avrdude -p m324p -c jtag2 -P usb:4945 -U lfuse:w:0xe0:m
Or reading the fuses:
avrdude -p m324p -c jtag2 -P usb:4945 -U lfuse:r:-:h
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
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
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.
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
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
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 can show such issues. 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 way out is adding an offset of 800'000 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.
Programming micro controller means accessing hardware directly. Larger 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:4945 --mkII :4242
avarice then waits with the stopped microcontroller to be connected. Once connected, disconnecting 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
As man avarice tells, the --program programming the chip is a deprecated option. However avarice can write the fuses: avarice --jtag usb:4945 --mkII --write-fuses <eehhll>
:4242
avarice might be difficult to compile and install. Steps are:
Get the source from the trunk in sf (latest not released)
start Bootstrap to get configure
./configure
make
make DESTDIR=<temp dir>
install to install it into a temporary dir and not the root
avarice -h will then run
To build avarice make sure subversion is installed then svn checkout https://svn.code.sf.net/p/avarice/code/trunk avarice-code
Go to its directory and do
./Bootstrap
./configure
make
make DESTDIR=<where it has to be installed>
install
A fork is also on github https://github.com/multiplemonomials/AVaRICE
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 were issues to build and maintained simulavr. A fork https://github.com/Traumflug/simulavr supporting the SIMINFO extension got prepared for the http://reprap.org/wiki/Teacup_Firmware simulations.
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
The gnu debugger gdb is available for the avr's under that name avr-gdb ( for gentoo emerge cross-avr/gdb).
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.
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
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
Do not use the avr-gdb load command since avrdude has already loaded the program into the chip.
Now everything is ready for the avr-gdb debug commands
At (gdb)
command prompt type in the following:
target remote localhost:4242 connects avr-gdb to the emulator via avarice The avarice window will show that it is connected.
b main sets a breakpoint at main
c runs until breakpoint
n single step not entering functions
s single step but entering functions
p <var>
prints value of variable <var>
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.
There are reasons why to deal with assembly language:
The gcc calls avr-as the assembler therefore a basic understanding of assembler is useful.
There are also micro controllers that are simply too small and too little memory to run C.
Assembler programs are usually faster than C programs.
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/
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 command line options of those tools need to be remembered and copied to Code::Blocks.
If the tool chain as gcc-avr is not included in the systems gcc (gcc-conf -l does not show it) Code::Blocks needs to known the location of the avr-gcc => Settings => Compiler (choose GCC Compiler for AVR) => Toolchain executables (not search directories).
The package srecord is required to get srec_cat
Occasionally as when running external tools (as avr-dude) in a separate window xterm is used as the default and needs therefore be installed. Alternatives as konsole can be selected in Settings => Environment.
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.
Since Code::Blocks supports AVR microcontrollers create a "New AVR Project".
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 Global level => Settings as well as on project levels => Project => Build Options. There are separate Build Options for the targets as Release and Debug.
When Code::Blocks gets installed with avr-gcc found by gcc-config -l then 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 default settings 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.
It is therefore important to have a concept what is defined per project and what globally.
~/.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.
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 (requires the default xterm or an alternative to be installed).
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.
To debug a program without emulator and chip requires a simulated chip and therefore simulavr. simulavr just supports a small number of chips. 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.
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.
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.
The chip needs to be programmed first as by using avrdude before it can be debugged. avarice does not do that.
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
in an editor might be a way to find out where the settings have been made.<project>
.cbp
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
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.
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/*
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 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 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
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.
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 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.
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 is a open source hard and software platform https://www.arduino.cc/. 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
The source files have the extension ino.
Downloading an arduino binary unpacking it and running it from its installation directory is the easiest way. When extracted there are setup scripts ./install.sh creates a desktop icon, arduino-linux-setup.sh
fiddles around with udev rules and user group assignments and requires root permissions via sudo. Instead trusting it, an administrator might prefer to do it manually.
The arduino-
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. <xxx>
/hardware/tools/avr
The first thing to be done is go to File Preferences and click the two boxes at
Show verbose output during compiling and upload
If ./arduino is started in a console then all text appears there, so it can be better observed what is going on and what problems occur. 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
is that what should be saved for later (mass) programming.<name>
.ino.hex
File preferences points to the file preferences.txt
is the place where additional settings are. Set
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 version 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/
directory where arduino has its avrdude. Simply replace it with a symlink ln -s /usr/bin/avrdude avrdude. <........>
/arduino-1.8.1/hardware/tools/avr/bin
An other issue is that uploading the code to the avr fails since a 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.
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. However emerge arduino 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.
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.