【问题标题】:How to resolve: failed to insert all hardware breakpoints; you may have requested too many hardware breakpoints/watchpoints如何解决:插入所有硬件断点失败;你可能请求了太多的硬件断点/观察点
【发布时间】:2021-04-10 12:44:08
【问题描述】:

我正在使用 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,但我可以使用任意数量的断点。

【问题讨论】:

    标签: stm32 breakpoints keil atmelstudio stm32cubeide


    【解决方案1】:

    除了硬件断点,软件断点也可以用来中断调试器。仅当代码放置在 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(和其他调试器)在处理断点的方式上可能会更聪明一些。例如,当您在一个函数中有多个断点时,通常不可能在到达某个断点之前 到达它上面的断点。在某些常见的调试场景中,这可能会大有帮助。

    【讨论】:

    • 1.一些调试软件足够聪明——例如,SEGGER
    • 2.如果您有 bkpt 指令和 __BKPT() 内在函数以便在 C 或 C++ 程序中使用,我认为使用这种不方便的“解决方法”没有任何意义。
    • 4.当断点未设置(分支、管道刷新、缓存内存失效)时,使用此函数会更改代码的时序。正如我所写,它根本不需要。
    【解决方案2】:

    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/

    【讨论】:

    • 我测试了这个(在STM32+GDB+ST-Link上),它不起作用。为什么SEGGER(硬件)会有所作为? GDB 是这里的猪,我希望改进。
    • @user103185 Segger 有自己的 gdbserver。它不仅是硬件,还有软件。请参阅我修改后的答案。
    • @user103185 我将它(stm32 编程)作为我的白天工作,多年来使用 Segger 调试器探针,并且在 ARM uCs 编程方面拥有丰富的经验。
    • 接下来的问题是 GDB 是否有错误(Segger 解决了它),或者 ST-Link 驱动程序有,应该修改。
    • @user103185 这不是错误,而是 Segger 功能
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 2019-09-01
    • 2015-05-31
    • 2013-04-28
    • 1970-01-01
    • 2012-04-07
    相关资源
    最近更新 更多