I have decided to write about the usage of Raspberry pi as both wireless programmer/debugger and tool for automated testing for Cortex-M MCUs. There are few articles and tutorials but still, this topic's online coverage is rather poor considering its usefulness.
Please consider this as more of an inspiration than complete tutorial.
You can use any Raspberry Pi as a standalone programmer/debugger plus also write debugging script which can do some form of low-level automated testing.
OpenOCD
Most debugging setups are server-client based. We have a server which is taking care of interfacing with our HW programmer/debugger and then client which is used for actual debugging - it asks the server to set breakpoints, read memory, etc...
We will use OpenOCD as our server but if we wish to use raspberry GPIO port as an SWD debugger we need to recompile it with its support turned on you can use Adafrauit's tutorial for this step: https://learn.adafruit.com/programming-microcontrollers-using-openocd-on-raspberry-pi
Also, OpenOCD can be used with most programmers and development boards by finding proper config scripts in the interface or target folder and editing your config file.
You can define events in your config file to customize what happens when for example client connects and disconnects like this:
$_TARGETNAME configure -event gdb-attach { halt } $_TARGETNAME configure -event gdb-detach { resume }
Depending on your target MCU and interface setting up OpenOCD can be as easy as it gets or rather complicated (Mainly in cases of newer MCUs which need some flash or security setup and there is no config script supplied by openocd)
Also by default OpenOCD is binding only to a localhost address if you want to be able to connect to it from other computers you need to add "bindto 0.0.0.0" to your config file.
Beware that it's not secured so anybody from your network can connect to it. The best solution would be to leave it bound only on to a localhost and create SSH tunnel
After successfully running openocd its output can look something like this:
Info : BCM2835 GPIO JTAG/SWD bitbang driver Info : JTAG and SWD modes enabled Info : clock speed 4061 kHz Info : SWD DPIDR 0x2ba01477 Info : lpc17xx.cpu: hardware has 6 breakpoints, 4 watchpoints Info : lpc17xx.cpu: external reset detected Info : Listening on port 3030 for gdb connections TargetName Type Endian TapName State -- ------------------ ---------- ------ ------------------ ------------ 0* lpc17xx.cpu cortex_m little lpc17xx.cpu running Info : Listening on port 6666 for tcl connections Info : Listening on port 4444 for telnet connections
GDB
Now to be able to connect to your OpenOCD server you need a client. GDB is something you would almost always use in this setup. If you have your standard arm gcc tools installed you can use arm-none-eabi-gdb.
You can use it from the command line like this:
arm-none-eabi-gdb ./YourELFBinary.elf //run gdb with your binary also its good not to move your binary from a place where it was compiled so gdb can parse track symbols to their place in a source code. //now you are in a gdb console target extended-remote 192.168.0.10:3333 //you can connect to your server like this //if you want to load binary into device load //show value of variable p var //continue program cont //reset MCU monitor reset //show stack info stack //you can break program at any time by pressing ctrl+c
This is example of some basic usage, you can use almost any IDE to debug using GDB, if you use eclipse look for GNU ARM C/C++ OpenOCD Debugging package.
GDB Scripts
But more interesting and useful usage for me is to use it for automated testing. You can write scripts for GDB using GDB internal interpreter or you can use python.
Let say we want to check if some variable isn't set to zero and if it is we want to know from where exactly.
target extended-remote 192.168.0.10:3333 watch var_pointer catch signal SIGTRAP commands if var_pointer != 0 cont else print "var_pointer is set to 0 from:" info stack end end
Or something more simple print something every time breakpoint gets hit:
target extended-remote 192.168.0.10:3333 rbreak Radio.cpp:.*receive* commands silent printf "radio beacon from address: %d\n", beacon.source_address cont end continue
You can run those scripts like this:
arm-none-eabi-gdb -batch --command=./script.gdb .\binary.elf
You can, for example, take your Raspberry pi, set up build tool-chain on it, and every time changes get committed to your source code Raspberry can build it, load it into MCU through SWD and then run gdb scripts and send you results on email etc..
And as you can see all of this costs only one Raspberry pi. (and a little bit of time while learning it all)