中断处理程序中的浮点运算(PowerPC,VxWorks)

时间:2011-07-06 13:17:28

标签: c++ embedded vxworks powerpc interrupt-handling

我没有找到任何资源可以完全回答我正在尝试理解的问题,我在一个我正在研究的软件中看到了这个问题,所以我会问这些天才!

首先,我在PowerPC处理器上运行VxWorks。

在尝试调试单独的问题时,我尝试在中断处理例程中抛出一些快速而脏的调试代码。它涉及一个双精度浮点运算来存储一个感兴趣的值(即,自从我看到最后一个中断进入以来已经存在多长时间),我后来在运行线程的处理程序之外使用了它。我没有看到这方面的问题(当然,它需要更长的时间,但时间方面我很快;中断不会太快)但是VxWorks肯定不喜欢它。当它到达那个代码时,它一直崩溃,这是重新启动系统的一个糟糕的崩溃。我花了一些时间来追踪双重操作作为问题的根源,我意识到它甚至不是双重“操作”,即使从中断调用的例程返回一个常量的双重失败也是如此。

在PowerPC(或其他一般体系结构)上,通常会出现在中断处理程序中执行浮点运算并在中断处理程序调用的函数中返回浮点(或其他类型)值的问题吗?我不知道为什么会导致程序崩溃。

(解决方法是延迟将自上次中断后的“滴答”转换为“时间”,因为laster中断直到代码超出处理程序,因为它似乎处理长整数操作就好了。)

6 个答案:

答案 0 :(得分:7)

在VxWorks中,必须在任务创建中指定利用浮点的每个任务,以便在上下文切换期间保存FP寄存器,但仅限于从使用浮点的任务切换时。这允许非浮点任务具有更快的上下文切换时间。

然而,当中断抢占浮点任务时,很可能是FP寄存器未被保存的情况。为此,中断处理程序需要确定哪个任务被抢占以及是否已将其指定为浮点任务;这会使中断延迟更高和更高,这在实时系统中通常是不可取的。

为了使其工作,任何使用浮点的中断例程必须明确地保存和恢复FP寄存器本身。在任何情况下,任何使用浮点的任务都必须这样指定,但如果你只有一个这样的任务就可以侥幸逃脱。

如果浮点任务被抢占,则您的中断将修改该任务正在使用的浮点寄存器值,FP任务恢复时的结果是非确定性的,但包括导致浮点异常 - 如果例如,先前非零寄存器变为零,随后用作除法运算的右手。

然而,在我看来,在这种情况下,浮点运算可能完全没有必要。您的“解决方法”实际上是传统的,最安全且最具确定性的方法,应该被视为您设计的更正,而不是解决方法

答案 1 :(得分:5)

您的ISR是否调用fppSave()/ fppRestore()函数?

如果没有,则ISR会踩踏现有任务可能正在使用的FP寄存器。

具体来说,FP寄存器由PPC架构上的C ++编译器使用(我认为处理throw / catch)。

答案 2 :(得分:0)

在VxWorks中,至少对于PPC架构,浮点运算将导致FP不可用异常。这是因为当发生中断时,MSR中的FP位被清除,因为VxWorks假定不存在FP操作。这加速了ISR /任务上下文切换,因为FP寄存器不必保存/恢复。

话虽这么说,有一段时间我们有一些调试代码,我们需要在中断上下文中进行FP操作。我们将调用特定ISR的VxWorks代码更改为1)设置MSR [FP],执行fpsave调用,调用ISR,执行fprestore调用,然后清除MSR [FP]。这让我们解决了这个问题。

话虽如此,我同意其他人的观点,不应在ISR环境中使用FP操作,因为ISR应该是快速的,FP操作通常不是。

答案 3 :(得分:0)

我在开发裸机应用程序时使用过e300内核,我可以说当发生中断时,内核会关闭FPU,你可以通过检查MSR的FP位来观察。在对浮点寄存器执行任何操作之前,必须通过将1写入MSR的FP位来重新启用FPU。然后根据需要在ISR中对FPU寄存器进行操作。

答案 4 :(得分:0)

VxWorks中的一般假设是不需要由ISR保存和恢复浮点寄存器。主要是因为ISR通常不会弄乱它们。从历史上看,大多数实时任务也没有执行FP,但这显然已经改变了。不明显的是,许多未明确使用浮点的任务仍然使用浮点寄存器。我相信使用C ++编写的代码的任何任务都使用浮点寄存器(至少在某些处理器/编译器上),即使没有明显的浮点运算。这样的任务应该给FP_? (我忘记了确切的拼写)任务属性,导致他们的FP regs在上下文切换期间被保存。

答案 5 :(得分:-1)

我认为你会发现this文章很有趣。也许你正陷入一个浮点异常。

我从未使用过PowerPC,但我对Google很好:P