When writing AVR code, it can be difficult to debug problems, especially when adding Serial.printf()
calls means that the bug vanishes! Actually, only Serial.begin()
is required to make the bugs vanish.
WARNING: The simulator hangs if you let the code run and there’s a delay()
call in the code. This may be an artefact of running under gdb – I have yet to test what happens if I just run the code. Might be worth bearing this in mind.
GDB Tutorial
See https://www.gdbtutorial.com/gdb_commands for a useful gdb tutorial
Configuration and Execution
In order to use the option Sketch->Optimize for Debugging in the Arduino IDE, you need to do a little configuration of the IDE to allow that option to have any effect on Arduino boards using the ATmega328P microcontroller. See this post from the future for details. Once the IDE is correctly configured, you may proceed.
- In the Arduino IDE, Sketch->Optimize for Debugging. Then rebuild the sketch with verbose compilation enabled in preferences.
- In a bash session
cd /tmp/arduino/sketches/LONG_HEX_NUMBER
which you can see in the compilation output from the previous step. simulavr -g -d atmega328 -f SKETCH.ino.elf
to start the simulator. You do not need the Arduino board to be running, we are simulation it.- Your terminal will hang, so open another [tab] and run:
1 2 3 4 5
cd /tmp/arduino/sketches/LONG_HEX_NUMBER avr-gdb file SKETCH.ino.elf target remote localhost:1212 load
You are now running the sketch in the simulator, and using gdb to set breakpoints etc in the normal manner.
Useful gdb commands
See also https://www.gdbtutorial.com/gdb_commands
b location
- sets a breakpoint atlocation
.ir
- displays all 32 registers.ir r18 r25
- displays registersr18
andr25
only.p variable
- displays the value of a variable.p (short)variable
- displays the value of a variable as ashort
data type.continue
,cont
orc
- resumes execution after a breakpoint stop.step
- steps into the next executable instruction.next
- same asstep
but will treat a function call as a single instruction and will stop when the function returns, unlikestep
.x/FMT ADDRESS
- displays a memory dump ofADDRESS
in the specifiedFMT
FMT Specifiers
The FMT
specifier for the x
command is in three parts:
- An optional counter to specify how many “data types” will be displayed.
- The format of the output:
o
= octald
= decimalx
= hexadecimalu
= unsigned ints
= stringt
= binary
- The data type:
b
= bytesh
= half words (16 bit)w
= words (32 bit)g
= double word (64 bits).