Hardware breakpoints vs Software breakpoints in embedded systems
Asked Answered
D

2

6

My understanding is that inserting software breakpoints involves replacing the next instruction in code to be executed by a software interrupt instruction which will cause the CPU to halt when it reaches that instruction.

Hardware breakpoints involve putting the address of the next instruction after the breakpoint to be executed into a register and when the addresses match, via the use of a hardware comparator, this then causes the CPU to halt (Correct me if i'm wrong).

What i'm confused about is, do we only use hardware breakpoints when using a hardware debugger to debug a board via JTAG for example? Or can JTAG use software breakpoints also?

Is GDB only used with software breakpoints, or can it be used also in conjunction with JTAG? Sorry if the question is a bit broad.

Debi answered 10/4, 2019 at 21:52 Comment(0)
F
6

"correct me if I'm wrong"

A breakpoint is set on the instruction, not after it - the break occurs before the instruction is executed, not after - otherwise setting a breakpoint on a jump, call or branch instruction would fail.

"do we only use hardware breakpoints when using a hardware debugger to debug a board via JTAG for example?"

JTAG is a simple communication interface to the on-chip debug (and is used for other purposes such as in-circuit memory and FPGA programming and boundary-scan for example).

While it may vary between architectures on ARM Cortex-M for example, you can access the on-chip debug registers from the target code and set hardware breakpoints. Yoiu can also place software break points in your code using the BKPT instruction (as opposed to a SWI as you suggest).

Or can JTAG use software breakpoints also?

As I said, JTAG is just a communication interface to the on-chip debug, however through the on-chip debug, you can directly set any RAM content, so the JTAG connected debugger software running on the development host can temporarily modify code in RAM to set a software breakpoint (by replacing the target instruction with a BKPT, then when the breakpoint is hit, reverting back to the original instruction so it can be executed. Software breakpoints are not so straightforward for code running from ROM, though some debuggers support unlimited ROM breakpoints (for a price) - the manufacturers of such hardware do not necessarily publicise the methods they use to do that.

Before JTAG and on-chip debug became widely available on evebnlow-end parts, technologies such as In-Circuit Emulation and ROM emulators were used. These were generally expensive and complex solutions.

Is GDB only used with software breakpoints, or can it be used also in conjunction with JTAG?

GDB can be used in a number of ways. It requires a "debug stub" - a software layer mapping the debugger software to the available hardware - the nature of which will depend on the debug interface and target device used. When using a UART or Ethernet port for example, the stub is actually code running on the target itself (such as Linux's gdbserver). In that case it is less reliable since software errors may prevent the debug port driver from actually running especially in targets lacking MMU protection. Simpler JTAG devices interface with GDB through a stub running on the development host, for example the commonly used OpenOCD software. More expensive JTAG debug hardware may run the stub on the JTAG hardware itself - such as Abatron's bdi2000 for example. Either way the debug stub will be able to use hardware and software breakpoints depending on the target capabilities.

Fenny answered 10/4, 2019 at 22:53 Comment(2)
Thanks for that. In terms of single-stepping through the code, how would that work?Debi
@Debi Single stepping at the instruction level is a built-in capability of the on-chip debug unit . Step- over and step-out functionality uses a temporarily set break point. Source level stepping will use either a sequence of instruction steps and breakpoints as necessary.Fenny
A
10

Breakpoint Definition

In the context of this article, let's agree on a unified definition of a breakpoint. The breakpoints discussed here are Program locations where we want the processor to halt so that we can do some sort of debugging. There could be other types of breakpoints, such as ones that are triggered by a data access, but in this article, we will discuss only Program Breakpoints, locations in our application code where we want to halt every time that code is encountered.

Hardware vs. Software Breakpoints

What's the difference between a hardware and a software breakpoint? Well, the obvious answer is "A hardware breakpoint is implemented in hardware" and "A software breakpoint is implemented in software". But what exactly does that mean, and what are the ramifications of it? Why would I choose one over the other?

Hardware Breakpoints

A Hardware Breakpoint is really implemented by special logic that is integrated into the device. You can think of a hardware breakpoint as a set of programmable comparators that are connected to the program address bus. These comparators are programmed with a specific address value. When the code is executing, and all of the bits in the address on the program address bus match the bits programmed into the comparators, the Hardware breakpoint logic generates a signal to the CPU to Halt. The advantage of using a hardware breakpoint is that it can be used in any type of memory. This might make more sense after Software breakpoints are discussed. When we discuss software breakpoints, we will find that they are only usable in Volatile memory. Hardware Breakpoints can be used regardless of whether the code being executed is in RAM or ROM, because to the hardware breakpoint logic, there is no difference. It's just matching an address on the PAB and halting the CPU when it finds one. The disadvantage of the HWBP is, because they are implemented in hardware, there are a limited number available. The number of HWBPs available differ from architecture to architecture, but in most cases there are only 2-8 available. The simplest way to figure out how many a device has is to connect to it in CCS and keep setting HWBPs until you get an error message that there are none available.

Software Breakpoints

As mentioned, a Software Breakpoint is implemented in software. But how is that done? There are actually a 2 different implementations. Some devices reserve a specified bit in their opcode definition that indicates a Software breakpoint. As an example, in one architecture of the C6000 family, all instructions are 32 bits long, and bit 28 is reserved to indicate a software breakpoint, so all instructions in that instruction set have bit 28 as a zero. In this case, when a software breakpoint is set in CCS, it will actually modify the opcode of the instruction at that location and set bit 28 to a 1. The Emulation logic then monitors the Program Opcode for whenever bit 28 is a 1, and halts the CPU when that occurs. Note that this is a minority case. Most architectures don't do it this way. The reason is that it limits the flexibility of the instruction set. Also, it doesn't work for architectures that have variable length instructions, so it also limits code density. The more popular way of implementing a software breakpoint is also much more complex. In this scenario, there is a specified breakpoint opcode. Typically, the opcode is 8-bits. Whenever a breakpoint is set, the leading 8 bits of the instruction at that location are removed and replaced with this 8-bit breakpoint opcode. The original 8-bits of the instruction are then stored in a breakpoint table. Whenever a breakpoint is encountered, the CPU halts and CCS replaces the breakpoint opcode with the original 8-bits of the instruction. When execution is restarted, CCS must do a bit of trickery because the instruction in the actual CPU pipeline isn't correct. It still has the breakpoint opcode. So CCS flushes the CPU pipeline and then re-fetches the instructions that were pending in them to their original state, with the next function to be executed being the one where the breakpoint was set. At the same time, CCS re-loads the instruction at that location with the breakpoint opcode so that the next time this code is encountered, it will again halt. The advantage of the SWBP is that there is an unlimited number of them, so you can put them in as many places as you like. The disadvantage is that you can't put them in non-volatile memory like ROM/FLASH, etc, because CCS can't write the opcode to the location.

http://processors.wiki.ti.com/index.php/How_Do_Breakpoints_Work

Amateur answered 26/4, 2019 at 12:46 Comment(1)
This is copied word for word from the link you provided.Lamblike
F
6

"correct me if I'm wrong"

A breakpoint is set on the instruction, not after it - the break occurs before the instruction is executed, not after - otherwise setting a breakpoint on a jump, call or branch instruction would fail.

"do we only use hardware breakpoints when using a hardware debugger to debug a board via JTAG for example?"

JTAG is a simple communication interface to the on-chip debug (and is used for other purposes such as in-circuit memory and FPGA programming and boundary-scan for example).

While it may vary between architectures on ARM Cortex-M for example, you can access the on-chip debug registers from the target code and set hardware breakpoints. Yoiu can also place software break points in your code using the BKPT instruction (as opposed to a SWI as you suggest).

Or can JTAG use software breakpoints also?

As I said, JTAG is just a communication interface to the on-chip debug, however through the on-chip debug, you can directly set any RAM content, so the JTAG connected debugger software running on the development host can temporarily modify code in RAM to set a software breakpoint (by replacing the target instruction with a BKPT, then when the breakpoint is hit, reverting back to the original instruction so it can be executed. Software breakpoints are not so straightforward for code running from ROM, though some debuggers support unlimited ROM breakpoints (for a price) - the manufacturers of such hardware do not necessarily publicise the methods they use to do that.

Before JTAG and on-chip debug became widely available on evebnlow-end parts, technologies such as In-Circuit Emulation and ROM emulators were used. These were generally expensive and complex solutions.

Is GDB only used with software breakpoints, or can it be used also in conjunction with JTAG?

GDB can be used in a number of ways. It requires a "debug stub" - a software layer mapping the debugger software to the available hardware - the nature of which will depend on the debug interface and target device used. When using a UART or Ethernet port for example, the stub is actually code running on the target itself (such as Linux's gdbserver). In that case it is less reliable since software errors may prevent the debug port driver from actually running especially in targets lacking MMU protection. Simpler JTAG devices interface with GDB through a stub running on the development host, for example the commonly used OpenOCD software. More expensive JTAG debug hardware may run the stub on the JTAG hardware itself - such as Abatron's bdi2000 for example. Either way the debug stub will be able to use hardware and software breakpoints depending on the target capabilities.

Fenny answered 10/4, 2019 at 22:53 Comment(2)
Thanks for that. In terms of single-stepping through the code, how would that work?Debi
@Debi Single stepping at the instruction level is a built-in capability of the on-chip debug unit . Step- over and step-out functionality uses a temporarily set break point. Source level stepping will use either a sequence of instruction steps and breakpoints as necessary.Fenny

© 2022 - 2024 — McMap. All rights reserved.