1. Purpose of this application

This application can connect to a target hardware (which contains some kind of programmable controller) in several ways and helps you debugging the software running on this controller.

It is possible to read and write bytes, words and ranges of bytes. You can do this interactively or using scripts to automate certain tasks.

To achieve this, the embedded controller needs to talk a certain protocol. Currently three protocols are implemented:

  • A simple protocol using the synchronous three wire SPI (MOSI, MISO, CLK).

  • A simple protocol using an asynchronous serial line (TXD, RXD).

  • A block oriented protocol (which is faster than the previous one when used with usb-to-serial-converters) using an asynchronous serial line (TXD, RXD).

Despite its name it is not limited to AVR controllers. Every device can debugged, provided it implements one of those protocols.

This program is used to adjust settings for [lavrdev], too.

2. Hardware interfaces

Several connections to the target controller are possible:

2.1. avrdev

avrdebug uses the block oriented protocol to talk to avrdev on a serial line, so use the command line parameter -a ser2.

avrdev acts like a gateway to the target device. The target device may be connected to avrdev via SPI or via a serial line. To tell avrdebug about which way to go, use -i UART or -i SPI.

You may also use -i SELF, which enables you to debug avrdev itself.

2.2. Simple parallel port adapter

You can use a simple adapter on the parallel port to connect via SPI.

The parallel port SPI connection can be a dongle like the one used by sp12 (atmel avr programmer):

Parallel port pin AVR pin










/SS this connection is optional!

The pin /SS is pulled low while being connected to the target.

Use command line parameter -a par.

2.3. Serial interface

Well, just make a standard UART connection from the PC to your controller. Of course you may use a usb-to-serial-converter, too.

You may use -a ser to use the simple serial protocol or -a ser2 to use the block oriented serial protocol.

3. Interface software running on the target

The target device needs to run some additional code to be able to talk to avrdebug.

On the homepage there is an archive containing examples (currently only for AVR devices).

As mentioned above there are three different methods of connecting to the target:

3.1. SPI

todo: describe SPI settings

The target device is in slave mode, which means that the communication clock is an input to it.

During one access, three bytes are exchanged.

First byte:

  • master sends low byte of adress

  • target sends 0x00

Second byte:

  • master sends high byte of adress, logically anded with 0x7F. The MSB is set for a write access and cleared for a read access.

  • target sends 0x01

Third byte:

  • in case of a write access, the master sends the value to be written. In case of a read access, the value is undefined.

  • target sends the value of the adress — in case of a write access this is the value before writing

The adress is limited to 15 bits.

3.2. Simple serial protocol

This protocol allows 16 adress bits and uses a seven bit CRC to make communication more secure.

avrdev sends four or fives bytes to the target:

  • first byte

    • MSB is set

    • bit 6 is cleared for a read access, set for a write access

    • bits 4 and 5 are unused

    • the lower nibble contains adress information

  • second byte

    • MSB is cleared

    • seven bits of adress information

  • third byte

    • MSB is cleared

    • five bits of adress information

    • bit 1 is unused

    • bit 0 contains data

  • fourth byte (only in case of write access)

    • MSB is cleared

    • seven bits of data

  • last byte

    • MSB is cleared

    • seven bits CRC

The target responds with two bytes in any case:

  • first byte: data read at the adress (in case of a write access this has been read before writing)

  • second byte

    • MSB is cleared

    • seven bits CRC

3.3. Block oriented serial protocol

I won’t describe that one here as it currently is only used between avrdebug and avrdev (which in turn uses the simple serial protocol to talk to the target device).

4. User interface

avrdebug does not have a GUI.

When compiled with libreadline, you have a command history and filename completion using the tab key.

5. User commands

Lines starting with # or ; are ignored.

5.1. Simple commands

show help




echo string

e "some text"

end of script file


loop (restart) script file


read script file


sleep some µs

s NumberOf_µs

5.2. read, write, wait until, break

I’ll show them without command modifiers first and give examples rather than using some syntax to describe their syntax ;-)

Every adress (A, B) and number (C, D) needs to be written decimal.

What to do command arguments

Read byte at adress A



Read D bytes starting from adress A


A * D

Read bytes from adress A to B


A - B

Write C to the byte at adress A


A : C

Write C to the bytes from adress A to B


A - B : C

Write C to D bytes starting from adress A


A * D : C

Wait until the byte at A is equal to C


A == C

Wait until the byte at A does not equal C


A != C

Wait until the byte at A is greater than C


A > C

Wait until the byte at A is smaller than C


A < C

The break command b is similar to the wait until command w, but instead of waiting until the condition is satified, it checks only once and aborts script execution if the condition is true.

Every command prints one or more values in return.

When using the w command, the previous value is displayed, not the one you are writing (as you do know that one anyway).

New feature: adresses A and B can be strings; their numerical values are read from a map file (out/asm/appl.sramdef or out/asm-after-pp/SRAM.txt) which contains lines like

#define some_name 935

New feature: you can add an offset to adress A, examples:

w16s 950 + 2 : -3748
r16s s32SomeValue + 2

5.2.1. Optional command modifiers

The general syntax of the command including optional modifiers is

Command L DisplayModifier

in case you are using a numerical length L.

Command is one of (r, w, u, b) and DisplayModifier is one of (u, s, h, q, Q)

The following sections will explain this in more detail.

How to specify the variables length

With the r, u and b commands you may read bytes, words (2 bytes) or any number of bytes as one value.

The number of bits is specified numerically by appending a number L in the range (8, 16, 24, 32) to the command. However, you have to use one of the modifiers (DisplayModifier) explained in the following sections in this case.

How to suppress output

You can suppress output by adding q or Q to the command. They only behave different with the u command (wait until): q means to only display the value when it matched, Q never displays the value read.

How to chose number base

Optional arguments (u, s, h) are allowed with the commands r, w, u. They indicate how to display the variables content: unsigned decimal, signed decimal, hexadecimal.

5.3. user variable

todo: how to use

6. Example script files

The script files below are written with numerical adresses, which is what avrdebug needs. Using it this way is cumbersome; take a look at the following chapter for better usage.

6.1. Some basic commands

# Trigger an algorithm in the target by setting a variable:
# Wait until the trigger variable gets reset:
# read some vars:
# reset those vars:
# use 'eof' to enter interactive mode
# use 'q' to quit the program

6.2. Read values in a loop

You might use something like this to continuously read a set of variables to a file, maybe to display them graphically or whatever:

e "this line is written only once"
# Insert a newline. Useful when using table output, ignored otherwise.
# Trigger an algorithm in the target by setting
# a variable, but don't display anything:
wQ 267 : 2
# Wait until the trigger variable gets reset,
# but don't display anything:
uQ 267 == 0
# read some vars:
r16s 517
# use 'loop' to start from the beginning:

To execute this script, use something like

avrdebug AdapterAndConnectionOptions -t -f ScriptFile > Outputfile


avrdebug AdapterAndConnectionOptions -t -f ScriptFile -o Outputfile

7. Integrate with your toolchain

You have to give variable adresses numerically, which is not easy, as they might change with every compilation of your firmware.

For interactive debugging, your toolchain should provide something like a map file which lists variable names and adresses, so you may look them up easily.

To make good use of script files I equipped my toolchain with some mechanism which automatically compiles script files with symbolic names to files with numerical adresses on every build, so

wQ Debug__b8ReadADC : 1
uQ Debug__b8ReadADC == 0
ruw Debug__au16ADC * 8

is automatically translated to something like

wQ 2168 : 1
uQ 2168 == 0
ruw 1783 * 8

There is a new feature which does part of that job for you by replacing names by values read from a map file, see above.

7.1. tavrasm

For use with tavrasm (there is only one project on which I do still use it, [lavrdev]) I have a tool which extracts variable adresses from the list file and produces a file suitable for the c preprocessor, which in turn is used to convert script files with symbolic names to files with numerical adresses.

7.2. gcc

Is guess that most people today use some variant of the gcc for their projects — I do not, so I can’t provide tools to convert script files in this case, sorry…

But the gcc is able to produce a mapfile during the build and I guess it should be possible to write a simple tool to extract variable names and adresses…

8. Command line arguments

Well, just execute avrdebug --help to get help about command line arguments.

Latest modification: 08.10.2017 21:45
Jens W. Wulf