Recently, I had the opportunity (need?) to explore the native debugging features of the 3rd gen Particle Hardware. In this particular case, I got myself set up to debug native code on a Particle Argon. Since this may be useful to others trying to get their debugger up and running, I decided to document the process.
Please note, before going any farther in this article – this is a very superficial/quick guide to getting set up with Native Debugging. I ran into a few things getting it set up on my Mac, and thought it would be a useful thing to document. However, this is not a very comprehensive guide to the strategy of debugging on Particle, or anything like that. It will get you up and running so that you can figure things out. That’s about it.
The scenario I got myself into was somewhat self-inflicted. I am in the process of adding a slightly more sophisticated UI to drive a small display embedded in one of my temperature control units. I had some time to go deep while I didn’t have access to hardware to do my typical development loop of small incremental changes, followed my micro-tests. Basically, I wrote a bunch of code that ended up causing a hard crash on the Argon, and I don’t know why….. so let’s figure it out!
If you’re reading this, you may be in the same scenario. Basically, I have a Particle Argon flashing a red light of doom pattern. You can learn what those different error codes may be here.
What’s nice now though, with the 3rd gen hardware, is that instead of begging a fairly painful sequence of console debugging, and trying to isolate the problem, we’ve got access to a native debugger via the Particle Workbench integration Particle has provided with MS VS Code.
I’m not going to get into how to set up Particle Workbench. If you need to install and configure, you should start here.
Setting Up the Debugger
Ok. So, we know we’ve got a problem. We’ve got Particle Workbench fired up, and we need to figure out how this debugging thing works. Turns out, it’s not too bad.
First things first – you’re going to need the hardware debugger module:
Second of all – to give credit where credit is due, there’s a great quick start on the Particle site in their Workbench documentation. This is where I grabbed the basics. I just wanted to document my findings for my specific project as well. If you run through this tutorial, you’ll be up and running in no time.
I established the dual-USB connections as outlined in the instructions. One to the Argon, which is the typical path for local firmware flashing. The second, through the Particle Debugger.
I’m on a Mac here, so I get to have some of the USB-C to USB adapter fun that Mac users enjoy frequently. I found that the Debugger itself was not happy trying to run on the selection of direct USB-C adapters I had on my bench, so I ended up plugging everything through a USB hub.
Building a Debug Build / Starting a Debug Session
Turns out, this is pretty simple in the Particle Workbench. You need to switch into debug mode by clicking the Debug icon on the left of the screen, and then you need to select your target.
After that, you put your Particle device into DFU mode (LED flashing yellow) by holding down both the Reset and Mode buttons for a couple seconds, and then releasing Reset and holding Mode until the device begins to flash yellow.
Clicking the Green Arrow at the top left of the Debug Panel starts your debugging session.
If all works as advertised, your device should reset, and your debugging session will activate. Controls are relatively straight forward – the debugging panel will appear and look like this:
The buttons are as follows:
- Start/Continue – Will allow execution to begin or resume (if you’ve hit a breakpoint – more about breakpoints below).
- Step Over –Will allow you to step over a function call. Or, in other words, execute a function without diving into the code for it.
- Step In – Allows you to step into a function call, which then allows you to step line by line through that function.
- Step Out – If you’ve stepped into a function and are ok to advance execution until the function returns, you click Step Out and the debugger will execute up to the point of return of the function you are in.
- Restart – Restarts the program and debugging session.
- Disconnect – Ends your debugging session.
The most important tool in a debugging session is being able to stop execution at a specific point. This will allow you to inspect variables and start stepping through the code one line at a time (using the Step In/Step Over functions described above).
Toggling breakpoints is super easy. Although you can do it through the menus, the fastest way is to simply hover over the area to the left of the line number of the line you wish to break on. Clicking there will set a red dot indicating a breakpoint. Click the red dot again to clear the breakpoint.
Conclusions and Next Steps
Obviously, this is a very quick/crude guide to getting your debugger set up, as opposed to comprehensive guide to the strategy of debugging. You’ll find that depending on the type of bug you’re chasing, sometimes it’s enough to just step through code. But, a lot of the time it takes some very careful digging and analysis of variables, contents of memory, and in particular writes to memory to figure out what may be going wrong.
We’ll continue to document our adventures and any tricky bugs we discover along with the techniques we used, but if you’ve got any helpful hints, please feel free to contribute below.