处理器数据表中列出了许多不同类型的陷阱,例如 BusFault、MemManage Fault、Usage Fault 和 Address Error。
他们的目的是什么?它们如何用于故障处理?
处理器数据表中列出了许多不同类型的陷阱,例如 BusFault、MemManage Fault、Usage Fault 和 Address Error。
他们的目的是什么?它们如何用于故障处理?
陷阱本质上是处理器在检测到指令流中有异常情况时强制执行的子程序调用。(一些处理器将它们变成中断,但这主要只是将更多上下文推送到堆栈上;如果陷阱包括用户地址空间和系统地址空间之间的切换,这会变得更有趣)。
这对于处理很少发生但需要解决的情况很有用,例如除以零。通常,在执行除法指令之前有一对额外的指令来测试除数是否为零是无用的开销,因为从不期望除数为零。因此,架构师让处理器与实际除法并行执行此检查,作为除法指令的一部分,如果除数为零,则使处理器陷入除零例程。另一个有趣的例子是非法内存地址;显然,您不想在使用每个地址之前编写测试代码来检查它。
通常有多种潜在的故障情况,处理器设计将针对每种不同类型的故障将控制传递给不同的陷阱例程(通常设置为向量)。
一旦处理器具有陷阱功能,CPU 架构师就会发现很多用途。一个常见的用途是调试器断点,以及用于执行操作系统调用的陷阱到操作系统。
微处理器具有针对各种故障条件的陷阱。它们是同步中断,允许正在运行的操作系统/软件对错误采取适当的措施。陷阱中断程序流程并设置寄存器位以指示故障。调试器断点也使用陷阱实现。
在典型的计算环境中,操作系统负责处理由用户进程触发的 CPU 陷阱。让我们考虑一下当我运行以下程序时会发生什么:
int main(void)
{
volatile int a = 1, b = 0;
a = a % b; /* div by zero */
return 0;
}
显示一条错误消息,我的盒子仍在运行,就像什么都没发生一样。在这种情况下,我的操作系统处理故障的方法是杀死有问题的进程并用错误消息通知用户Floating point exception
。
内核模式中的陷阱问题更大。如果操作系统本身有错误,则操作系统采取纠正措施并不那么简单。对于系统进程,没有底层保护。这就是为什么有缺陷的设备驱动程序会导致真正的问题。
在裸机上工作时,没有操作系统的舒适保护,情况与上述情况非常相似。实现连续和正确操作的第一个目标是在触发任何陷阱之前捕获所有潜在的陷阱条件,使用断言和更高级别的错误处理程序。将陷阱视为最后一道防线,一个您不想陷入的安全网。
为陷阱处理程序定义行为值得深思,即使它们“不应该发生”。当事情以意想不到的方式出现问题时,它们将被执行,在最极端的情况下是由于宇宙射线改变了 RAM。不幸的是,对于错误处理程序应该做什么,没有一个正确的答案。
代码完成,第 2 版:
最合适的错误处理方式取决于发生错误的软件类型,并且通常更倾向于正确性或稳健性。严格来说,这些术语彼此处于相对的两端。正确性意味着永远不会返回不准确的结果;没有结果比不准确的结果更好。稳健性意味着总是试图做一些可以让软件继续运行的事情,即使这会导致有时结果不准确。
显然,我的操作系统的故障处理在设计时考虑到了稳健性;我可以执行有缺陷的代码并做几乎任何事情而不会导致系统崩溃。仅针对稳健性进行设计将意味着尽可能进行恢复尝试,如果其他所有方法都失败,则重置。如果您的产品是玩具,这是一种合适的方法。
安全关键应用程序需要更多的偏执狂,并且应该支持正确性;当检测到故障时,写入错误日志,关机。我们不希望我们的放射治疗单元从无效的垃圾值中挑选剂量水平。
ARMv7-M(不要与 ARM7 或 ARMv7-A 混淆)Cortex-M3 技术参考手册,它也可能是新 ARM ARM 之一(ARM 架构参考手册)的一部分,其中有一节描述了每个这些故障。
现在,为什么与什么可能是问题的根源。原因通常是为了让你有机会恢复。想象一下,您的机顶盒或电话碰到其中之一,您希望它挂起还是尽可能尝试恢复?除非你预料到这些故障之一(在这种情况下你不应该是这样,x86 系统和它们的一些故障是完全不同的故事)如果你存活足够长的时间来击中其中一个故障,那么你很可能最终会扣动扳机自己(试图通过重置处理器/系统来杀死自己的软件)。您可以浏览长长的列表并尝试找到可以从中恢复的列表。除以零,异常处理程序如何知道导致这种情况的数学错误是什么?一般是不能的。未对齐的加载或存储,处理程序如何知道该代码试图做什么,就像除以零一样,它可能是一个软件错误。未定义的指令,代码进入杂草并执行数据很可能此时您已经走得太远并且无法恢复。处理程序无法修复硬件的任何类型的内存总线故障。
你必须经历每一个错误,并且为每一个错误定义你将如何处理它,你可以解决那个错误的所有方法,以及你可以摆脱或处理这些路径中的每一个的方法。有时您可能能够恢复,否则您需要默认操作,例如,将处理器挂在处理程序中的无限循环中,以便软件工程师(如果有)可以尝试使用调试器进入并找到代码停止。或者有一个看门狗定时器,根据芯片和电路板设计在芯片内部或外部(通常在芯片外部,WDT 将重置整个电路板)。您可能有一些非易失性存储器,您尝试将故障存储在其中,在允许或导致复位之前,执行此操作所需的时间和代码可能会导致您出现另一个故障,具体取决于失败的原因。
简而言之,它们允许您在处理器发生某些事情时执行代码。操作系统有时会使用它们来进行错误恢复。