I think the biggest frustration point for any new or even seasoned engineer is the debugging phase: my application finally builds fine, but I’m not able to connect and download it to the target board :-(. In my view the debugging part is the most fragile part of the development process. I’m always very relieved if I can connect to a brand new board, because I know if it does not work, then the problem could be a very bad one, costing my several hours or even days to overcome it.
I don’t say that this is a complete check list, but I hope it will help you in a desperate situation where you are not able to connect or debug your target.
Below is my list to check things if debugging fails, based on my experience.
- Check power supply. Too many times the board is not powered, or the power supply not turned on. Or worse, that the external power supply is not stableorcannotprovide the needed current. I had a case where the external power supply dropped the voltage every minute or so which dramatic consequences to the board. If your board is USB powered:make sure enough power is provided. Some notebooks are only providing 100 mA, use a powered hub or a 5V USB wall power supply. The P&E Multilink and other debug probes feature a ‘power sensing’ LED which helps in such a situation.
- Check the plug: on the Freescale Freedom boards there are two USB ports, but only one is for debugging:
- Check the polarity of your debug cable: many debug headers/connectors do not protect you from putting the cable the wrong way.
- Change the USB cable and port. I have seen cases where one port on a host was somehow bad. Try avoid USB3 ports, do not use USB hubs between the host and the probe. Change cables and port. Avoid long cables. Check the USB contacts/plug on both the host and the probe side: they could be weared out, have bad contacts or even broken soldered connectors.
- Make sure you are talking to the right device. If you have multiple boards and multiple debug devices: Make sure you are connecting with the correct one. make sure your debugging device is listed. Most debug cable have USB ID: I put stickers with the number on the debug device.
- Check that you have a file: If you get a dialog telling you that the program file does not exist:
Then it exactly means that: the program file does not exist (:-)), or you have specified none or a non-existing file. Check your debug/launch configuration and have a valid file specified:
- Update the firmware of board/debug probe: I have spent several times debugging a problem, only to find out that a new firmware of the board/debug probe solves the problem. In rare cases, a new firmware might break something working, so keep backups of the old firmware, just in case. See “Illustrated Step-by-Step Instructions: Updating the Freescale Freedom Board Firmware” how to update the Freedom board firmware.
- Do not use the ‘debug’ icon: There is a bug in Eclipse Kepler+CDT that pressing the ‘debug’ button does not launch the right configuration, or screws up otherwise.
Instead, select the debug/launch configuration from the drop down list:
If you do not have anything in the list, select the ‘Debug Configurations…’ entry and press ‘Debug’ from there. Use the ‘favorites’ menu setting to force it to the list:
- Kill hanging debuggers. Check in the task manager if you have a zombie debug process (gdb executable, or whatever debugger technology you are using, see “Killing Me Softly: Zombies and Debugger Engines” or here).
Kill them in the task manager. Or quit the IDE. If this does not help: restart your machine as last resort. Asking for trouble with gdb is if you try to launch a second debug session with one already going on.
Error in final launch sequence Failed to execute MI command: -target-select remote 127.0.0.1:7224 Error message from debugger back end: Remote communication error. Target disconnected.: No error. Remote communication error. Target disconnected.: No error.
Kill/Terminate first the current debug session before starting a new one.
- Verify the host drivers. USB drivers are a constant source of pain. Make sure you know which USB drivers should be active/present in your system. Note down your current configuration, because maybe you get a host machine update or whatever, and your drivers do not work any more. See “Fixing the USB Drivers“. If you have USB 3.0 plugs on your machine, switch to USB 2.0 ones, as for me USB 3.0 is a constant source of troubles.
- Check the cables. I had too many times bad USB cables, try to exchange the cables. In one case the USB plug in the notebook was worn out, try different USB ports. I had as well bad debugging flat cables: if they are used too long or bended too much, the cable can break inside, causing all kind of weird problems. Check as well the USB plug of the debug probe (cold solder on the connectors, maybe as bad as in “How NOT to Solder Headers on a Board“? Resoldering the connectors helped me in one case). I have seen a person complaining about debugging not working, and I noticed that the USB cable was maybe 5 or 6 meters long (yikes!). In another case we had frequent debugging failures, and the reason was noise from a nearby motor which affected the signals in the debug probe and cable: shielding the cables and probe plus shortening the flat band cable solved the problem. In any case: have your critical equipment duplicated: it is easier to swap out a part in the chain than just guessing if your debug probe is broken or not. I had bad debug probes probably broken by ESD (Electro-Static-Discharge) or other high voltage: having a second unit at hand will be a huge time saver.
- Check SWD or JTAG. Many ARM controllers can be used with SWD or JTAG (see “Using the FRDM-K64F with CodeWarrior“). If your board only has SWD, and I you get for example:
Connecting to target. OpenSDA detected - Flash Version 1.14 Can not enter background mode. Unable to initialize PEDebug. PE-ERROR: Failed to Initialize Target
Then you try to connect in JTAG mode to the board, instead of SWD. Make sure you have the correct settings in your debugger:
- Check the processor: Failing to set the correct processor in the debugger settings will let the debugger talk to a completely different CPU (different flash programming algorithm, different memory map, etc) and things are failing badly. It is easy to select the wrong device from the list. Every single letter or digit counts.
Check carefully what is soldered on the board: maybe the schematics is wrong, or you have a similar (but different) board. I had a case where the wrong microcontroller had been populated by the factory!
- Check the clocks. On ARM cores, you need to ‘clock’ any peripherals before you can access it, or you get a hard fault. Make sure that you clock for example the RTC before you access it. You might even need to power your peripheral externally with a dedicated pin first. Try first to run your microcontroller with the internal clock, at default and low-speed. Check the circuit of your external clock, check the data sheet of your oscillator/crystal if you have used the correct bypass capacitance network. Keep in mind that the external clock traces need to be as close to the processor as possible, and that it can influence other traces. I had a case where the debug traces were routed underneath the oscillator. Of course this was a great failing point :-(.
- Check the Watchdog: some devices have the watchdog enabled by default. If the watchdog does not get kicked, it will reset your processor. Ensure that the watchdog is disabled very early in the startup (right after reset).
- Check the logs. Carefully inspect the debugger logs or console output. Does it make sense? Are the expected parameters listed? What is the debugger doing, and when does it fail?
- Step through the startup code. If you are able to connect, but somehow the application does not reach main, you will need to debug through your startup code. Your debugger setting should have something like ‘run to main’ or ‘run after reset’: disable it so you can find out what is going on.
- Check the debug pins: if you made your own board, are the signals/footprint correct? Reset line stable and as recommended by the vendor (usually pull-up with a capacitor)? Use as scope to inspect the signals. Check if there are not shortcuts between the signal lines. The debug probe needs the reset line to halt the processor: if the pull-up is too strong or the C too high, it might be difficult for the debugger to gain access. I had one case were the CPU was soldered (QFN package) wrongly :-(.
- Check if you have not disabled debugging: Have you secured your part (see “How (not) to Secure my Microcontroller“)? If it is secured, debugging is not possible, so hopefully you can still do a mass erase (see “Unlocking and Erasing FLASH with Segger J-Link“). With modern microcontroller it is possible to divert debugging pins for general purpose functions. Check if you have not disabled in your application critical resources for debugging (reset pin? JTAG/SWD pins?). Some processors have extra ‘firmware upgrade pins’, like the EzPort on Kinetis/ColdFire: wiring these pins wrongly will get the processor in a special/upload mode which interfere with debugging.
- Re-Muxed Debug Pins: On many controllers it is possible to re-use the pins used for debugging for other things like GPIO. Out of reset typically they are configured for debug, but if your startup or initialization code changes them to be used for something else than debugging, your debugging session will terminate.
- Divide and conquer: Try to get a working solution/project (e.g. use a simple/empty project with an evaluation board from your vendor). Then find out what is different in your non-working environment. Try to limit the number of variables: remove external/not needed connections on the board. I had a case where the external clock circuit was causing problem: removing that clock moved me on the right track.
- Keep an audit trail: Use a version control system for your project(s). Many times it works for a long time, and then you make a (you think unrelated) change, and things do not work anymore. Using version control system like Git allows you to go back in time, or make a diff what you have changed. It helps you as well for when the tool has corrupted you some of the settings.
- Try different tools/machines: Hopefully you have the choice of alternative tools. As sad as it is, depending on your system/drivers/other tools installed, one or the other tool might simply not work. Try installing your tools on a fresh machine to see if that helps. Use a different operating system (32bit/64bit, different windows version, etc), try it with your home machine. Maybe it works on one machine so you can isolate the problem.
- Repower board and/or debug probe: sometimes the board and/or the debug probe are screwed up. Try repower them. Sometimes the debug probe cannot force the target into reset mode (the debug probe constantly tries to pull the reset pin): power off the target microcontroller and re-power it might get the debug probe a chance to connect. If you have a reset button (you always should add one in your own design!), press the reset button while power-on the board to keep it hopefully in reset.
- Smell the blue smoke. Electronics are driven by blue smoke. Because when you see it coming out, you know it is dead. If you smell something weird, check if it is your board. Check the temperature of you micrcontroller carefully touching it (I have burnt once one of my fingers badly!). If it is hot, turn off power and hope for the best (or a replacement).
- FreeRTOS Task Stacks: if using FreeRTOS, using very large stacks (say >4KByte) can cause problems with the debug probe kernel awareness: disable that kernel awereness and try a smaller stack if this makes a difference.
There is not a single tip or trick if debugging does not work. But checking the basics for shure will help. Otherwise, try to swap out things to limit the search area. The most troublesome things are custom boards, as many things can fail. Invest into an evaluation board which works so you have something to compare with.
Happy Debugging 🙂
PS: If you have more tips and tricks, post a comment and share!