【问题标题】:Floating point operations in interrupt handler (PowerPC, VxWorks)中断处理程序中的浮点操作(PowerPC、VxWorks)
【发布时间】:2011-07-06 13:17:27
【问题描述】:

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

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

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

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

(解决方法是将自上次中断以来的“滴答声”转换为自上次中断以来的“时间”,直到代码超出处理程序,因为它似乎可以很好地处理长整数操作。)

【问题讨论】:

  • 不能用 64 位定点值代替吗?应该够大了……
  • 正如我所提到的,这就是解决方法。一般来说,我不会在中断处理程序中使用浮点操作,因为它们往往需要大量操作才能完成,并且中断处理程序需要快速。我的问题实际上是“为什么它不起作用”而不是“我应该怎么做”。后者我理解,但前者让我大吃一惊。
  • 它应该可以工作,没有什么神奇或特别之处,应该和任何其他变量类型或结构一样工作。我会反汇编编译器生成的内容,以了解它将值放在哪里以及另一端在哪里获取值,将其与传递无符号整数或其他东西进行比较,然后查看断开连接。
  • 不具体了解 PowerPC,但保存浮点状态可能很昂贵,并且通常在需要时才进行。如果一直这样做,中断响应时间会受到严重影响。

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


【解决方案1】:

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

            我想你会发现this 的文章很有趣。也许您遇到了浮点异常。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-08-31
              • 1970-01-01
              • 2011-07-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-09-25
              • 1970-01-01
              相关资源
              最近更新 更多