中断处理程序中的浮点操作(PowerPC, VxWorks)

Floating point operations in interrupt handler (PowerPC, VxWorks)

本文关键字:PowerPC VxWorks 操作 程序 中断处理      更新时间:2023-10-16

我还没有找到任何能准确回答我正在开发的一个软件中的问题的资源,所以我将在这里询问天才!

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

在尝试调试一个单独的问题时,我尝试在中断处理例程中抛出一些快速而肮脏的调试代码。它涉及一个双精度浮点操作来存储感兴趣的值(即,自从我看到最后一个中断进入以来已经多长时间了),稍后我将在正在运行的线程的处理程序之外使用该值。我不觉得这有什么问题(当然,这需要更长的时间,但时间上我有足够的时间;中断不会来得太快)然而,VxWorks肯定不喜欢它。当它到达该代码时,它总是崩溃,其中一个严重的崩溃会重新启动系统。我花了一点时间来追踪双操作作为问题的根源,我意识到它甚至不是双"操作",甚至从中断中调用的例程返回一个常量double都失败了。

在PowerPC(或一般的其他架构)上,是否有一般的问题在中断处理程序中做浮点操作,并在中断处理程序调用的函数中返回浮点(或其他类型)值?我不明白为什么这会导致程序崩溃。

(解决方法是延迟从上次中断到上次中断的"滴答"转换为"时间",直到代码脱离处理程序,因为它似乎处理长整数操作很好。)

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

当中断抢占浮点任务时,很可能不会保存FP寄存器。要做到这一点,中断处理程序需要确定哪个任务被抢占了,以及它是否被指定为浮点任务;这将使中断延迟既高又可变,这在实时系统中通常是不希望的。

因此,为了使其工作,任何使用浮点数的中断例程都必须显式地保存和恢复FP寄存器本身。任何使用浮点数的任务在任何情况下都必须这样指定,尽管如果只有一个这样的任务,也可以这样指定。

如果一个浮点任务被抢占,你的中断将修改该任务正在使用的浮点寄存器值,当FP任务恢复时,其结果是不确定的,但包括导致一个浮点异常——例如,如果一个先前非零的寄存器变为零,并随后被用作除法操作的右手。

然而,在我看来,在这种情况下,浮点运算可能完全没有必要。你的"变通方法"实际上是传统的、最安全的、最确定的方法,应该被看作是对你设计的修正,而不是变通方法

你的ISR调用fppSave()/fppRestore()函数吗?

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

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

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

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

话虽如此,我同意这里其他人的观点,即FP操作不应该在ISR上下文中使用,因为ISR应该是快速的,而FP操作通常不是。

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

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

我想你会对这篇文章感兴趣的。也许你遇到了浮点异常。

我从未使用过PowerPC,但我很擅长使用Google: p