1

我们正在尝试将遗留应用程序从旧的单片 RTOS 移植到 PowerPC 8360 上的基于 unix 的 RTOS。在旧系统中,我们的大型代码库变得依赖于 1/0 返回零和 0/0 返回零。现在在新的操作系统中,1/0 返回 inf,0/0 返回 NaN,这会破坏我们的应用程序。我们尝试过使用 FPSCR 寄存器,但没有任何结果。

其次,如果有办法改变它,改变会影响我们的应用程序而不是整个系统吗?我们不想改变系统内其他应用程序的 div/0 行为。

预见到不可避免的“你为什么要那样做”的问题,我们必须保留以前的行为,因此将应用程序更改为实际上不被零除是不可能的。这是我们的痛处,所以请不要问。提前致谢!

4

2 回答 2

3

注意:自从我从事这种工作以来已经有一段时间了。希望我的答案在球场上。

您需要捕获发生这种情况时发生的 div-0 异常——我相信MSR.FE0并且 需要进行操作,以确保以您想要的方式进行MSR.FE1 处理FPSCR.VEFPSCR.ZE

因此,一旦您完成设置并开始工作,您将需要:

  • 控制这些场景(0/0 和 1/0)的异常处理。在我使用的大多数小型实时内核中,所有源代码都可用,我知道该怎么做。不确定您的 RTOS 是什么或您拥有多少控制权。很有可能,如果它是一个“重量级”的操作系统,它不会让你摆弄异常处理程序逻辑。我认为0/0会触发“无效操作”异常(FPSCR.VE),而1/0会触发 IEEE 浮点除零异常(FPSCR.ZE)。

    • 如果您得到 Invalid Operation 异常,您需要确定原因是0/0什么或其他。随着0/0,FPSCR.VXZDZ将被设置(我认为)。还有其他方法可以触发此异常,所以这FPSCR是您的朋友。

    • 如果你得到 IEEE FP div-0 异常,你需要确定原因是1/0什么还是其他什么(例如2/0)。我认为为此,您必须检查中断上下文的寄存器,以查看分子是否1在导致异常的除法运算时。FPU 不在乎您是否尝试了1/0or 2/0,但显然您的应用程序确实如此。

  • 接下来,您需要更改返回的上下文,以便获得所需的结果。这可能类似于更改操作中使用的 FP 寄存器,以便当您从异常返回并重新尝试 FP 除法时,它会产生零。例如,制作分子0和除数1

然后当你从异常中返回时,你应该得到你想要的结果。抱歉,我对特定的寄存器和值生疏了,我希望这足以完成工作。

您还询问了仅为您的应用程序进程选择性地启用此行为。我以前不得不做这样的事情,但更多的是在平面地址空间中,“单进程,多线程”类型的内核(每个任务实际上都是一个线程,都在同一个平面地址空间中运行)。我已经完成了几种不同的方式,这里有一些可能对你有用的想法:

  • 在异常处理程序中,检查进程 ID/任务 ID,如果是您的应用程序进程,则以特殊方式处理,否则以标准“系统”方式处理。

  • 或者,在上下文切换到您的应用程序时,为此异常安装“特殊”处理。在应用程序进程的上下文切换时,将其替换为标准处理。请注意,应用程序本身无法执行此操作,您必须利用内核来执行此操作(可能有一个您可以使用的上下文切换挂钩/标注,否则您可能会修改内核源代码)。

我以前继承过这样的遗留代码,我感到你的痛苦。您想对安装这种愚蠢行为的人挥舞拳头,但现在挥舞拳头并不能帮助您发布产品。你需要一个解决方案。祝你好运。

于 2011-06-24T03:26:04.643 回答
0

如果您要迁移到符合 POSIX 的系统(如 QNX 或 Linux),您可能想尝试在应用程序中添加代码以捕获SIGFPE并处理那里的条件。

不知道您使用的是什么语言,并且(更重要的是)长时间不担心捕获信号,我不确定您将如何添加代码,但也许是这个问题的答案(我如何捕获系统Linux C++ 中的级异常?)将有所帮助。

于 2011-06-24T11:41:13.953 回答