Every developer uses breakpoints to debug their software. It’s fundamental. Double click on the line of code that you want to break program execution on and then let it go (or is it break?). Quite a few developers that I encounter don’t realize that there are different breakpoint mechanisms occurring in the background that provide this critical functionality. In this post, we’ll examine the difference between a hardware and software breakpoint and how it can effect us as developers.
The first breakpoint type that is used and generally preferred is a hardware breakpoint. Every microcontroller has comparators which are part of the debugging module. For example, the ARM Cortex-M microcontrollers can have 2 – 4 comparators in their debugging module. The comparator is set with a program counter value and when a match occurs, a debug event is raised and the program halts. Hardware breakpoints are the fastest and the most used breakpoint.
Hardware breakpoints have a problem. A microcontroller will typically only have 2 – 4 comparators which means once they are used up, no more breakpoints can be added! I can’t tell you how many times I’ve wanted three or more breakpoints in my application only to have to strategically switch in and out which breakpoints are active. It’s annoying and also time consuming. Thankfully, there are also software breakpoints.
A software breakpoint is typically an instruction that temporarily replaces an instruction in RAM that is either an illegal instruction and causes a fault or is designed to cause the application to break. A perfect example is the BKPT instruction in the ARM instruction set. When the CPU reaches this instruction, it halts execution. Software breakpoints can only be used for application code that reside in RAM. The reason is that an instruction is literally swapped out for the breakpoint instruction. Once a developer steps past the BKPT, the originally code that would have executed at that location is ran.
Developers can use a nearly endless number of software breakpoints but the major issue is that again they are designed for code running in RAM. On a modern microcontroller such as an ARM Cortex-M, the odds are that the code is executing from flash. This brings us to a third breakpoint type, the flash breakpoint.
Flash breakpoints allow a developer to create unlimited breakpoints for applications that are running from flash. Just like a regular software breakpoint, a flash breakpoint has the ability to have a nearly endless number of breakpoints. They also can work on a microcontrollers internal and external flash memory! An example debugger that has this capability is the Seggar J-Link (usually the Pro or Ultra+ version but I understand licenses can be purchased for other version as well). There are numerous methods that debugger vendors use to create flash breakpoints and the best are nearly as fast as a typical hardware breakpoint.
From a developers standpoint, which breakpoint type that is used almost doesn’t matter. It’s important for developers to understand though the breakpoint type that is being used and the maximum number of hardware breakpoints that their system is capable of. Purchasing a high quality, professional debugger is always a great idea to ensure that the necessary number of breakpoints are available and that they are fast enough for the application at hand. If that isn’t an option, careful microcontroller selection can also help make sure that you maximize how many hardware breakpoints are available to you.