Hardware Debugging the Arduino using Eclipse and the AVR Dragon

There is no music associated with this post.

I’ve written before about using an Atmel AVR Dragon to debug an Arduino board, using AVR Studio 4. I recently had some communication from Stephen Lake where he mentioned he was using Eclipse for Arduino development. I’d looked at Eclipse a long time ago and setting it up was an absolute terror with no real benefit. Stephen said it was much easier now, so I figured I’d have a look. Along the way I found the toolchain is robust enough these days to support DebugWIRE debugging of the Arduino and not have it suck too hard. I spent a lot of time trying to get the setup right, so I figured I’d detail it out if you’re trying to figure it out too, and save you the effort.

I’m standing on the shoulders of giants here. I’ve developed none of the software/plugins involved. I just put the pieces together from some disparate sources, some of which are a little out of date. The real credit goes to the authors of the software used in this. I did the setup on Windows and Linux, and the steps are 90% the same. I haven’t tried any of this out on OSX. This worked for me, maybe it will work for you. Maybe it won’t. I did this with Arduino IDE 1.0 installed.

Here’s what you’re going to need:

  • An Arduino that’s been modified for DebugWIRE operation
  • Eclipse
  • An AVR Dragon. Other debuggers might work, but a Dragon is what I have
  • WinAVR (Windows) or the AVR Toolchain (Linux)
  • libusb for Windows
  • Some patience. Okay, a lot of patience.

Get a DebugWIRE-capable Arduino

I wrote a whole big-ass article on this before, so you can reference that. For this experiment I used my modified Diecimila board. It will probably work with the UNO and other boards, I just haven’t tested them. Your mileage may vary.

Eclipse

More specifically, Eclipse IDE for C/C++ Developers (includes Incubating components). At the time of this writing Eclipse was 3.7.2. The nice thing about Eclipse is that it doesn’t have to be “installed” on your system, you can just unzip the folder and run it from that. That means you can keep many, many different versions of Eclipse configured for different tasks like I do around and not have to worry about trying something that will foul it up in some other aspect. I started out with the base CDT version and added into it. You’ll also need Java for this, of course, since Eclipse requires Java to run. Hey, I hear Eclipse can be used for Java development. groan.

On Ubuntu you can just apt-get it, but I chose to download and unzip it.

Atmel AVR Dragon

The dragon is (still) only $54 from Digikey in Canada. I’m sure you can get one just about everywhere. You can probably make all this work with the Atmel JTAG ICE III (I didn’t even know they had a III out), but those are expensive and so I don’t have one. You don’t have to do any mods to the Dragon other than maybe put some pin headers on it. I put a ZIF socket onto mine, but we won’t use it for this exercise.

AVR Dragon connected to Diecimila via ISP cable

WinAVR (ie – GCC Toolchain)

For Windows you want WinAVR. I used WinAVR 20100110 in this, and there’s nothing newer (and not likely to be anything newer). You might think that 2010 is old and you need something newer and cooler, but trust me working with the 20100110 is a lot easier than trying to build your own toolchain on Windows. When I started with this I had problems and I thought “a newer version might fix it”, and the problems just turned out to be me, and the building new stuff turned out to be a colossal pain.

You’ll also want some version of AVR Studio. In this I used 5.1 but I know it works with AVR Studio 4, since my previous article involved Studio 4. The thing to note is that v4.x and v5.x want different versions of the Dragon firmware, so if you want to go back and forth between 4.x and 5.x you’ll have to keep re-flashing the Dragon too. That’s a pain in the ass.

On Ubuntu you can just use the stock available AVR toolchain stuff,

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

As of this writing, the versions were gcc-avr (1:4.5.3-2), binutiles-avr (2.20.1-2), gdb-avr (7.2-1), avr-libc (1:1.7.1-2), avrdude (5.10-3), avarice (2.10-3ubuntu1). Like WinAVR, there are newer versions available but the stock ones worked (I did build avarice 2.12 to test, didn’t make any difference in what I saw). I also had the stock Ubuntu 11.10’s OpenJDK for Eclipse.

From here on out I’m going to stick to the Windows side of things, but really, if you use Ubunnnntu you’ll figure out how to set the right stuff in Eclipse, you’re smart like that.

libusb for Windows

Here’s where the pain in the ass really comes in. I spent the longest time trying to get this sequence of stuff right, and here’s what worked. This is the primary reason I wrote this article, because it was such an orderal figuring out the right way to make this all work correctly.

If you install one of your AVR Studio (v4 or v5), it will install the AVR Dragon USB driver. That’s great. The Dragon works fine in AVR Studio. Problem: nothing else will. The WinAVR stuff won’t talk through the Jungo driver to the Dragon. Instead, you’ll have to install libusb-win32 to provide an alternate usb access that the WinAVR stuff can work with.

Difficulty: when you install the libusb stuff, the Jungo driver is not active, and so AVR Studio doesn’t work with the Dragon. So if you’re like me and you keep popping back and forth between environments, you have to keep changing the driver. The good part is, it’s easy to do, it’s just busyness. There may be an alternate way to make this work, but I couldn’t find it.

So you need libusb-win32 for this. I used version 1.2.6. There is a version that comes inside the WinAVR directory itself, but I wasn’t successful getting it to work flawlessly. It probably does, but if so I wasn’t doing it right. I was able to do it right with the 1.2.6 version, so that’s what I’ll describe.

With AVR studio installed, and your dragon attached, you can check in the Windows device manager that you have a driver for “Jungo” in play, and the AVR Dragon is associated with it. Unzip the libusb-win32 stuff, and look inside for the “install-inf.exe” program. If you run that, this will make a very nice .INF style installer for your Dragon that uses the libusb driver.

Once you’re done you can push the “Install Now” button to actually install the driver.

From here on out, if you’re going to go back and forth between AVR Studio and the WinAVR-style toolchain you’ll have to learn how to switch between the Jungo driver and the libusb driver. It’s pretty easy. With your Dragon attached, bring up the device manager. Select whatever driver is currently installed, right-click and select “uninstall.” Don’t worry, this doesn’t remove anything, the driver sticks around on your computer. The driver will disappear from the device manager list. Unplug and re-plug in your Dragon via USB and you’ll see the Windows “found new hardware” message. Walk through the Install New Hardware wizard, but don’t let it automatically install anything. Choose “Install from a list or specific location”, and “Don’t search. I will choose the driver to install.” Then you’ll get to pick between the Jungo driver and the libusb driver.

Verify Dragon Operation with Jungo and libusb drivers

AVR Studio

Before you go any futher, you should verify that you can get your Dragon to work in AVR Studio and the WinAVR toolchain. Switch to the Jungo driver, start up AVR Studio, and start up the “AVR Programmer”.

You should be able to connect to your Dragon, and read the fuses on the chip. The nice thing about AVR Studio 5.1 is the programmer will tell you the correct chip if you’ve picked the wrong one. On my Diecimila it’s an ATMega168.

NOTE THE FUSE CONFIGURATION. Messing up the fuses is the easiest and fastest way to making your Arduino experience unhappy. We’re going to be changing some fuses during the course of debugging, so you’ll have to learn how to put all the fuses back correctly when you’re done. If you screw up the fuses, the on-board Arduino bootloader will not work correctly. Also note that the fuses are different for the different Arduino models. The ones I show are for my Diecimila. The ones on the UNO are set differently.

Also, you can use the AVR Studio programmer to burn the bootloader back to the Arduino in the event you mangle things up pretty good. This is useful since the Arduino IDE will let you burn the bootloader with a variety of devices but the Dragon is not one of them. Remember to choose the right bootloader for your chip for pity’s sake.

AVRDUDE and libusb

With your Dragon connected, and connect to your modified-Arduino via the ISP cable, switch over to the libusb driver as described earlier. Open up a command prompt (Start -> Run -> cmd). The main command-line program from WinAVR we’ll use will be AVRDUDE. WinAVR sets that PATH variable, so you can type avrdude commands from any directory.

Easy: Check to see that your dragon even responds. Use dragon_isp with avrdude:

avrdude -p atmega168 -c dragon_isp -Pusb 

You should get something like this:

avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.17s
avrdude: Device signature = 0x1e9406
avrdude: safemode: Fuses OK
avrdude done.  Thank you.

Sometimes you have to hit the command a couple of times before the Dragon will start talking. You’ll hear windows make that little “dunk” sound as the Dragon resets itself, and if you try to avrdude it too quickly it won’t respond correctly. With the libusb driver installed and set to be the current driver you can unplug/replug as much as you want and it’ll always use the libusb driver. It won’t go back to Jungo unless you uninstall the libusb one and switch back manually.

If you get something like this:

avrdude: Version 5.10, compiled on Jan 19 2010 at 10:45:23
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch
         System wide configuration file is "C:\WinAVR-20100110\bin\avrdude.conf"
         Using Port                    : usb
         Using Programmer              : dragon_isp
avrdude: usbdev_open(): did not find any USB device "usb"

That means you have usb issues. Check that the libusb driver is being used. Try replugging your Dragon and see if that helps.

For even more detail, use the -v flag on avrdude:

avrdude -p atmega168 -c dragon_isp -Pusb -v

You’ll get reams of data. Remember, this is for the Diecimila with the ATMega168. If you have an UNO or a Mega or something with the ATMega328 your results will be different.

avrdude: Version 5.10, compiled on Jan 19 2010 at 10:45:23
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2009 Joerg Wunsch
         System wide configuration file is "C:\WinAVR-20100110\bin\avrdude.conf"
         Using Port                    : usb
         Using Programmer              : dragon_isp
avrdude: usbdev_open(): Found AVRDRAGON, serno: 00A200011176
JTAG ICE mkII sign-on message:
Communications protocol version: 1
M_MCU:
  boot-loader FW version:        255
  firmware version:              7.21
  hardware version:              1
S_MCU:
  boot-loader FW version:        255
  firmware version:              7.21
  hardware version:              7
Serial number:                   00:a2:00:01:11:76
Device ID:                       AVRDRAGON
         AVR Part                      : ATMEGA168
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :
                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65     5     4    0 no        512    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     16384  128    128  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
         Programmer Type : DRAGON_ISP
         Description     : Atmel AVR Dragon in ISP mode
         Vtarget         : 5.0 V
         SCK period      : 8.00 us
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.16s
avrdude: Device signature = 0x1e9406
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as 0
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK
avrdude done.  Thank you.

Remember our little talk about fuses earlier? Take note of your fuse values (in my case, FF DF 00), as you’ll need them later to reset stuff. You can choose to have avrdude write them to a file, but it’s also good just to make a note somewhere.

If your Dragon talks to avrdude correctly with the libusb driver, you’re all set. Practice going back and forth between AVR Studio configuration and avrdude configuration for your Dragon.

You can also use avrdude to re-flash the arduino bootloader, in case you mess it up. Just change references to the dragon_isp and -Pusb for the configuration.

For example, for my Diecimila, and the Dragon programmer I use this, which also sets the fuses:

avrdude -p atmega168 -c dragon_isp -Pusb -v -U flash:w:ATmegaBOOT_168_diecimila.hex:i -U hfuse:w:0xDF:m -U lfuse:w:0xFF:m -U efuse:w:0x00:m

For just the bootloader, and no fuses:

avrdude -p atmega168 -c dragon_isp -Pusb -v -U flash:w:ATmegaBOOT_168_diecimila.hex:i 

Where the ATmegaBOOT_168_diecimila.hex is from the arduino bootloader directory in the Arduino IDE tree (in Arduino-1.0’s case that’s arduino-1.0\hardware\arduino\bootloaders), pick the right bootloader for your chip. Remember your fuses are probably different. Which is why it’s good to use AVRDUDE or AVR Studio to find them out and write them down before you mess with anything. The ultimate reference is your arduino boards.txt (arduino-1.0\hardware\arduino\boards.txt). If you’re too lazy to look there, there is this reference as well, but I note that one of my fuses is slightly different in my Diecimila. Look up what all the fuse codes do if you’re concerned.

AVRDUDE will erase all the flash as a feature of doing this, so if you had an arduino program on the chip it will also be gone when you re-flash the bootloader. When the Arduino is “empty” it sits there flashing the LED (pin 13) on the arduino board on and off.

Ladyada also has a tutorial on using AVRDUDE, where they talk about more of the options.

Install Arduino Support for Eclipse

This is the reason that this whole post is even possible. It used to be a huge pain in the ass. No stop, don’t do anything that article says. Instead take the advice at the top of it and go get this plugin instead. The full installation instructions are there on that nice person’s site. Thanks very much for that.

In short: in Eclipse, choose “Install new software”, enter his plugin repository address, and add the latest version of the plugin (1.2.1 as of this writing).



Now at this point you’re all set to do Arduino development in eclipse. You can write code in Eclipse, and upload it in Eclipse (via avrdude). There are some differences between doing development in Eclipse vs. doing it in the Arduino IDE. If you’re new to Eclipse you’ll find it has a shit-tonne of features and things that make you scratch your head. Also, code you develop has to be modified slightly to conform to the Eclipse CDT standards. This is detailed in the baeyens.it instructions. In particular Eclipse will throw out tons of warnings you never knew about for code that works fine in the Arduino IDE, because the Arduino IDE is set to compile with the warnings off. Warnings on is helpful if you’re trying to figure out problems, but if you’re new to the whole coding scene it will probably be pretty daunting to wrap your head around them. Also, the Eclipse ide still requires prototypes for functions, which if you’re written functions in the Arduino IDE you’re probably asking “What are prototypes?” I wouldn’t call using Eclipse for Arduino development a beginner’s task. Learn to do stuff with the Arduino IDE first. Again, the reason I’m writing this is because we want to move on to doing hardware debugging with Eclipse.

Install GDB Hardware Debugging into Eclipse

Most of this is similar to this setup for doing debugging with basic AVR chips, and not specific to the Arduino. I’ll give some specific setup points for integrating this with the Arduino plugin.

Here’s some more magic install stuff. In Eclipse “Install New Software”, and you can select “Work With: all available” sites. You will see a staggering amount of extra stuff you can install into Eclipse, only a fraction of which I even know what it does. What you’re looking for is GDB Hardware Debugging, so you can enter “gdb” into the filter box, and it will narrow the list down.

I didn’t install SimulAVR (the simulator), because I didn’t care about that. I also didn’t set up AVARice as an Eclipse “external tool” because quite frankly figuring out this debugging setup was more difficult that way. I found it much easier just to rely on running the WinAVR tools from an open command-line window.

Most of the settings are project dependent, so you’ll have to set them every time you start debugging a new project in eclipse, so I’ll go through that using some demo code.

A Simple Project in Eclipse

First off, make a new Arduino sketch in Eclipse using the Arduino plugin instructions. (File -> New Project)

Note that this will make two projects in your Eclipse tree. One for your test project, and one which contains the core Arduino code in a separate project meant for your specific Arduino board. In my case, the Diecimila. I called my project “ArduinoDebugTest.”

In the ArduinoDebugTest.cpp file, let’s use this code:

// Do not remove the include below
#include "ArduinoDebugTest.h"
#define LEDPIN 13
//The setup function is called once at startup of the sketch
void setup()
{
// Add your initialization code here
    pinMode(LEDPIN,OUTPUT);
    Serial.begin(9600);
}
// The loop function is called in an endless loop
void loop()
{
//Add your repeated code here
    digitalWrite(LEDPIN,HIGH);
    digitalWrite(LEDPIN,LOW);
    delay(1000);
    digitalWrite(LEDPIN,HIGH);
    Serial.println("I turned the LED on, off, and on again");
}

This code is pretty simple, because all we want is something simple we can use with the Dragon debugger to see that it works. It’ll flash the LED on the arduino board, then print something via the Serial porn on the Arduino.

Build this code with Eclipse (there are many ways to do this, including the little hammer icon on the toolbar, also right-clicking on the project). You’ll see in the console lots of messages go by as it builds the Arduino Core and then builds your program. If everything works out the final message will include the size of your code:

Device: atmega168
Program:    2568 bytes (15.7% Full)
(.text + .data + .bootloader)
Data:        232 bytes (22.7% Full)
(.data + .bss + .noinit)

That should look at least partially familiar, since the Arduino IDE also reports a size when it’s done compiling. Connect your Arduino board via USB to your computer and upload the code with Eclipse (the AVR upload button). Note that the Arduino Plugin very nicely sets up avrdude for you for the upload.

Here’s a fine point to remember: because you’ve modified this Arduino board to work with DebugWIRE, you’ve also lost the ability for avrdude (and the Arduino IDE, which uses avrdude) to auto-initiate the upload. So you have to be quick and push the reset button on the Arduino board when you start the upload. That will trigger the bootloader to look for a new upload for a couple of seconds, then it starts your on-chip arduino program. Timing is important. I find I can push the “AVR Upload” button, then immediately push the reset on the Diecimila and the upload works fine. You can see it works if the TX/RX led’s on the Arduino furiously light up for a few seconds. With the Arduino 1.0 IDE your timing has to be more precise because the IDE always does a build before the upload, so you have to wait until the build part is done – push the reset button – and then catch when the IDE’s upload starts. Also, in Eclipse you’ll see some status messages in the Console saying the upload is working and finishes.

After the upload finishes you should see the Arduino LED start to flash. Then start up the Arduino IDE’s serial monitor (or your favourite terminal program that you know how to get to talk to the Arduino’s usb-serial), and you should see this:

Congratulations, you’ve successfully gotten the code-edit-build-upload workflow working. Now the real fun starts. You can actually stop here and happily continue on your life using Eclipse for Arduino development and never have to bother yourself with hardware debugging.

Build your project with Debugging Info Available

With Eclipse, normally you have build configurations for “Release” and “Debug” versions. When you build for debug the compiler adds in extra symbols and shit which the debugger (GDB) uses to figure out just what the heck is going on in your compiled code, and trace that back to what the source code was.

I had issues making a “Debug” build configuration work with the Arduino plugin, and I think it’s because of the separate project for the Arduino Core that has to be compiled against. Headers would get confused and code wouldn’t build (“pins_arduino.h” kept getting involved, so something was wrong). So in the end I just elected to turn on debugging in the Release configuration and it works fine. The Arduino IDE normally does build things in debug mode (-g), and I think from the output the Arduino Eclipse Plugin is the same, so this may not make any difference – but I set some options to be sure.

In the properties for your project (not preferences for eclipse – these properties are stored for each project), go to the C/C++ Build Settings, and in the Release configuration (the only one which should be there) you want to turn on debugging information.

Normally it looks like this by default:

Change it to “Standard debugging info -g2” and “stabs (avr-gdb / insight)”. Do this for both “AVR Compiler” and “AVR C++ Compiler” to be sure.

(This may not make any difference, as the Arduino Plugin is already setting flags, but this makes me feel better).

After this you should rebuild your program, and upload it to the Arduino over the USB port.

If you have consistency problems with building, trying doing the “make clean” before rebuilding, as that will make it recompile everything. Computers are fast, you can wait the ten extra seconds.

Put Arduino chip into DebugWIRE mode

This is pretty easy, but very important. The Dragon can only debug in debugwire if debugwire is turned on in the AVR chip (duh). Problem is when debugwire is active SPI is not available, so you can’t leave debugwire on all the time. So get used to putting it in and out of debugwire mode.

To set debugwire mode, the easiest way in this workflow is to use avrdude to set the appropriate fuse. You can use the fuse calculator in eclipse, or one of a million online ones. You can also use AVR studio, but if you do this you’ll have to pop back to the Jungo USB driver, then back to the libusb driver to get anything more done.

In my case, the Diecimila’s regular hfuse setting is 0xDF (we saw that earlier with avrdude, remember?). To enable DebugWIRE the hfuse setting has to be changed to 0x9F. Use avrdude to change it:

avrdude -p atmega168 -c dragon_isp -Pusb -v -U hfuse:w:0x9F:m

Results are something like this:

Changing fuses:
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.16s
avrdude: Device signature = 0x1e9406
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as DF
avrdude: safemode: efuse reads as 0
avrdude: reading input file "0x9F"
avrdude: writing hfuse (1 bytes):
Writing | ################################################## | 100% 0.16s
avrdude: 1 bytes of hfuse written
avrdude: verifying hfuse memory against 0x9F:
avrdude: load data hfuse data from input file 0x9F:
avrdude: input file 0x9F contains 1 bytes
avrdude: reading on-chip hfuse data:
Reading | ################################################## | 100% 0.06s
avrdude: verifying ...
avrdude: 1 bytes of hfuse verified
avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as 9F
avrdude: safemode: efuse reads as 0
avrdude: safemode: Fuses OK
avrdude done.  Thank you.

To change it back, reset them to 0xDF:

avrdude -p atmega168 -c dragon_isp -Pusb -v -U hfuse:w:0xDF:m

You may have to do the operation twice, as avrdude might have trouble on the first pass and ask you to redo the command without powercycling. There is a “-c dragon_dw” mode you can use, but I find that avrdude is smart and notices the dragon is in Debugwire mode and switches as needed.

After you change the debugwire fuse state, you have to power-cycle your Arduino. You also might as well power-cycle the Dragon itself, since I have much more “first try worked” success if both get power-cycled.

Once you’ve enabled the debugwire fuse, the Arduino’s on-board bootloader will not work. SPI is disabled and so the bootloader doesn’t function correctly. So make sure you’ve got the correct code uploaded before you enable debugwire. Otherwise you’ll have to disable it, upload, then re-enable it.

Hardware GDB Debugging with the Dragon

If you found the stuff up until now not complicated enough, this probably will satisfy you. What we’ve done up until this point is essentially the same workflow as the Arduino IDE does. What we’re going to have to do now is change the build process slightly in order to accommodate GDB, which is the program behind all the debug session stuff we’re about to do. Then we’re going to find a really big pitfall, but more when we get to that.

Debugging is accomplished through GDB. Eclipse talks to GDB. GDB knows how to talk to AVARICE. AVARICE is the program that knows how to run DebugWIRE on the AVR Dragon. The Dragon is the board that talks via DebugWIRE over the ISP cable to control the execution of code on the Arduino board. Make sense? We have to get all these layers to talk to each other correctly or none of this shit works.

We’ll start on the Eclipse end. Start by making a new “Debug Configuration” in Eclipse (click the arrow next to the little picture of the bug, a couple of squares to the right of the hammer… sigh). A dialog starts up with a bunch of C/C++ options on the left side. Click and add a new configuration on the one called “GDB Hardware Debug”

Then we’re going to march through the tabs on this debug configuration.

First thing is in the “Main” tab to pick your .elf file, which is the compiled code used by the debugger which has all the symbols and shit in it. When I use this with the standard AVR development plugin it auto-inserts the proper .elf file for me, but with the Arduino plugin you have to navigate to your Arduino Eclipse workspace and select the .elf by hand. No big deal.

Set your GDB command to be the avr-gdb.exe in the WinAVR directory. You need to change the preferred launcher to the “Standard GDB Hardware Debugging Launcher” down at the bottom of the dialog window. I couldn’t make this work with the DSF launcher. You can tell you’ve got the right one because it has the option for “protocol version: mi” as shown. I change the port number to 4242, only because the original AVR Debugging article does that.

Then in the “Startup” tab have the setup as shown. Note this is different than the AVR debugging article setup. In particular rather than break on “main” we’re going to break on “setup” since in the Arduino version of the world the “main” is hidden. Turn off reset, halt, and load image (I couldn’t get it to work anyway). Turn on load symbols. I don’t make any changes in the next two tabs (source, common) so you can leave those as is.

Once you’ve got all the settings done, you can click “Apply” and close the dialog. Don’t bother trying to start “Debug” yet, because we need to get AVARICE running.

Running AVARICE is pretty easy. In a command window:

avarice --debugwire --dragon --ignore-intr :4242

If your Dragon is connected properly, you have libusb active as the driver, and your chip is in DebugWIRE mode. you’ll see this:

AVaRICE version 2.9, Jan  7 2010 22:42:57
JTAG config starting.
Found a device: AVRDRAGON
Serial number:  00:a2:00:01:11:76
Reported debugWire device ID: 0x9406
Configured for device ID: 0x9406 atmega168
JTAG config complete.
Preparing the target device for On Chip Debugging.
Waiting for connection on port 4242.

If you get an error, check that you’re using libusb. Also in most cases just cycling the power on both the Dragon and the Arduino puts it back to working. If you give avarice a -v flag for verbose it will constantly spit shit out for you to read and not be interested in as you debug.

Are we there yet? Start the Debug Session

Okay, with your eclipse debug configuration set, debug-enabled code uploaded to the arduino, debugwire enabled, and avarice up and running and waiting for a connection, it’s time to start up the debugger. Click the little bug and select your debug configuration. It will want to change “perspective” on eclipse to show the debug windows, go ahead. It’ll also rebuild your code, but don’t worry about that, since it should be the same version that’s on your arduino already (right?).

if you look at your command window, you should see AVARICE has hooked up with GDB:

Connection opened by host 127.0.0.1, port 4951.

and ta-dah, that’s really it. Because you set the breakpoint for “setup” the code initialized and stopped at the beginning of your setup() routine. Now you can use the single-step commands in the toolbar to march through your code. When you end your debugging session AVARICE will quit, so you need to restart that before you restart debugging. The chip will remain in debugwire mode so you’re all set.

So now, you’re debugging, is it what you expected? Arduino’s success as a platform comes from the fact that the hardware is cheap, the IDE is easy to use, and the Arduino Core is a shitload huge library of awesome functions that make coding for it easy. If you use the “step into” command you’re going to be buried under the mountain of code that goes together to make your own Arduino code run, which will get pretty tedious, and you normally don’t have to debug yourself anyway. Also, timing based things (delay(), sending serial stuff) is going to get seriously broken if you try single stepping through it. Your friend in these cases is the “step over” command in the toolbar, which essentially says “run this whole command, including any subroutines, and come back after you’re done since I don’t want to see any of that single-stepped”.

As the exercise, you can single-step (step into/step over) until you get into your loop() routine, and then you can use step-over each of the digitalWrite() commands, and you should see the light on the Arduino change accordingly. When you hit the delay() and the Serial.print() you’ll want to use step-over unless you’re not bored enough single stepping.

You can set breakpoints and use the “resume” toolbar icon to say “just run until this line gets hit, then I’ll start stepping”, which can be useful if you have a lot of code that runs before your routines you want to debug are executed.

You’ll find your code keeps jumping out to this previously-hidden main() routine, which is how C/C++ actually works, so you just have to step through that back into your loop() code each time.

Also debugwire disables SPI, so if you were hoping to use this to check SPI hardware, I’m afraid you’re out of luck. Back to Serial.print(), or using something like a logic analyser (I have the Salae one).

To get back out of debugging, there’s a red button on the toolbar called “terminate”.

Note that when single-stepping it can take a seemingly long time between steps, because GDB/AVARICE/Dragon is doing a lot of talking amongst themselves getting status from your chip. I believe every time the single-stepper stops the Dragon dumps the entire contents of the Arduino’s ram for display by GDB/Eclipse. You do get lots of fun light flashing on the Dragon during all this, though.

Optimization Can Be a Bitch

The sample program above didn’t have any variables, on purpose. When you’re debugging in Eclipse one of the windows shows the variables in your program, which is – in my opinion – the best part of debugging. It lets you spy into the variables and see if variable “a” is really holding what you think it’s holding. I didn’t use any variables for illustration above because it wouldn’t have worked right, here’s why, and here’s how you work around that.

The Arduino is an embedded platform with limited ram and storage (flash). The Arduino people (correctly) turned on size optimization in the Arduino’s compiler. Optimization is big topic in compiler design, and it essentially boils down to “the user wrote this code to do this task, and as the compiler I will re-write it to make it work faster/better/smaller”

The problem with debugging optimized code is that… well, it’s different code than what you wrote. In particular, the size optimizer (-Os) on GCC will do some amazing stuff like “you set this variable, and never used it, so I removed all references to it from the actual compiled code.” There’s also the general case of “oh, you didn’t have a lot of variables, so instead of keeping them in ram I kept them in registers instead for easier access.” Variables held in registers tend not to show up in the “variable” window so you can’t spy on them, you have to go look at the registers directly.

Let’s do a little experiment to show this. Make a new Eclipse Arduino Sketch called ArduinoOptimizerTest and use this code in your .cpp file:

// Do not remove the include below
#include "ArduinoOptimizerTest.h"
//The setup function is called once at startup of the sketch
void setup()
{
    Serial.begin(9600);
}
// The loop function is called in an endless loop
void loop()
{
    int a;
    int b;
    a=25;
    b=a+a;
    Serial.print("a is ");
    Serial.println(a);
    Serial.print("b is ");
    Serial.println(b);
    delay(1000);
}

Now this is a damned boring program. It stores a number in a variable, does some math, and prints it out. Yawn. You don’t need an Arduino for this, but we will do this to show just how much the Optimizer works to make you a better person. To show we’re not cheating, build this with the debugger info set, load it onto your arduino, and check it with the serial monitor to see that it does give output. (“a is 25” “b is 50” over and over).

Easy, it worked, right? This is a stupid experiment, right? So now go into debugging mode with the Dragon. Put the chip into debugwire mode, do a debug config, and start debugging in Eclipse and have a look at what’s going on.

Oh shit, check it out. See when you ran your program and single stepped it… it never ran the a=25 / b=a+a lines, for some reason the single step went right over them to the Serial.print() line. Why did it do that? Well, check the disassembly window on the right hand side. The Disassembly is the “these are the actual machine code instructions GCC compiled your code into and are running on the Arduino.” It’s a lot of strange looking little single-purpose instructions but you can see how your code has been translated into the machine code.

See how it says “loop:”, a couple of push r16/push r17 and then the instruction pointer for “Serial.print” is that “ldi” instruction? The GCC -Os optimizer said “you know what, you set those a and b variables, but never actually use them other than to do that print, so we just skipped all that and moved it all into the print call itself. The code was simple enough that the optimizer optimized it all away. The results are the same, but the execution is different than you expected.

Note that this is not actually a problem, this is a good thing. It means the compiler is looking out for you and trying it’s damnedest to make your code fit in the limited Arduino space and still do everything you want. It does mean that if you’re stepping through the code you may get surprised.

As an aside, many many many years ago when I was writing unix code on Sun systems you could not debug optimized code at all with the debugger. You had to debug with the un-optimized code only. So if you had a bug that showed up when optimized, but not when un-optimized, you were really shit-outta-luck. It was the best thing evar(tm) when GCC started doing enough work to let you debug stuff that had been mangled by the optimizer.

So okay, as an academic exercise now, what if you want the “pure” code you wrote to debug, and not the optimized version? Easy. We go back into the project properties and turn off the optimizer (-O0 instead of -Os for both the AVR Compiler and AVR C++ Compiler).

Then you have to rebuild – right click your project and do “make clean” first, to make sure all the code gets rebuilt without optimzations. When your build finishes you’ll see that sure enough, your code is larger than when it was built with -Os. You could get a problem where the code could be too big to fit in your Arduino, but in this test case it’s still okay. Upload the code to your Arduino (remember you’ll have to take it out of debugwire mode to do that, then re-enable debugwire again), start up AVARICE, start up the debugger, and here’s what you’ll see:

See that the instruction pointer will actually be able to land on the “a=25” line, and the disassembly shows that there’s actual code assigned to it now. You can also see the disassembly directly for each of the instructions that follow (a shit load of instructions to do something that seems simple, isn’t it? This is why the optimizer works so hard for you).

In the two screenshots you can also see that “a” and “b” were set to some random values before being initialized, which is the reason you initialize variables.

Remember to re-build your projects with optimization on (-Os) again if you’re going to continue.

If you’re doing all this on Linux, you don’t have to worry about the libusb steps, since avrdude/avarice work on linux just fine with the default ubuntu install. Also there’s no AVR studio for linux, so hey, no having to deal with that end at all. Just remember how to set your chips back to factory with avrdude if you mess things up.

Condensed Version

  • Write Code in Eclipse, build without errors
  • Upload to Arduino over usb-serial in Eclipse
  • Enable DebugWIRE on Arduino with AVRDUDE
  • Start AVARICE
  • Configure and start up debugging in Eclipse
  • Debug until your eyes cross
  • Disable DebugWIRE when done

Summing Up

So this works for me, maybe it will work for you. Is it easier than debugging using my previous method with AVR Studio? I guess that depends on how much you like Eclipse.

Is this any better than debugging using AVR Studio? Not sure on that one yet, I’m still investigating doing the debug with AVR Studio 5.1. Certainly less toolchain setup in that case. Using Eclipse in the mix does give you better diagnostics on code errors than using the Arduino IDE, at the cost of more complexity.

Is any of this easier than just using Serial.print() statements? Hell no. But if you really can’t figure out why something’s not right, this might be the best way.

Finally, here’s another Arduino picture, as required by law.

Really, that's all folks.

The Arduino Duemilanove with ATMega328 and that Reset Line

This one is a small followup to my earlier discussion of how to pop of the capacitor of an Arduino Diecimilia so you can both disable the auto-reset and use debugWIRE.

At the time I did that post I had Duemilanove’s in my posession but I was doing the project with the Diecimila, so I didn’t really go into that board. The Duemilanove has the advantage of not having to change a jumper for the DC power/USB power, as it auto-switches.

In the documentation page for the Duemilanove. they discuss the auto-reset line (not in the context of debugWIRE, but it’s the same thing):

The Duemilanove contains a trace that can be cut to disable the auto-reset. The pads on either side of the trace can be soldered together to re-enable it. It’s labeled “RESET-EN”.

I never made the mod to any of my Duemilanoves as I never needed it, but certainly nicer than the “pop off the capacitor” method, since it’s reversible with just a soldering iron and doesn’t require you to re-solder the chip capacitor. I’ve also wondered if you could solder a jumper onto the pads and so be able to enable/disable the auto-reset/debug at will.

But never mind that. A couple of days ago I got a new batch of Duemilanoves for projects. These ones I ordered were the ones that advertised that they were the ATMega328 version (as opposed to the ATMega168 on the Diecilimia and original Duemilanove). Here’s a look at the top and bottom.


Top View


Underside

The board is marked with the appropriate logos and such, and I bought it from a reputable place, so I think it’s an authentic Duemilanove, as opposed to a workalike from the same design (there are lots of Arduino clones, since it’s open design, and there’s nothing wrong with them).

So I was working with this one today, and I thought, “huh, this looks different”. I lined it up against one of my existing Duemilanoves.

Old Duemilanove on Top, ATMega328 Version on bottom

I didn’t see it at first, either. Here, let me point it out.

RESET-EN pads are missing from ATMega328 Version

Yep, the newer ATMega328 version of the board (which shouldn’t be any different other than the chip plugged in the socket) is missing those “RESET-EN” pads. That’s disappointing.

Here’s a couple of views under my microscope, since I like using my microscope.

Original Duemilanove with pads

Pads missing from the ATMega328 version

The hardware reference page doesn’t mention this change.

What does this mean? Well, nothing really. Board still works fine, and you get the ATMega328 for more space. It just means that if you want to do the auto-reset/debugWIRE changes, you’re back to doing them by my “Pop off the capacitor” method. Have fun.

Modify an Arduino for DebugWIRE

This article talks about the Diecimila, but there is a newer article that talks about the Duemilanove

Here’s a departure. Today I’m going to give a little instruction in how to modify an Arduino board so you can actually do something useful with it – like debug it.

No warranty is expressed or implied in this. If you do this and you wreck your Arduino, your AVR Dragon, your wife leaves you and the dog eats your shoes don’t complain to me. Blah blah blah.

The Arduino (http://www.arduino.cc) is a very nice idea. Little boards based on the Atmel 8-bit line of microcontrollers. Nice and cheap basic little boards that have a USB connection, and an onboard bootloader so you don’t need another piece of hardware to program it. You program in a language they say is based on Processing, but to the user just looks like C++ with a lot of busy-work done in libraries for you. If you’re new to microcontrollers but want to do stuff, the Arduino is a good choice for a start. There’s also a significant community built up around the Arduino now, so you have lots of other people to compare with for help and ideas.

What’s nice about the Arduino is the hardware isn’t particularly bound to the pseudo-Processing-C++ language. If the day comes you become frustrated with the limitations on Arduino code and want to go on and be a full on Atmel Assembler/GCC nerd, you can. You can also ditch the onboard bootloader for more space, if you feel like it.

Speaking from my background, I do some embedded system stuff, and the frustrating part of the Arduino is the lack of an “ICE” (In-Circuit-Emulation)/”OCD” (On-Chip-Debugging) workflow. Sure, you can pepper your code with Serial.println() statements, but that only gets you so far if you’re staring at the board and asking “Just why aren’t you doing what I want?”

With previous Atmel microcontrollers I’ve worked with they have an interface called JTAG. A few years ago I went out and bought a JTAGICE clone so I could debug my stuff. JTAG is great.

Problem: The chip on the Arduino Diecimila/Duemilanove (ATMega168 or ATMega328), doesn’t have JTAG. Whoops.

The chips used in the Arduino use Atmel’s fancy new proprietary method called “DebugWIRE.” JTAG uses a ten-pin connector and uses I/O lines that your circuit might want during debugging. DebugWIRE allegedly uses just one – the reset line. I say “allegedly” since you seem to have to be hooked up via the ISP (in-circuit-programming) six-pin connector to make it work, but at least it doesn’t take out one of your I/O banks.

The barrier to DebugWIRE for me for a long time was the cost. Normally you had to buy the JTAGICEMKII. which is damned expensive (CDN$352 at Digikey. I seem to recall a couple of years ago that thing was $600. There aren’t any clones that I know of for the JTACICEMKII since DebugWIRE is proprietary. I think my JTAGICE clone was only $70 in 2005.

Enter… the Dragon.

The AVR Dragon is a nice little programmer that

  • Has USB (no fussing with 9-pin serial ports)
  • Does DebugWIRE, ISP, and JTAG
  • Is Cheap ($57.74 at Digikey. Not super-cheap, but not $352).

In the picture of my Dragon, I’ve added a 40-pin ZIF socket and some more pin headers. The default Dragon does have ISP and JTAG headers mounted, so it’ll work for this stuff right out of the box.

In my first experiment with the Dragon I was unhappy to find it did not work with the Arduino board. Hook it up, kinda get a response, but generally nothing worked right. Did some reading, did some looking at schematics, and here’s the problem:

This is for an Arduino Diecimilia board, the Duemilanove might be a little different, check first.

One of the nice things the Arduino does for the casual user is eliminate the need for fussing with bootloaders and external programming hardware. One trick it uses is to trigger the RESET line via the USB controller chip – this way when you go to “Upload” your program from the Arduino IDE it issues a board reset (thus activating the bootloader) and slurps up your code over USB. The problem: it does this by tying one of the USB FTDI chip serial control lines to the ATMega168 RESET line via a 100 nF capacitor.

Remember, DebugWIRE uses the RESET pin to do all the chip control and debugging. The protocol is proprietary, but let’s be realistic – there’s no easy way to do On-Chip-Debugging via one stupid pin and not have to signal the hell out of that pin – who knows in what weird ways. With this 100 nF dude in place, DebugWIRE gets all confused and… you get disappointing results.

So I figured, I spent my $57.74, and I have some time, I’d see if this assertion was correct. I tracked down in the schematic (shown above) and from the Diecimila page what component would have to be removed. I couldn’t trace very well on the nice little board itself, so I dug out the schematic in Eagle and made sure of the location of the capacitor to be removed in the board layout. (Aside: Eagle is nice, free to use for small things, cheap for non-profit hobby folks).

As lots of people will tell you, hand-soldering with surface-mount components is a pain. Luckily you don’t have to solder anything onto the board, you just have to remove the one there. I did it my favourite way, which is looking down a stereo dissecting microscope – which you can buy off eBay for a hundred bucks. If you’re going to solder small things and you’re half-blind like I am, a microscope is worth it.

So, a quick trip under the microscope. I took out the Atmel microcontroller from the board (it’s in a socket, hey hey smart people) to make sure I didn’t destroy it by accident. Heat up the pad with the iron, use a little soder-wick, use a little pressure and the capacitor pops off. You could use a vacuum desoldering gun, one of those spring-loaded jobs, or you could probably just cut the capacitor in half with an x-acto knife if you’re so inclined, I suppose.

That was pretty easy, wasn’t it? If you were super-ambitious you could wire in a jumper so you could engage the capacitor when you weren’t needing to use the debugger. I wasn’t that ambitious. Here’s why you might want to consider this:

You’ll recall from earlier I said that Arduino’s IDE used this capacitor to auto-reset the board via USB when you went to do a code upload. Well, thanks to this surgery that capability’s been removed. What that entails is that when you want to program the Arduino now, you have to manually hit the big reset button on the board a couple of seconds before the Arduino IDE attempts to download it. Arduino’s IDE does a compile before an upload, so in my case I just wait for the message about a successful compilation to appear and hit the reset. Chip goes into bootloader mode, IDE triggers a new upload, everything’s great.

So let’s consider getting setup for a DebugWIRE session on the Diecimila. We’ll use this boring demo code from the Blink demo that everyone can understand:

This is a graphic because WordPress\’ code tag doesn\’t work right.

I used arduino-0017 for this. I’ve heard with 0018 that it changes handling for locations of compiled code, so take that into account. Compile the code with the Arduino IDE and upload it to the board, and watch the hardware perform as it should.

Now, hookup the Dragon via the ISP connector

Hardware for debugging is only half the magic. The other magic is AVR Studio 4, which is Atmel’s own free development environment for programming Atmel stuff. Couple this with the free GCC compiler WinAVR. AVR Studio does Assembler, and if you have WinAVR installed will also let you jack in and program with GCC (C normally, C++ if you’re a risky fellow). You’ll need WinAVR for this experiment, for reasons that will become obvious.

This is important, because microcontrollers like the ATMega168 don’t ‘speak’ C, they speak assembler opcodes. When you program it you’re downloading a bunch of assembler hex bytecode that actually makes the chip operate. AVR Studio lets you jump one step back and use your GCC source code to step through program operation on the chip.

Here’s why this works: although Arduino’s language is called a variant of “Processing”, under the hood it’s really just GCC C/C++ with a lot of nice libraries for handling the hardware easily. When the Arduino IDE compiles, it invokes the GCC compiler and produces a hexcode file to upload to the Arduino.

So this means – you compile your code in Arduino’s IDE, then you load the compiled project into AVR Studio. In AVR Studio 4 you open an existing file, navigate into the subdirectory called “applet” under where the “Blink.pde” source was saved, and open the file that ends in “.elf” ELF is a format that AVR can use to “connect the dots” between the .hex you loaded onto the Arduino, and the Arduino (secretly C/C++) source code you actually wrote. AVR Studio will want to save your project as a new project, which you should.

Note you don’t have to recompile anything with AVR Studio, just open up the .elf in it, and AVR Studio will take over.

Then it’s just a matter of hooking up the Dragon and configuring it in AVR Studio. Configure your project to use the AVR Dragon (not the Simulator) and set the installed chip type correctly (ATMega168 in this case). “Select Platform and Device”. .

Tell it you’re using ISP to start. With the right chip selected, pick “Read Signature”. This makes the Dragon talk to the chip, and find out who it is. If you have trouble with your hardware setup this is where you’ll find it first. Make sure it reads the correct signature before you go any further.

You can check the fuses of the chip (more on this later):
Fuses are ATMega settings that are stored on the chip, like which interfaces are active, and the chip’s reset condition. If this is your first time looking at this board, take note of all the fuse settings in case you goober them up and have to reset them to the Arduino’s default settings.

Then it’s just a matter of starting a debug session (“Start Debugging”). If your chip isn’t in funky DebugWIRE mode AVR Studio will prompt you to change it. Here’s where things start to get dangerous. Once you enable DebugWIRE, you can’t use the ISP interface anymore (the SPI interface is disabled). This means if you goof something up in DebugWIRE mode you can’t use the ISP or the Arduino Bootloader to reprogram the chip.

This isn’t what some call “bricking” the chip. It’s still perfectly fine, you just have to get it out of DebugWIRE mode first. The problem is there’s only one spot to actually do that, so you tend to forget to do it. That’s in the Dragon programmer options. Once you disable DebugWIRE everything goes back to normal.

If you’re like me, and you accidentally did goober your chip up, you can pull the chip and put it into another programmer (like your Dragon, if you’ve outfitted it with the sockets, or an STK500 in my case) and use the high-voltage programming mode. HVPP mode doesn’t care about SPI being enabled or not, and is how I saved myself every time I did a “whoops, screwed that up, time for a reset” while figuring all this out. This is where those fuses are important. If you use HVPP and muck up the fuses for bootloader and boot reset configuration, the Arduino’s Bootloader will mysteriously work exactly once and never again, making you reflash the bootloader code. I know, I did that. The bootloader code is in the Arduino software directory, with a .hex for your particular board. You can reflash it to the chip with AVR Studio.

Protip: To get the chip out of DebugWIRE mode, you just have to start a debug session with the Dragon in place. You don’t have to have the actual code that’s on the Arduino at the moment. Just load up something (like the blink.cpp.elf project), go into the Dragon options and just disable DebugWIRE. Presto, good as new. Someday Atmel may fix this deficiency in AVR Studio, but this works for now.

So… hardware hooked up? DebugWIRE enabled? Well hell, start debugging. AVR Studio will find all your source code files and give you all the magic you need to single-step and breakpoint operate your Arduino. You’ll find your code has some extras in it you didn’t write, since that’s the nature of the preprocessor that Processing uses to get the code to compile by GCC, but that’s a story for another time.

That’s a lot of words to say “remove a capacitor and it works.”