我们正在尝试将遗留应用程序从旧的单片RTOS移植到PowerPC 8360上的基于unix的RTOS。在旧系统中,我们的大代码库依赖于1/0返回零,0/0返回零。现在在新的操作系统中,1/0返回inf,0/0返回NaN,这会破坏我们的应用程序。我们尝试过使用FPSCR寄存器但没有结果。
其次,如果有办法改变它,那么改变是否会影响我们的申请流程而不影响整个系统?我们不想更改系统中其他应用程序的div / 0行为。
预测不可避免的“为什么你这样做”这个问题,我们必须保留以前的行为,所以改变应用程序实际上不会被零除以是不可能的。这是我们的痛处,所以请不要问。提前谢谢!
答案 0 :(得分:3)
注意:自从我研究这种东西以来已经有一段时间了。希望我的回答是在球场。
你需要捕获发生这种情况时发生的div-0异常 - 我相信MSR.FE0
和MSR.FE1
以及FPSCR.VE
和FPSCR.ZE
都需要被操纵以确保以你想要的方式处理。
所以,一旦你完成了设置和工作,你需要:
控制这些场景(0/0和1/0)的异常处理。在我使用的大多数小型实时内核中,所有源代码都可用,我会知道该怎么做。不确定您的RTOS是什么或者您拥有多少控制权。如果它是一个“更重量级”的操作系统,它可能不会让你摆弄异常处理程序逻辑。
我认为0/0
将触发“无效操作”异常(FPSCR.VE
),而1/0
将触发IEEE浮点零分割异常(FPSCR.ZE
)。
如果您收到无效操作例外,则需要确定原因是0/0
还是其他原因。使用0/0
,FPSCR.VXZDZ
将被设置(我认为)。还有其他方法可以触发此异常,因此FPSCR
是您的朋友。
如果您获得IEEE FP div-0异常,则需要确定原因是1/0
还是其他原因(例如2/0
)。我认为为此你必须检查中断上下文的寄存器,以查看在导致异常的除法操作时分子是否为1
。如果您尝试1/0
或2/0
,FPU并不在意,但显然您的应用程序会尝试。
接下来,您需要更改返回的上下文,以便获得所需的结果。这可能类似于更改操作中使用的FP寄存器,以便在从异常&返回时返回。 FP部门重新尝试,它产生零。例如,设分子0
和除数1
。
然后当你从异常中返回时,你应该得到你想要的结果。对不起,我对特定的寄存器和值很生气,我希望这足以完成工作。
您还询问了有关为您的申请流程选择性地启用此行为的问题。我以前必须做这样的事情,但更多的是在平面地址空间,“单进程,多线程”类型的内核(其中每个任务实际上是一个线程,都在同一个平面地址空间中运行)。我已经做了几种不同的方式,这里有一些可能适合你的想法:
在异常处理程序中,检查进程ID /任务ID,如果它是您的应用程序进程,请以特殊方式处理它,否则以标准“系统”方式处理它。
或者,在上下文切换到您的应用程序时,为此异常安装“特殊”处理。在应用程序进程之外的上下文切换中,将其替换为标准处理。请注意,应用程序本身将无法执行此操作,您必须使用内核来执行此操作(可能存在可以使用的上下文切换挂钩/标注,否则您可能正在修改内核源代码)。
我之前和之后继承了这样的遗留代码。我感觉到你的痛苦。你想要对安装了这种骨头行为的人握拳,但是现在握拳并不能帮助你运送产品。你需要一个解决方案。祝你好运。
答案 1 :(得分:0)
如果您要转向符合POSIX标准的系统(如QNX或Linux),您可能需要尝试在应用程序中添加代码以捕获SIGFPE并处理其中的条件。
不知道你正在使用什么语言,(更重要的是)不担心长时间捕捉信号,我不确定你将如何添加代码,但也许是这个问题的答案({{ 3}})会有所帮助。