Debugging is one task every developer wants to avoid but it is unfortunately a necessary evil of software development. When the time comes to roll-up your sleeves and start a debugging session, there are 7 tips that every developer should be mindful of.
Tip #1 – Take controlled baby steps
When a bug creeps into embedded software the first instinct of a developer is to jump into the code and start making changes. Instead of making changes in a controlled and directed manner, they are usually hap hazard and nearly random. Embedded software development isn’t the wild west. The resolution of even the simplest bugs should still involve reviewing available data, evaluating it, hypothesizing the most likely cause, update and then test. In the event that the change does not solve the problem new data should come to light that then helps the process to be repeated.
Tip #2 – Increase assertion density
The ASSERT macro is a great tool that developers can use to verify assumptions within their code. Surprisingly, many developers don’t take the time to put them into their code. The ASSERT density of a code base can often be the difference between long and painful debug sessions or the trapping of a failed assumption the moment it happens. ASSERT can help a developer discover bugs or assumption failure immediately. What is the ASSERT density of your code base?
Tip #3 – Use a data logger
Information about how the software is operating is the greatest tool to an embedded software engineer when debugging. Having performance information such as when tasks start and complete, whether they are pre-empted among other details can be critical. The use of a log is a great way for a developer to gain insight into the software. A log can be as simple as a RAM buffer, a file written to external flash or as complex as encoded data transmitted to a remote location. In any case, a log file is a great way to glean insights for debugging and system analysis.
Tip #4 – Use advanced breakpoints
Developers are familiar with using standard break points that can be turned on by simply double clicking on the left margin of a line of code. Many IDE’s have far more advanced breakpoint capabilities that are rarely utilized. An example of an advanced break point is setting a line to break when a variable reaches a certain value. The use of advanced break points can drastically decrease debugging time and make difficult to catch bugs far easier to spot.
Tip #5 – Review the datasheets again
Debugging peripherals can be especially difficult. Modern microcontrollers can have 10’s of registers to setup a single peripheral. The peripheral settings are not always obvious or well documented. Even worse, the details to properly set the up are usually not within just a single datasheet. Bread crumbs are scattered amongst the family, peripheral and sometimes even application notes. Looking at just one is not enough. When hardware is misbehaving review the datasheets again and again.
Tip #6 – Monitor the call stack
Developers will sometimes question how they ever got to a specific line of code in the first place. IDE’s contain a call stack window that can reveal exactly that information. The call stack shows what functions were called and in what order, revealing information that can be very useful for tracing a bug.
Tip #7 – Take a break
Debugging can be a taxing exercise. Diving deep into the workings of software and hardware can give a developer tunnel vision. A developer sometimes needs to step back by either moving on to a different task or by taking a break. Getting away from the system by going for a walk or doing something relaxing will allow the subconscious mind to work on the solution and when its time to start looking at the code again, additional insights will usually follow.
Whether you spend a lot of time debugging or very little, the fact is as embedded software developers it is impossible to avoid. Using the tips in this article can help make debugging a little bit more palatable.