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

时间:2019-04-10 21:52:57

标签: debugging embedded interrupt breakpoints jtag

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

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

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

GDB是仅与软件断点一起使用,还是可以与JTAG一起使用?很抱歉,这个问题有点广泛。

2 个答案:

答案 0 :(得分:3)

  

如果我错了,请纠正我”“

在指令上设置断点,而不是在其后-在指令执行前 发生断点,而不是在执行后-否则在跳转时设置断点,调用否则分支指令将失败。

  

例如,当使用硬件调试器通过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。无论哪种方式,调试存根都将能够根据目标功能使用硬件和软件断点。

答案 1 :(得分:0)

断点定义

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

硬件与软件断点

硬件和软件断点之间有什么区别?好吧,显而易见的答案是“在硬件中实现硬件断点”和“在软件中实现软件断点”。但是,这到底是什么意思,其后果是什么?为什么我要选择一个?

硬件断点

硬件断点实际上是通过集成到设备中的特殊逻辑实现的。您可以将硬件断点视为连接到程序地址总线的一组可编程比较器。这些比较器用特定的地址值编程。当代码正在执行并且程序地址总线上地址中的所有位与比较器中编程的位匹配时,硬件断点逻辑会向CPU产生信号以暂停。 使用硬件断点的优点是可以在任何类型的内存中使用它。在讨论了软件断点之后,这可能更有意义。当我们讨论软件断点时,我们会发现它们仅在易失性内存中可用。无论执行的代码是在RAM还是ROM中,都可以使用硬件断点,因为对于硬件断点逻辑而言,没有区别。它只是匹配PAB上的地址,并在找到地址时暂停CPU。 HWBP的缺点是,由于它们是在硬件中实现的,因此可用数量有限。可用的HWBP的数量因体系结构而异,但是在大多数情况下,只有2-8个可用。确定设备数量的最简单方法是在CCS中连接到该设备,并继续设置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无法将操作码写入该位置。

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