aboutsummaryrefslogtreecommitdiffstats
path: root/guides
diff options
context:
space:
mode:
Diffstat (limited to 'guides')
-rw-r--r--guides/debugging.md81
1 files changed, 81 insertions, 0 deletions
diff --git a/guides/debugging.md b/guides/debugging.md
new file mode 100644
index 0000000..1e13191
--- /dev/null
+++ b/guides/debugging.md
@@ -0,0 +1,81 @@
+# This is a simple guide to using AVR-GDB with simavr
+First of all, you can use the [Makefile](../Makefile) in the directory above.
+But for the competeness sake, I'll list commands
+
+## Running simulation
+QEMU: I don't personally prefer it, but here is a breakdown:
+```sh
+qemu-system-avr -M arduino-uno -bios <image> -nographic -s -S
+```
+* `-M`: machine to use, shorthand for `--machine`. Self-explanatory.
+* `-bios`: the thing that you would flash onto your arduino. Note that this is
+ not a hex file, this must be an elf file, the one you get out of `ld`.
+* `-nographic`: this should be default to be honest
+* `-s`: shorthand for `-gdb tcp::1234`. Enables GDB debugging
+* `-S`: suspend execution and wait for debugger to connect.
+This should be everything you need.
+[More documentation] (https://www.qemu.org/docs/master/system/target-avr.html)
+
+SIMAVR: This is the one I prefer
+
+First of all, the `--help` is actually not as big so it's easy to guess
+everything yourself, but fine, here is the command:
+```sh
+simavr -m atmega328p -g <image>
+```
+I think you can already see why I like it more. Breakdown of flags:
+* `-m, --mcu` stands for "MicroController Unit". atmega328p is the processor arduino
+ uno uses
+* `-g, --gdb`: wait for gdb to connect on `:1234`
+* `-f, --freq`: optionally specify the clock frequency, arduino uno has 16MHz
+You can also interrupt the process to kill it! Qemu does not let you do that.
+
+## gdb
+```sh
+$ avr-gdb <image>
+(gdb) target remote :1234
+(gdb) c
+```
+First of all, load the image. Then connect to the simulation. Since this is not
+a program in a traditional sense, it's already running and you have to
+`continue` instead of `run`.
+* to break at an address, use `b *0x69`. also, 0x69 is odd, so you will not land
+ there. Instructions are either 16 bit or 32 bit on AVR, so almost any even
+ address is a valid instruction.
+* to print instructions at some address, use `x/16i 0x420`, replace 16 with
+ amount of instructions and 0x420 with an actual address. you can also use
+ `$pc`, which stands for program counter (current instruction) as an address.
+ Also, unlike on intel/arm64, you can safely write `x/4i $pc-4` and get a valid
+ disassembly.
+* To print register values, use `print $r16`, replace `r16` with any register
+ you want. For formatted printing, see `help x` in gdb shell, it is often
+ useful to `print/x` in hexadecimal or `print/t` in binary.
+* use `displ` command. You will probably want to track current instruction, 1 or
+ 2 registers and some IO memory addresses. For me, a "must have" is
+ `displ/i $pc`, which displays an instruction to be executed each time the
+ execution avdances. really useful for stepping
+* `si` command steps 1 assembly insstruction. you will find yourself using it a
+ lot
+* To print IO registers, use `print *(unsigned char*)0xADD12E55`. NOTE that, if
+ you can use `in/out` instruction to access a memory location, gdb can't, it
+ will always use `sts/lds`. So don't forget `0x20` to all IO locations before
+ `0x3F`. For example, if you want to track `PORTB`, you'd often write
+ `displ/t *(unsigned char)0x25`, even though documentation says the `PORTB` is
+ at `0x05`.
+* To restart the program without restarting the simulation, you can write
+ `set $pc = 0`. This will trick a processor into thinking that next instruction
+ is at `0x00`, which is a reset vector. Note that state of your registers does
+ not reset. The set command it useful in many places, for example you want a
+ loop to execute for a little longer - you can set the counter register to 0.
+* you can safely put breakpoints at interrupts, at any labels you defined,
+ anywhere.
+* I coudn't get `compile code` gdb instruction to work (to execute assembly
+ on-the-fly), because it can't find the avr C compiler. Maybe this is a
+ distribution misconfiguration. Didn't bother setting up stuff in a debian VM.
+
+This is it! Hope this was helpful.
+
+P.S.: Internet has a lof of `avr-gdb` guides, and even more "just `gdb`" guides,
+which are as relevant. Search them up and have fun debugging!
+
+JAC, 2025