在 vxworks 中,每个任务都应该使用 VX_FP_TASK 选项生成吗?

发布于 2024-08-21 00:28:35 字数 214 浏览 4 评论 0原文

在 vxworks 中,每个任务都应该使用 VX_FP_TASK 选项生成吗?

如果您的任务使用任何浮点运算,则需要 VX_FP_TASK 选项。但是一个人如何预测未来——我的意思是,一个人如何知道他/她是否会使用浮动呢?

在修复任何错误或引入新代码时,程序员是否应该发现哪些所有任务都会受到他/她的代码更改的影响,以及该任务是否是通过此选项生成的?这是非常乏味的。我错过了什么吗?

In vxworks, should every task be spawned with VX_FP_TASK option?

The VX_FP_TASK option is required if your task uses any floating point operations. But how does one predict the future - i mean, how can one know if he/she will use float or not?

While fixing any bug or introducing new code, should the programmer find which all tasks will get effected by his/her code chage and if that task is spawned with this option or not? This is very tedious. Am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏尔 2024-08-28 00:28:35

VX_FP_TASK 强制任务上下文切换包含 FP 寄存器。这会增加上下文切换时间。如果在你的申请时间内,即使有这样的开销也能满足截止日期和性能目标,那么我建议这样做没有什么问题。没有 VX_FP_TASK 可能会被视为一种优化,只有在必要时才需要谨慎应用。因此,如果默认情况是使用 VX_FP_TASK,则在可能需要优化性能的少数情况下,您可能需要执行较少的检查,因为通常不需要优化来实现所需的结果。如果上下文切换的性能开销会影响你的项目的成败,那么它在任何情况下都可能是微不足道的。

另一方面,虽然在嵌入式系统中 FPU 变得越来越普遍,但由于传统上缺乏硬件 FP 支持,嵌入式系统设计人员通常将 FP 作为例外而不是规则。因此,一种解决方案是制定一项内部设计规则,即未经正式论证和签核,不得使用浮点:即浮点的使用必须在设计中,而不是程序员决定。检查通常是扫描源代码中的 floatdoublemath.h 的简单情况。 (因为如果代码中没有出现这些情况,可能很难使用浮点)。例如,您可以添加预构建静态分析检查来查找这些内容并标记警告。

在许多应用中,可以进行设计,使 FP 数学运算自然地局限于特定任务。然而,当有人选择将原本用于这些任务之一的现有函数用于另一个非 FP 安全的任务时,就会出现问题。这可能很难发现;解决这个问题的方法是使用浮点函数,并且可以在其他任务中使用这些函数来包含使用 taskOptionsGet() 测试任务选项的调试 ASSERT。

因此,扫描 floatdoublemath.h 的使用,并向使用这些函数的函数添加 ASSERT 检查的组合将可能会保护您免于在代码维护中引入错误。

[2010 年 2 月 14 日添加]

尽管复杂的宏通常是一件坏事,但我建议以下内容可能有用(如上所述):

#if NDEBUG
    #define ASSERT_FP_SAFE() ((void) 0)
#else
    #define ASSERT_FP_SAFE() do{ int opt; \
                                 STATUS st = taskGetOptions( taskIdSelf(), &opt ); \
                                 assert( st == OK && (opt & VX_FP_TASK) != 0 ) ; \
                               }while(0) ;
#endif

该宏应该插入到任何使用 float 或 double 的函数中,或包括 或您可能使用的任何其他 FP 相关库(您可以通过文本搜索实现)。当从非 FP 任务调用此类函数时,断言将失败。

请注意,对 taskGetOptions() 返回的检查将捕获中断上下文中浮点的使用。尽管如果断言发生在中断中,您可能不会得到任何输出。调用 logMsg() 可能更安全;你可以使用 if st != OK ,否则使用 assert() 。

不幸的是,这是一个运行时断言,因此必须运行代码才能对其进行检查。如果能通过静态分析来检测就更好了,但我想不出一个简单的方法。但是,如果您还使用代码覆盖率分析,那么这可能就足够了。即使您确实选择将所有任务设置为 VX_FP_TASK,这也可能是一个好习惯;这样,如果有人忘记做其中一项或另一项,您就有机会发现。

VX_FP_TASK forces the task context switch to include the FP registers. This increases context switch time. If in your application time, deadlines and performance targets can be met even with this overhead, then there is little problem I suggest is doing this. Not having VX_FP_TASK might be considered an optimisation to be applied with care only if and when necessary. So if the default case is to use VX_FP_TASK, you will probably have less checking to do in the few cases where you might need to optimise performance, since often optimisation is unnecessary to achieve the required results. If the context switch performance overhead this imposes makes or breaks your project, it may be marginal in any case.

On the other hand although in embedded systems FPUs are becoming more common, it is also common for embedded systems designers to use FP as the exception rather than the rule because of the traditional lack of hardware FP support. One solution is therefore to have an in-house design rule that floating point shall not be used without formal justification and sign-off: i.e. use of floating point must be in the design, rather than a programmer decision. Checking is generally a simple case of scanning the source for float, double, and math.h. (since it is probably difficult to use floating point without either of these occurring in the code). You might for example add a pre-build static analysis check that looks for these and flags a warning.

In many applications it is possible to design so that FP math operations are naturally confined to specific tasks. A problem occurs however when someone chooses to use an existing function intended for use in one of these tasks in another that is not FP safe. This may be difficult to spot; a solution to this is to have functions that use floating point and which may be used in other tasks to include a debug ASSERT that tests the task options using taskOptionsGet().

So a combination of scanning for use of float, double, and math.h, and adding an ASSERT check to the functions that uses these will probably protect you from introducing errors in code maintenance.

[added 2010Feb14]

As much as complex macros are generally a bad thing, I suggest that the following may be useful (as alluded to above):

#if NDEBUG
    #define ASSERT_FP_SAFE() ((void) 0)
#else
    #define ASSERT_FP_SAFE() do{ int opt; \
                                 STATUS st = taskGetOptions( taskIdSelf(), &opt ); \
                                 assert( st == OK && (opt & VX_FP_TASK) != 0 ) ; \
                               }while(0) ;
#endif

This macro should be inserted in any function that uses float or double, or which includes <math.h> or any other FP dependent library you may use (which you can achieve by textual search). The assertion will then fail when such a function is called from a non-FP task.

Note the check of the return from taskGetOptions() will catch use of floating point in interrupt contexts. Although if the assert occurs in an interrupt, you may not get any output. A call to logMsg() may be safer perhaps; you could use that if st != OK and assert() otherwise.

Unfortunately it is a run-time assertion, so the code has to run for it to be checked. It would be better if it could be detected through static analysis, but I cannot think of a simple method. If however you also use code coverage analysis, then this may be sufficient. It may be a good habit even if you do choose to make all tasks VX_FP_TASK; that way if anyone forgets to do one or the other, you have a chance of catching it.

╰つ倒转 2024-08-28 00:28:35

根据经验,我可以给您一个简单的答案:始终使用 VX_FP_TASK 生成任务。特别是如果您的代码可以用于不同的架构。

根据编译器(gnu、diab)、您使用的编译标志和体系结构,浮点寄存器不仅仅可以用于浮点运算。在大多数架构中,FP 寄存器比常规寄存器大,因此它们成为优化代码的完美候选者。

例如,在 PPC603 处理器中,如果您使用 C++ 而不是普通 C,则 FP 寄存器将用于优化,如果您没有在该任务上启用 VX_FP_TASK,则可能会损坏另一个任务的 FP 寄存器,即使它是不做任何计算!

正确的执行比性能更重要,大多数时候,性能的提升并不能证明不启用它所带来的风险是合理的。

如果要确保所有任务都启用该标志,请考虑添加一个钩子,以便在使用 taskCreateHookAdd( ) 创建任务期间始终启用该标志

From experience I can give you a simple answer: Always spawn a task with VX_FP_TASK. Especially if your code could be used for different architectures.

Depending on the compiler (gnu, diab), the compiling flags that you use, and the architechture, the floating point registers can be used for more than just floating point operations. In most architectures FP registers are bigger than regular registers, so they turn into perfect candidates for optimizing code.

For example, in PPC603 processors, if you use C++ instead of plain C, the FP registers will be used for optimization, and if you don't have VX_FP_TASK enabled on that task it could corrupt the FP registers of another task, even though it's not making any calculations!

Correct execution is more important than performance, and most times the performance gain doesn't justify the risk introduced by not enabling it.

If you want to ensure that all tasks have the flag enabled, consider adding a hook that always enables the flag during task creation with taskCreateHookAdd( )

别再吹冷风 2024-08-28 00:28:35

始终使用 VX_FP_TASK!没有它并试图追踪由此产生的不稳定错误的成本令人难以置信昂贵。

ALWAYS use VX_FP_TASK! The cost of not having it, and trying to track down the erratic errors which result is unbelievably expensive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文