5 steps to setup and use a debugger with the Particle Photon

See this follow-up article if you use Windows.

1. Buy the hardware

2. Install the software

sudo apt-get install libusb-1.0.0-dev
  • Open a terminal to the OpenOCD source folder and run
./configure --enable-ftdi
make install
(on Linux you need sudo make install)
  • On Linux, copy UDEV rules files to avoid having to run openocd with sudo.
sudo cp contrib/99-openocd.rules /etc/udev/rules.d/

3. Compile the firmware

Don’t use pins D3 to D7

git checkout develop
cd main
make clean all program-dfu PARTICLE_DEVELOP=1 PLATFORM=photon USE_SWD_JTAG=y MODULAR=n

4. Start the debugger

openocd -f interface/ftdi/particle-ftdi.cfg -f target/stm32f2x.cfg -c "gdb_port 3333" -c "\$_TARGETNAME configure -rtos FreeRTOS"
Successfully connected to the Photon through the Programmer Shield
Reset the target using OpenOCD through telnet
arm-none-eabi-gdb -ex "target remote localhost:3333" ../build/target/main/platform-6-m/main.elf
GDB ready to debug!

Using the debugger

  • Set breakpoints in your code with break <function>
  • List breakpoints with info breakpoints and remove them with delete
  • Resume execution with c (continue) and interrupt execution with Ctrl-C (this can be very useful to find an infinite loop).
  • Go the next line with s (step) or n (next). Next skips over function calls. Run until the current function returns with fin (finish).
  • Show the value of a variable with p <variable> and all locals with info locals
  • Print a stack trace with bt
  • Send OpenOCD commands using monitor <command>
  • Reset the Photon and pause immediately at start with monitor reset halt. You can then set breakpoints and start the program with continue
Break at setup and get ready to trace the program



Load all symbols in the same GDB session:

  • Extract the address of each module .text section
  • Load each ELF into GDB with add-symbol-file, passing the address above (for some reason GDB doesn’t use the address in the ELF file as a default and forces you to find that address on your own)

Set breakpoints

(gdb) break setup
Breakpoint 1 at 0x806ed2c: setup. (3 locations)
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y <MULTIPLE>
1.1 y 0x0806ed2c in system_part2_init at src/module_system_part2.c:96
1.2 y 0x0806ed2d <setup+4294967295>
1.3 y 0x080a02f0 in setup() at src/application.cpp:40
(gdb) disable 1.1 1.2
(gdb) continue
Program received signal SIGINT, Interrupt.
setup () at src/application.cpp:40
40 {
(gdb) list
38 /* This function is called once at start up ----------------------------------*/




CTO at MuniRent. Sharing my love of code

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Julien Vanier

Julien Vanier

CTO at MuniRent. Sharing my love of code

More from Medium

Efficient ways to call .env

SQL Injection VS Prepared Statement

Publishing npm package on github using github actions.

[Solved] Error MSB8041 MFC libraries are required for this project.