Skip to content

Commit d2f5949

Browse files
authored
📝 Simplify debugging.md (#61)
1 parent 965c568 commit d2f5949

1 file changed

Lines changed: 111 additions & 152 deletions

File tree

mkdocs/user_guide/debugging.md

Lines changed: 111 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,198 +1,157 @@
1-
# 🎯 Debugging Firmware with PyOCD
1+
# 🎯 Debugging Firmware with PyOCD - A Beginner's Guide
22

3-
## Introduction
3+
## What is PyOCD?
44

5-
PyOCD is an open-source Python package for programming and debugging Arm
6-
Cortex-M microcontrollers using CMSIS-DAP. It's a highly flexible and
7-
easy-to-use tool, but it's important to note that it only supports ARM
8-
processors.
5+
PyOCD is a Python-based debugging tool specifically designed for ARM Cortex-M microcontrollers. Think of it as a bridge between your computer and your microcontroller that lets you inspect and control your program while it's running. While it only works with ARM processors, it's much more user-friendly than alternatives like OpenOCD.
96

10-
PyOCD stands out for its user-friendly approach compared to other On-Chip
11-
Debugging (OCD) tools like OpenOCD, despite being slightly limited in terms of
12-
the range of processors it supports.
7+
## Setting Up Your Environment
138

14-
For the full documentation for PyOCD see [https://pyocd.io/](https://pyocd.io/).
15-
16-
## Installation
17-
18-
To install PyOCD, run the following command in your terminal:
9+
### 1. Install PyOCD
1910

2011
```bash
2112
python3 -m pip install pyocd
2213
```
2314

24-
## Connecting a Debugger to your Device
25-
26-
Connect the debugger (STLinkV2) to your MicroMod Carrier board using the STLink
27-
to SWD connector adapter. Before connecting and powering everything check that
28-
the the ribbon connector is connected to the port with the glowing LED. That is
29-
the correct connection. Using the incorrect connection could cause part damage.
15+
### 2. Connect Your Hardware
3016

31-
If you are using another type of device with different connections follow this
32-
guide. A connection to ground (`GND`) must be made between the debugger and the
33-
development board in order for the devices to communicate.
17+
1. You'll need:
18+
- Your development board
19+
- A debugger (like STLinkV2)
20+
- Appropriate connecting cables
3421

35-
!!! Danger
36-
DOUBLE AND TRIPLE CHECK YOUR CONNECTIONS! Incorrect connects can result in
37-
breaking a board, debugger or possible your computer.
22+
2. Make the physical connections:
23+
- For SWD (most common):
24+
- Connect GND (Ground)
25+
- Connect SWDIO (Data line)
26+
- Connect SWDCLK (Clock line)
27+
- If your board uses JTAG:
28+
- Connect GND, TDI, TMS, TCK, and TDO pins
29+
- If you have a JTAG device that supports SWD
30+
- Connect GND
31+
- Connect JTAG TMS to MCU SWDIO
32+
- Connect JTAG TCK to MCU SWDCLCK
3833

39-
=== "Connecting SWD"
40-
Connect jumpers from `GND`, `SWDIO` and `SWDCLK` to the pins on the board.
41-
If the board supports both `SWD` and `JTAG` like many arm cortex boards do,
42-
then connect the pins in the following way: `SWDIO` --> `TMS` and
43-
`SWDCLK` --> `TCK`.
34+
!!! important
35+
Double-check all connections! Incorrect wiring can damage your board,
36+
debugger, or computer.
4437

45-
=== "Connecting JTAG"
46-
Connect jumpers from the `GND`, `TDI`, `TMS`, `TCK`, and `TDO` pins on the
47-
JTAG debugger to the headers on the development board of the same name.
38+
## Starting a Debug Session
4839

49-
## Connecting to device using PyOCD
40+
### 1. Launch PyOCD Server
5041

51-
The following commands will use `pyocd` and your debugger to connect to your
52-
target platform.
53-
54-
=== "lpc40"
55-
```bash
56-
pyocd gdbserver --target=lpc4088 --persist
57-
```
42+
First, start the PyOCD server for your specific device:
5843

59-
=== "stm32f1"
60-
```bash
61-
pyocd gdbserver --target=stm32f103rc --persist
62-
```
44+
```bash
45+
# For LPC40xx boards:
46+
pyocd gdbserver --target=lpc4088 --persist
6347

64-
To find all of the available platforms use `pyocd list --targets`.
48+
# For STM32F103xx boards:
49+
pyocd gdbserver --target=stm32f103rc --persist
50+
```
6551

66-
## Using arm-none-eabi-gdb
52+
Not sure about your target? Run `pyocd list --targets` to see all options.
6753

68-
`arm-none-eabi-gdb` is a version of GDB (GNU Debugger) configured for debugging
69-
Arm Cortex-M devices.
54+
### 2. Connect GDB
7055

71-
To start a GDB debugging session, open an additional terminal or terminal
72-
window. Then execute the following command:
56+
Open a new terminal and launch GDB:
7357

7458
```bash
75-
arm-none-eabi-gdb -ex "target remote :3333" -tui path/to/yourfile.elf
59+
arm-none-eabi-gdb -ex "target remote :3333" -tui your_program.elf
7660
```
7761

78-
- `-tui`: GDB TUI provides a text window interface for debugging. To start GDB
79-
in TUI mode, use the `-tui` option
80-
- `-ex "target remote :3333"`: `-ex` executes a GDB command. And the command
81-
`target remote :3333` connects to a remote gdb server, in this case, the pyocd
82-
server (with default port `:3333`).
62+
This command:
8363

84-
## Starting the Debugging Process
64+
- Opens GDB with a text-based UI (`-tui`)
65+
- Connects to PyOCD (`target remote :3333`)
66+
- Loads your program (`your_program.elf`)
8567

86-
Here is a cheat sheet for using [GDB Cheat
87-
Sheet](http://darkdust.net/files/GDB%20Cheat%20Sheet.pdf).
88-
89-
A typical first breakpoint for a program is to set a breakpoint on main.
90-
91-
```gdb
92-
b main
93-
```
68+
!!! tip
69+
`arm-none-eabi-gdb` command not found? No worries, build an project for an
70+
arm based device like so `conan build . -pr stm32f103c8 -pr arm-gcc-12.3`.
71+
There is a file called `generators/conanbuild.sh` which provides your
72+
command line access to the paths to the ARM compiler toolchain where GDB
73+
resides. Sourcing those environment variables would look like this, but
74+
replace `stm32f103c8` with your platform and `MinSizeRel` with your build
75+
type:
9476

95-
Next you will want to reset the program back to the start and halt the CPU using
96-
the following command.
77+
```bash
78+
source build/stm32f103c8/MinSizeRel/generators/conanbuild.sh
79+
```
9780

98-
```gdb
99-
monitor reset halt
100-
```
81+
## Basic Debugging Commands
10182

102-
To begin running through the program use the `continue` or `c` command.
83+
### Essential GDB Commands
10384

10485
```gdb
105-
c
86+
# Start your debug session
87+
b main # Set breakpoint at main()
88+
monitor reset halt # Reset the CPU and stop at the beginning
89+
c # Continue execution
90+
91+
# Navigate through code
92+
n (or next) # Execute next line (skip function details)
93+
s (or step) # Step into functions
94+
finish # Run until current function returns
95+
c (or continue) # Run until next breakpoint
96+
97+
# Inspect values
98+
p variable_name # Print variable value
99+
info registers # View all CPU registers
106100
```
107101

108-
At this point you should see the source code of your `main.cpp` show up. Now you
109-
can step through your code and set breakpoints using `step`, `next`, `finish`
110-
and `continue`, `break`, etc.
111-
112-
Typically you would use the `run` command to start the code. When performing
113-
firmware testing, the `run` command is not needed as the code is already
114-
"running" on the remote microcontroller.
115-
116-
!!! info
117-
On boards with a factory bootloader, when you start debugging, you will
118-
notice that you cannot see the source code lines in the gdb shell. This is
119-
because the bootloader instructions are not associated with any addresses in
120-
your code, thus you will not see source code. This is fine. Continue with
121-
the guide. The LPC40xx family of microcontrollers has such a bootloader.
122-
123-
## Stepping Through Code
124-
125-
Once in a GDB session, you can step through your code using the following
126-
commands:
127-
128-
- `next` or `n`: Executes the next line in the source code. If the line contains
129-
a function call, it treats the entire function as one instruction and executes
130-
it in one go.
131-
- `step` or `s`: Executes the next line, but if it contains a function call,
132-
`step` will go into that function so you can continue debugging inside it.
133-
- `finish`: Runs until the current function is finished.
134-
- `continue` or `c`: Continues execution until the next breakpoint or
135-
watchpoint.
136-
- `until lineno`: Continues execution until a line number greater than the
137-
current one is reached. Useful for loops.
138-
139-
Remember that you can use the `help` command in GDB to get information about any
140-
other command.
141-
142-
## Inspecting Variables and Registers
143-
144-
You can inspect the state of your program by examining variables and registers:
102+
!!! tip
103+
If you are familiar with GDB, you notice that the command "run" was not
104+
used. In this context, there is no program, just the CPU. The debugger is
105+
controlling and stopping the CPU from executing. So there is no need to
106+
"run" the program, its already running. You simply have to continue.
145107

146-
- `print variable` or `p variable`: Prints the current value of the specified
147-
variable.
148-
- `info registers`: Shows the current state of all CPU registers.
149-
- `info register regname`: Shows the current state of a specific CPU register.
150-
- `print gpio_reg->CTRL`: Shows the value of a register
108+
### Viewing Memory and Registers
151109

152-
!!! tip
153-
If you get an error like:
110+
To access hardware registers and memory:
154111

155-
```
156-
Cannot access memory at address ???
157-
```
112+
```gdb
113+
# Enable access to all memory
114+
set mem inaccessible-by-default off
158115
159-
This happens because GDB is limiting access to memory that is known at
160-
link time and is apart of the binary's structure. But if a user wants to
161-
access peripheral memory not associated with RAM or Flash memory then they
162-
can execute this command:
116+
# View register values
117+
p gpio_reg->CTRL # View specific register
118+
```
163119

164-
```gdb
165-
set mem inaccessible-by-default off
166-
```
120+
### Managing Breakpoints
167121

168-
## Setting Breakpoints and Watchpoints
122+
```gdb
123+
b function_name # Break at function start
124+
b filename.cpp:123 # Break at specific line
125+
info breakpoints # List all breakpoints
126+
delete 1 # Remove breakpoint #1
127+
delete # Remove all breakpoints
128+
```
169129

170-
Breakpoints allow you to pause program execution at a particular point, and
171-
watchpoints let you pause execution whenever a particular variable changes:
130+
### Updating Your Program
172131

173-
- `break function` or `b function`: Sets a breakpoint at the beginning of the
174-
specified function.
175-
- `break filename:lineno` or `b filename:lineno`: Sets a breakpoint at a
176-
specific line in a specific file.
177-
- `watch variable`: Sets a watchpoint on a variable. The program will stop
178-
executing whenever the variable's value changes.
179-
- `info breakpoints`: Lists all the breakpoints that are currently set.
180-
- `delete n`: Deletes breakpoint number `n`. Use `info breakpoints` to see
181-
breakpoint numbers.
182-
- `delete`: Deletes all breakpoints if used without a number.
132+
If you make changes to your code:
183133

184-
## Flashing a Device using GDB
134+
1. Build your program in another terminal
135+
2. In GDB:
185136

186-
In GDB, you can also use the `load` command to flash your device. The `load`
187-
command automatically uses the target specified when you started the GDB
188-
session.
137+
```gdb
138+
monitor erase # Erase current firmware image
139+
load # Flash the new program
140+
monitor reset halt # Reset to start and halt CPU
141+
```
189142

190-
```gdb
191-
(gdb) load
192-
```
143+
## Tips for Beginners
193144

194-
This command will load the program onto your device.
145+
- Start with simple programs to get comfortable with the debugging process
146+
- Use frequent breakpoints to understand program flow
147+
- `-s build_type=Debug` builds are easy to debug with a debugger than
148+
`-s build_type=MinSizeRel` or `-s build_type=Release` builds
149+
- Remember that embedded debugging is different from regular program debugging
150+
because your code is running on actual hardware and you are controlling the
151+
cpu
152+
- If you can't see source code lines initially, don't worry - this is normal
153+
with bootloaders (like on LPC40xx boards), proceed with the `continue`
154+
command and you should end up at your first breakpoint whenever it is reached
195155

196-
You can build the elf file in another terminal, then run `load` again to update
197-
the program. It may or may not reset the core back to the start so
198-
`monitor reset halt` may be needed.
156+
For a complete reference of GDB commands, check out this
157+
[GDB Cheat Sheet](http://darkdust.net/files/GDB%20Cheat%20Sheet.pdf).

0 commit comments

Comments
 (0)