1

我正在使用 STM32 Cube IDE,我经常收到一个错误对话框,上面写着:

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

我知道我使用的 ARM Cortex M0+ 仅支持 4 个硬件断点,因此会出现错误,但这通常还不够。我该如何解决这个问题,并设置超过 4 个断点?

请注意,我以前使用过 STM8(使用 IAR EWB),这是一个更受限制的 MCU,但我可以使用任意数量的断点。

4

2 回答 2

0

ARM 调试外设的硬件断点数量有限。

一些调试探针(例如 SEGGER J-Link)可以通过插入 bkpt 指令来设置“软件”断点并即时重新编程闪存。__BKPT()您可以使用内在函数设置自己的软件断点。

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

如果您使用 stlink-V2,您可以将其转换为 Segger,并通过使用此链接中的软件从无限断点和更快的调试中受益:https ://www.segger.com/products/debug-probes/j-link /models/other-j-links/st-link-on-board/

于 2021-01-05T10:37:09.637 回答
0

除了硬件断点外,软件断点也可用于中断调试器。仅当代码放置在 RAM 中时,调试器才支持这一点。这通常根本不实用。

作为一种生活黑客,可以做的是制作breakpoint()包含硬件断点的函数。现在,无论在哪里调用此函数,都会激活断点:

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);
}

调试器现在将停止在breakpoint(). 要查看断点的实际位置,必须先跳出。

这种技术为单步等交互释放了硬件断点,并且可用的 4 个断点通常就足够了。

笔记:

  • breakpoint()函数的另一种选择是使用__asm("BKPT #0") ,它进入调试器。不幸的是,没有办法跳过这条指令(在 STM32/GDB 上测试),所以它实际上就像一条 HALT 指令。它可用于在故障条件或未使用的中断中放置断点。
  • 省略时,该breakpoint()功能似乎只工作一次__asm("NOP");
  • 关于STM8,它特别有一个支持字节更新的闪存,所以它可以以非常类似于RAM的方式工作。调试器可以根据需要使用它来插入软断点。
  • 不过,STM8 只有 2 个断点寄存器,它们可能专门用于单步执行。
  • 其他更强大的 ARM Cortex MCU 可以有 6 或 8 个硬件断点。
  • GDB(和其他调试器)在处理断点的方式上可能会更聪明一些。例如,当您在一个函数中有多个断点时,通常不可能在到达某个断点之前先到达某个断点。在某些常见的调试场景中,这可能会有很长的路要走。
于 2021-01-04T17:57:36.783 回答