2

I am using STM32 Cube IDE and I frequently get an error dialog that says:

failed to insert all hardware breakpoints; 
you may have requested too many hardware breakpoints/watchpoints

I know the ARM Cortex M0+ I use supports only 4 hardware breakpoints, hence the error, but this is often not enough. How do I work around this, and set more than 4 breakpoints?

Note I have previously worked with the STM8 (with IAR EWB), a much more limited MCU, yet I could use as many breakpoints as I wanted.

user103185
  • 925
  • 2
  • 8
  • 20

2 Answers2

1

Besides hardware breakpoints, software breakpoints can be used to break into the debugger. The debugger supports this only if the code is placed in RAM. This is often not at all practical.

As a life-hack, what can be done instead is to make breakpoint() function which contains a hardware breakpoint. Now wherever this function is called, the breakpoint is activated:

void __attribute__ ((noinline)) breakpoint()
{
    __asm("NOP");     // <---- set a hardware breakpoint here!
    // hello, please Step Out to go to caller location (ex: press Shift-F11)
}

void main()
{
    int x = 1;
breakpoint();             // break into the debugger
    printf("%d\n", x);
    x += 2;
breakpoint();             // break into the debugger, again
    printf("%d\n", x);
}

The debugger will now stop within breakpoint(). To see the actual location of the breakpoint, one must Step Out.

This technique frees up the hardware breakpoints for interactions like single stepping, and the 4 breakpoints available would often be enough.

Notes:

  • an alternative for the breakpoint() function would be to use __asm("BKPT #0") , which enters the debugger. Unfortunately there is no way to Step Over this instruction (tested on STM32/GDB), so it effectively acts like a HALT instruction. It can be used to place breakpoints inside fault conditions or unused interrupts.
  • the breakpoint() function seem to work only once when the __asm("NOP"); is omitted
  • with regard to the STM8, it exceptionally has a flash memory that supports byte updates, so it can act in a way very similar to RAM. A debugger can use this to insert soft breakpoints, and as much as needed.
  • the STM8 has only 2 breakpoint registers, though, which are probably used exclusively for single stepping.
  • other, more powerful, ARM Cortex MCU's can have 6 or 8 hardware breakpoints.
  • GDB (and other debuggers) could probably be a bit smarter in the way they deal with breakpoints. For example when you have several breakpoints in a function, it would often be impossible to hit some breakpoint before hitting the breakpoint above it. This could go a long way in certain common debugging scenarios.
user103185
  • 925
  • 2
  • 8
  • 20
  • 1. Some debug software is smart enough - for example, SEGGER – 0___________ Jan 05 '21 at 10:39
  • 2. I do not see any point of using this inconvenient "workaround" if you have bkpt instruction and `__BKPT()` intrinsic for convenient use in the C or C++ programs. – 0___________ Jan 05 '21 at 10:41
  • 4. Use of this function changes the timings of the code when the breakpoint is not set (branch, pipeline flush, cache memory invalidation). And as I wrote it is not needed at all. – 0___________ Jan 05 '21 at 10:48
0

The ARM debug peripheral has a limited number of the hardware breakpoints.

Some debug probes (SEGGER J-Link for example) can set "software" breakpoints by inserting the bkpt instruction and reprogram the FLASH memory on the fly. You can set your own software breakpoint by using the __BKPT() intrinsic.

#ifdef DEBUG 
#define DEBUGBKPT()     __BKPT()
#else
#define DEBUGBKPT()
#endif

If you use stlink-V2 you can convert it to the Segger and benefit from the unlimited breakpoints and much faster debug by using the software from this link: https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/

0___________
  • 60,014
  • 4
  • 34
  • 74
  • I tested this (on STM32+GDB+ST-Link) and it does not work. why would the SEGGER (hardware) make a difference? GDB is the pig here, and I would love improvements. – user103185 Jan 05 '21 at 13:04
  • @user103185 Segger has its own gdbserver. It is not only the hardware, but also the software. See my amended answer. – 0___________ Jan 05 '21 at 13:19
  • @user103185 I do it (stm32 programming) as my daytime job and for years use Segger debugger probes, and have vast experience in the ARM uCs programming. – 0___________ Jan 05 '21 at 13:24
  • the question then is whether GDB has a bug (and Segger worked around it), or the ST-Link driver has, and it should be amended. – user103185 Jan 05 '21 at 13:28
  • @user103185 it is not a bug it is a Segger feature – 0___________ Jan 05 '21 at 13:48