Introduction: Debugging AVR Code in Linux With Simavr
I recently started programming AVR chips, namely the ATTiny85. They can be programmed using C, compilers are readily available in Ubuntu, and you can do a LOT with them - just search for avr on this site! Anyway, I was having some trouble with my project today - the LED wouldn't flash! I couldn't figure out what was going on, as debugging these things is non-trivial. That is, until I discovered simavr.
It's a simulator for AVR in Linux that can take your ELF or HEX code and run it as if it's actually on-chip, but gives you hooks and the possibility of dumping trace files. I'll go through a simple example.
Step 1: Git It
There are a few dependencies on Ubuntu (which is what I use all the time):
sudo apt-get install avr-libc libelf-dev \ libglut3-dev gtkwave git build-essentialI had to remove some crappy Mesa symlink for OpenGL in 10.10. Only do this if you have problems compiling related to -lGL,
sudo rm /usr/lib/libGL.so cd /usr/lib sudo ln -s libGL.so.1 libGL.so cdFinally, use git to download the source code:
git clone git://gitorious.org/simavr/simavr.gitNow, build it.
cd simavr makeIf you get any errors, leave me a comment. I'd be happy to help. You should have a new program called run_avr in the simavr subdirectory once that completes.
Step 2: Try a Test
There's tons of tests that come with the software. They're located in the (surprise!) tests subdirectory in the code. You can run one like this:
./run_avr ../tests/atmega88_example.axfYou should see something like this:
AVR_MMCU_TAG_VCD_TRACE 00c6:00 - UDR0 AVR_MMCU_TAG_VCD_TRACE 00c0:20 - UDRE0 Loaded 1760 .text Loaded 114 .data Loaded 4 .eeprom Starting atmega88 - flashend 1fff ramend 04ff e2end 01ff atmega88 init avr_eeprom_ioctl: AVR_IOCTL_EEPROM_SET Loaded 4 at offset 0 Creating VCD trace file 'gtkwave_trace.vcd' Read from eeprom 0xdeadbeef -- should be 0xdeadbeef.. Read from eeprom 0xcafef00d -- should be 0xcafef00d.. simavr: sleeping with interrupts off, quitting gracefullyNotice it made a VCD trace file? Let's see what that looks like in GTKWave!
Step 3:
gtkwave gtkwave_trace.vcdYou can drag and drop the Signals on the left into the Signals list by the Waves dialog to make them show up. You can also right click the Signals and change their properties (like making them display in binary).
Step 4: How It Worked for Me
You specify the chip you want to simulate on the command line, and you can give it the object file created by avr-gcc (ELF format) to make it run. I also specified the frequency here as 8Mhz.
If you'd like to see some sample code, here's the source for the test I did above:
https://github.com/hank/life/blob/master/code/avr/tutorials/ctc_ledblink.c
run_avr -mcu attiny85 -freq 8000000 -t ~/repos/life/code/avr/tutorials/ctc_ledblink.oThis produced this wonderful output:
AVR_MMCU_TAG_VCD_TRACE 0053:00 - TCCR0B AVR_MMCU_TAG_VCD_TRACE 004a:00 - TCCR0A AVR_MMCU_TAG_VCD_TRACE 0038:01 - tick AVR_MMCU_TAG_VCD_TRACE 0038:02 - reset_timer AVR_MMCU_TAG_VCD_TRACE 0038:08 - OC0A Loaded 136 .text Starting attiny85 - flashend 1fff ramend 025f e2end 01ff attiny85 init Creating VCD trace file 'gtkwave_trace.vcd' avr_timer_configure-0 TOP 31250.00Hz = 256 cycles avr_timer_configure-0 TOP 488.28Hz = 16384 cycles avr_timer_configure-0 TOP 488.28Hz = 16384 cycles avr_timer_configure-0 A 2450.98Hz = 3264 cycles avr_timer_configure-0 TOP 31250.00Hz = 256 cycles avr_timer_configure-0 A 156862.75Hz = 51 cycles simavr: sleeping with interrupts off, quitting gracefullyNow that I had the trace file, I looked at it with gtkwave like in step 3. I used my datasheet and compared the registers with what I expected, and I was setting my timer registers backwards! Whoops! Anyway, it would have taken me a much longer amount of time to solve it without simavr - this way it only took a few minutes to get it up and running and find my problem. I highly recommend you try it out!
If you'd like to see some sample code, here's the source for the test I did above:
https://github.com/hank/life/blob/master/code/avr/tutorials/ctc_ledblink.c

Participated in the
3rd Epilog Challenge
15 Comments
2 years ago on Step 4
Did you test simavr in VS Code for Arduino UNO ?
3 years ago on Step 1
sudo apt-get install avr-libc libelf-dev libglut3-dev gtkwave git build-essential
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package libglut3-dev
But this seems to work :
sudo apt-get install freeglut3-dev
I say seems because I have a problem with run_avr
Reply 3 years ago
Here is the problem :
> ./run_avr ../tests/atmega88_example.axf
Loaded 1760 .text at address 0x0
Loaded 114 .data
Loaded 4 .eeprom
Read from eeprom 0xdeadbeef -- should be 0xdeadbeef..
Read from eeprom 0xcafef00d -- should be 0xcafef00d..
And it don't create any .vcd file
5 years ago
Now several graphical applications available for Linux & Windows based on the simavr library, which make the simulation environment setup easy. You can draw entire schematic diagram with AVR processor and external parts connected and simulate it in real time. Look there:
https://sourceforge.net/projects/simulide
and here:
https://sourceforge.net/projects/simutron
5 years ago
Hi - as someone said below it's very hard to find an easy guide to simavr online - for a good simulator that is a shame as few will be able to use it. I am trying to get it to work and have had a little success. Some .axf examples will work but not them all.
My question is around your code which has a header file "basic_functions.h". I am unable to locate this anywhere. Is it one you wrote yourself? It seems to define things like SET_HIGH, SET_LOW, TOGGLE etc. I will re-write the code without them for the moment to try to run the simple blink commands. However, if you could post up a copy of it that would be great.
7 years ago on Introduction
Please update GIT repository, gitorious is no longer maintained. https://github.com/buserror/simavr
8 years ago on Step 4
Great! You shed light to something really dark for me!
Thank you a bunch!
9 years ago on Introduction
Thanks!!! Nice tut!!!
9 years ago
make -C simavr RELEASE=0
make[1]: Betrete Verzeichnis '/home/sebastian/simavr/simavr'
make obj config
make[2]: Betrete Verzeichnis '/home/sebastian/simavr/simavr'
make[2]: Für das Ziel »obj« ist nichts zu tun.
make[2]: Für das Ziel »config« ist nichts zu tun.
make[2]: Verlasse Verzeichnis '/home/sebastian/simavr/simavr'
make libsimavr run_avr
make[2]: Betrete Verzeichnis '/home/sebastian/simavr/simavr'
make[2]: Für das Ziel »libsimavr« ist nichts zu tun.
LD obj-x86_64-linux-gnu/run_avr.elf
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `gelf_getshdr'
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `elf_begin'
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `elf_end'
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `elf_strptr'
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `elf_nextscn'
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `elf_version'
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `elf_getdata'
/home/sebastian/simavr/simavr/../simavr/obj-x86_64-linux-gnu/libsimavr.so: Nicht definierter Verweis auf `gelf_getsym'
collect2: error: ld returned 1 exit status
make[2]: *** [obj-x86_64-linux-gnu/run_avr.elf] Fehler 1
make[2]: Verlasse Verzeichnis '/home/sebastian/simavr/simavr'
make[1]: *** [all] Fehler 2
make[1]: Verlasse Verzeichnis '/home/sebastian/simavr/simavr'
make: *** [build-simavr] Fehler 2
Hey, can you tell me were is my fault?
MfG
10 years ago on Step 2
Hello! I have problems running tests (I am using Fedora 17):
[adam@deathstar simavr]$ ./simavr/run_avr tests/atmega48_disabled_timer.axf
Loaded 152 .text
Loaded 0 .data
avr_make_mcu_by_name: AVR 'atmega48' not known
./simavr/run_avr: AVR 'atmega48' not known
This error happens on each test that I try to run, and on my own .hex files as well.
Do you have any suggestions?
Reply 10 years ago on Step 2
Hmm I'm not sure. Have you done a top-level make to build all the cores? Make sure they're available.
10 years ago on Step 4
Interesting tutorial, especially since it is so hard to find anything else written up about simavr.
I do have a question though. How did you specify what you want to trace? I am assuming that you had to wrap your original .hex/.elf file in some sort of wrapper code that was linked against simavr? Did you have to do something like this?
#include "avr_mcu_section.h"
AVR_MCU(F_CPU, "atmega88");
/*
* This small section tells simavr to generate a VCD trace dump with changes to these
* registers.
* Opening it with gtkwave will show you the data being pumped out into the data register
* UDR0, and the UDRE0 bit being set, then cleared
*/
const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = {
{ AVR_MCU_VCD_SYMBOL("UDR0"), .what = (void*)&UDR0, },
{ AVR_MCU_VCD_SYMBOL("UDRE0"), .mask = (1 << UDRE0), .what = (void*)&UCSR0A, },
};
I am assuming that some sort of wrapper is required, since when I use run_avr on my plain .elf file, I just get:
Loaded 1892 .text
Loaded 6 .data
Starting attiny85 - flashend 1fff ramend 025f e2end 01ff
attiny85 init
and simavr just sits there.
Reply 10 years ago on Step 4
Apparently (I had to look it up), I did do something like that as can be seen here:
https://github.com/hank/life/blob/master/code/avr/tutorials/ctc_ledblink.c
It's commented out in that code, but I apparently had it there specifically for SIMAVR. Cheers!
11 years ago on Introduction
Quite amazing! Thank you. I have just started working with ATtiny85 and this may come in handy.
11 years ago on Introduction
Great instructable. Gave me just the handle I needed to begin wrapping my head around this pretty cool AVR simulator. Super job!
Thanks!