在vxworks中,是否应使用VX_FP_TASK选项生成每个任务?
如果您的任务使用任何浮点运算,则需要VX_FP_TASK选项。但是,如何预测未来 - 我的意思是,如何知道他/她是否会使用浮动?
在修复任何错误或引入新代码时,程序员是否应该发现所有任务都会受到他/她的代码影响,以及是否使用此选项生成该任务?这非常乏味。我错过了什么吗?
答案 0 :(得分:6)
VX_FP_TASK强制任务上下文切换包含FP寄存器。这增加了上下文切换时间。如果在您的应用程序时间内,即使有这个开销也可以满足最后期限和性能目标,那么我建议这样做几乎没有问题。没有VX_FP_TASK可能被视为优化,仅在必要时才小心应用。因此,如果默认情况是使用VX_FP_TASK,那么在可能需要优化性能的少数情况下,您可能需要做的检查较少;因为通常不需要优化来实现所需的结果。如果上下文切换性能开销会导致您的项目成败,那么无论如何它都可能是微不足道的。
另一方面,虽然在嵌入式系统中FPU变得越来越普遍,但由于传统上缺乏硬件FP支持,因此嵌入式系统设计人员通常使用FP作为例外而不是规则。因此,一种解决方案是具有内部设计规则,即在没有正式证明和签字的情况下不得使用浮点:即浮点的使用必须在设计中,而不是程序员的决定。检查通常是扫描float
,double
和math.h
的来源的简单案例。 (因为在代码中没有出现这些中的任何一个可能很难使用浮点数)。例如,您可以添加一个预构建静态分析检查,以查找这些并标记警告。
在许多应用程序中,可以进行设计,使FP数学运算自然局限于特定任务。然而,当有人选择使用旨在用于其中一个任务之一的现有功能而非FP安全时,会出现问题。这可能很难发现;解决方案是使用浮点函数,可以在其他任务中使用,包括使用taskOptionsGet()测试任务选项的调试ASSERT。
因此,扫描使用float
,double
和math.h
以及向使用这些功能的函数添加ASSERT检查的组合可能会保护您免于在代码中引入错误维护。
[已添加2010Feb14]
复杂的宏一般都是坏事,我建议以下内容可能有用(如上所述):
#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()可能更安全;你可以使用它,如果st!= OK和assert()否则。
不幸的是,它是一个运行时断言,因此代码必须运行才能进行检查。如果可以通过静态分析检测到它会更好,但我想不出一个简单的方法。但是,如果您也使用代码覆盖率分析,那么这可能就足够了。即使您选择完成所有任务VX_FP_TASK,这也可能是一个好习惯;这样,如果有人忘记做其中一个,你有机会抓住它。
答案 1 :(得分:3)
根据经验,我可以给您一个简单的答案:始终使用VX_FP_TASK生成任务。特别是如果您的代码可以用于不同的架构。
根据编译器(gnu,diab),您使用的编译标志和架构,浮点寄存器不仅可用于浮点运算。在大多数架构中,FP寄存器比常规寄存器大,因此它们成为优化代码的理想选择。
例如,在PPC603处理器中,如果使用C ++而不是普通C,FP寄存器将用于优化,如果您没有在该任务上启用VX_FP_TASK,则可能损坏另一个任务的FP寄存器,即使它没有进行任何计算!
正确执行比性能更重要,并且大多数时候性能提升并不能证明不启用它所带来的风险。
如果要确保所有任务都启用了标志,请考虑添加一个始终在任务创建期间使用taskCreateHookAdd()
启用该标志的挂钩答案 2 :(得分:2)
总是使用VX_FP_TASK!没有它的成本,并试图追查导致的不稳定错误难以置信昂贵。