Tuesday 2 June 2020

GDB hosted printf() for AVR8

Atmel Studio 7.0 has a rather nice AVR8 hardware simulator but they don't support a debug channel so it can be hard to figure out what your code is doing.

Happily, their simulator supports GDB (their whole toolchain is GNU) and there's a feature of GDB that can be used to provide a debug channel without interference with the simulator.

First build the obligatory "Hello, World!" program

debug.c:
// Note the optimiser will remove this if it's not compiled independently
void dputs(const char* sz)
{}

main.c:
extern void dputs(const char*);
void main()
{
    dputs("Hello, World!");
}

Then start the simulator with thanks to Morten
atbackend.exe /avr8-gdb-ports=12345

Then start gdb attached to the simulator
avr-gdb.exe -iex "target remote :12345" \
            -ex "monitor tool simulator" \
            -ex "monitor device ATmega640" \

A few commands sets up the target and debug channel
load HELLOWORLD.ELF
file HELLOWORLD.ELF
monitor reset
dprintf dputs,"%s",_
continue

And hey presto!


What happened there? Well from the simulator's point of view it was an empty function call that took a couple of clock cycles. However, GDB inserted a breakpoint that halts the simulator, including simulated peripherals, and read some RAM from the simulation before allowing it to continue.

There's no particular reason why this wouldn't work over JTAG too. However, be aware that the clock only stops for the microprocessor; other peripherals and in particular off-chip peripherals will notice the lag incurred by GDB stopping the chip, reading the RAM, starting the chip again.

No comments:

Post a Comment