嵌入式系统中的硬件断点与软件断点

Eng*_*999 4 embedded debugging breakpoints interrupt jtag

我的理解是插入软件断点涉及用软件中断指令替换要执行的代码中的下一条指令,该指令将导致 CPU 在到达该指令时停止。

硬件断点涉及将要执行的断点之后的下一条指令的地址放入寄存器中,当地址匹配时,通过使用硬件比较器,这将导致 CPU 停止(如果我错了,请纠正我)。

我感到困惑的是,例如,在使用硬件调试器通过 JTAG 调试电路板时,我们是否只使用硬件断点?或者 JTAG 也可以使用软件断点吗?

GDB 仅与软件断点一起使用,还是也可以与 JTAG 结合使用?对不起,如果问题有点宽泛。

Cli*_*ord 5

如果我错了,请纠正我

断点设置指令上,而不是在它之后——中断发生指令执行之前,而不是之后——否则在跳转、调用或分支指令上设置断点将失败。

“例如,当使用硬件调试器通过 JTAG 调试电路板时,我们是否只使用硬件断点?

JTAG 是片上调试的简单通信接口(并用于其他目的,例如在线存储器和 FPGA 编程和边界扫描)。

例如,虽然它可能因 ARM Cortex-M 上的架构而异,但您可以从目标代码访问片上调试寄存器并设置硬件断点。Yoiu 还可以使用 BKPT 指令(而不是您建议的 SWI)在您的代码中放置软件断点。

或者 JTAG 也可以使用软件断点吗?

正如我所说,JTAG只是片上调试的通信接口,但是通过片上调试,您可以直接设置任何RAM内容,因此运行在开发主机上的JTAG连接的调试器软件可以临时修改RAM中的代码设置软件断点(通过用 BKPT 替换目标指令,然后当断点被击中时,恢复到原始指令以便可以执行。软件断点对于从 ROM 运行的代码并不是那么简单,尽管一些调试器支持无限制的 ROM 断点(有价) - 此类硬件的制造商不一定会宣传他们用于执行此操作的方法。

在 JTAG 和片上调试在低端器件上广泛使用之前,使用了在线仿真和 ROM 仿真器等技术。这些通常是昂贵且复杂的解决方案。

GDB 仅与软件断点一起使用,还是也可以与 JTAG 结合使用?

GDB 可以以多种方式使用。它需要一个“调试存根”——一个将调试器软件映射到可用硬件的软件层——其性质将取决于所使用的调试接口和目标设备。例如,当使用 UART 或以太网端口时,存根实际上是在目标本身上运行的代码(例如 Linux 的gdbserver)。在这种情况下,它不太可靠,因为软件错误可能会阻止调试端口驱动程序实际运行,尤其是在缺乏 MMU 保护的目标中。更简单的 JTAG 设备通过在开发主机上运行的存根(例如常用的 OpenOCD 软件)与 GDB 连接。更昂贵的 JTAG 调试硬件可能会在 JTAG 硬件本身上运行存根——例如 Abatron 的 bdi2000。无论哪种方式,调试存根都可以根据目标功能使用硬件和软件断点。


Bab*_*jan 5

断点定义

在本文的上下文中,让我们就断点的统一定义达成一致。这里讨论的断点是我们希望处理器停止的程序位置,以便我们可以进行某种调试。可能还有其他类型的断点,例如由数据访问触发的断点,但在本文中,我们将仅讨论程序断点,即每次遇到该代码时我们希望停止的应用程序代码中的位置。

硬件与软件断点

硬件断点和软件断点有什么区别?嗯,显而易见的答案是“硬件断点在硬件中实现”和“软件断点在软件中实现”。但这究竟是什么意思,它的后果是什么?为什么我会选择一个而不是另一个?

硬件断点

硬件断点实际上是由集成到设备中的特殊逻辑实现的。您可以将硬件断点视为一组连接到程序地址总线的可编程比较器。这些比较器被编程为一个特定的地址值。当代码正在执行,并且程序地址总线上地址中的所有位都与编程到比较器中的位匹配时,硬件断点逻辑会生成一个信号给 CPU 以暂停。使用硬件断点的好处是可以在任何类型的内存中使用。在讨论了软件断点之后,这可能更有意义。当我们讨论软件断点时,我们会发现它们只能在易失性内存中使用。无论正在执行的代码是在 RAM 还是 ROM 中,都可以使用硬件断点,因为对于硬件断点逻辑,没有区别。它只是匹配 PAB 上的一个地址,并在找到一个地址时停止 CPU。HWBP 的缺点是,因为它们是在硬件中实现的,所以可用的数量有限。可用的 HWBP 数量因架构而异,但在大多数情况下,只有 2-8 个可用。确定设备有多少个的最简单方法是在 CCS 中连接到它并继续设置 HWBP,直到您收到一条错误消息,指出没有可用的 HWBP。可用的 HWBP 数量因架构而异,但在大多数情况下,只有 2-8 个可用。确定设备有多少的最简单方法是在 CCS 中连接到它并继续设置 HWBP,直到您收到一条错误消息,指出没有可用的 HWBP。可用的 HWBP 数量因架构而异,但在大多数情况下,只有 2-8 个可用。确定设备有多少个的最简单方法是在 CCS 中连接到它并继续设置 HWBP,直到您收到一条错误消息,指出没有可用的 HWBP。

软件断点

如前所述,软件断点是在软件中实现的。但这是怎么做的呢?实际上有两种不同的实现。某些设备在其操作码定义中保留了一个指定位,用于指示软件断点。例如,在 C6000 系列的一种架构中,所有指令的长度均为 32 位,而第 28 位保留用于指示软件断点,因此该指令集中的所有指令都将第 28 位设为零。在这种情况下,当在 CCS 中设置软件断点时,它实际上会修改该位置处指令的操作码并将第 28 位设置为 1。然后仿真逻辑监控程序操作码,以便在第 28 位为 1 时,发生这种情况时会停止 CPU。请注意,这是少数情况。大多数架构不会这样做。原因是它限制了指令集的灵活性。此外,它不适用于具有可变长度指令的体系结构,因此它也限制了代码密度。实现软件断点的更流行的方式也复杂得多。在这种情况下,有一个指定的断点操作码。通常,操作码是 8 位。每当设置断点时,该位置指令的前 8 位将被删除并替换为该 8 位断点操作码。然后将指令的原始 8 位存储在断点表中。每当遇到断点时,CPU 就会暂停,CCS 会用指令的原始 8 位替换断点操作码。当重新开始执行时,CCS 必须做一些诡计,因为实际 CPU 流水线中的指令是不正确的。它仍然具有断点操作码。因此,CCS 会刷新 CPU 管道,然后将其中挂起的指令重新提取到其原始状态,下一个要执行的函数是设置断点的函数。同时,CCS 使用断点操作码在该位置重新加载指令,以便下次遇到此代码时,它会再次暂停。SWBP 的优点是它们的数量不受限制,因此您可以将它们放在任意多个位置。缺点是不能将它们放在非易失性存储器中,如 ROM/FLASH 等,因为 CCS 无法将操作码写入该位置。下一个要执行的函数是设置断点的函数。同时,CCS 使用断点操作码在该位置重新加载指令,以便下次遇到此代码时,它会再次暂停。SWBP 的优点是它们的数量不受限制,因此您可以将它们放在任意多个位置。缺点是不能将它们放在非易失性存储器中,如 ROM/FLASH 等,因为 CCS 无法将操作码写入该位置。下一个要执行的函数是设置断点的函数。同时,CCS 使用断点操作码在该位置重新加载指令,以便下次遇到此代码时,它会再次暂停。SWBP 的优点是它们的数量不受限制,因此您可以将它们放在任意多个位置。缺点是不能将它们放在非易失性存储器中,如 ROM/FLASH 等,因为 CCS 无法将操作码写入该位置。

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