公告

大中华汽车电子生态圈社区并入开发者社区- 更多资讯点击此

Tip / 登入 to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Translation_Bot
Community Manager
Community Manager
Community Manager

你好,我想让 FPU 在 XMC4200 上运行,但由于某种原因我无法获得预期的性能。 我使用的是最新版本的 DAVE。

在随附的项目中:

1。 我启用了 FPU:SCB-> CPACR |= 0x00f00000;//启用 FPU

2。我有两个函数,一个平方根和一个乘法,还有一些用于在示波器上测量时间的引脚切换。

3。我测量了平方根的大约 390 个时钟周期,乘法测量了 26 个时钟周期。 我认为这些时间太长了,即使未启用 FPU,它们也不会有太大变化。 所以,我认为我没有正确使用 FPU。

如果有人 CAN 帮助我找到问题,我将不胜感激。 我通过更改活动项目属性尝试了这个论坛中的所有建议,但没有发现任何改进。

我还复制了 " main.c " 下面的文件,这是我在项目中创建的唯一文件。

我期待收到你的来信。 在此先感谢。

亚尔辛

 

========main.c============

#include " dave.h "
#include
 
float A = 555;
浮点数 B;
浮点数 C;
 
int main(空白)
{
 
SCB-> CPACR |= 0x00f00000; //启用 FPU
PORT1-> IOCR0 |= 0x800000;//Bit23 将推挽输出设置为 1 P1.2,主板引脚 13
 
 
而 (1U)
{
 
PORT1-> OMR |= (1u < < 2); //将 OMR 位 2 设置为 P1.2 高。
PORT1-> OMR |= 0x40000;//将 OMR bit 18 设置为高,将 P1.2 设置为低。
 
 
PORT1-> OMR |= (1u < < 2); //将 OMR 位 2 设置为 P1.2 高。
B = sqrtf (A); //4840 ns(大约 390 个时钟周期)
PORT1-> OMR |= 0x40000;//将 OMR bit 18 设置为高,将 P1.2 设置为低。
 
 
PORT1-> OMR |= (1u < < 2); //将 OMR 位 2 设置为 P1.2 高。
C = A * B; //327 ns(大约 26 个时钟周期)
PORT1-> OMR |= 0x40000;//将 OMR bit 18 设置为高,将 P1.2 设置为低。
 
}
}
0 点赞
7 回复数
Translation_Bot
Community Manager
Community Manager
Community Manager

嗨 @Yalcin_Haksoz

我们正在处理你的案子。

到目前为止,请参考以下链接并检查它是否有帮助。

链接:https://community.infineon.com/t5/Knowledge-Base-Articles/Implementing-Floating-Point-Unit-FPU-for-X...

最好的问候
Pradeep。

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

嗨 @Yalcin_Haksoz

如果您参考 m4 上的 arm 文档CortexCAN看不到每条指令所需的时钟周期。

例如,指令 STR 需要一个时钟周期。

请参考下面的链接,其中提供了每条指令在 Cortex m4 中需要多少时钟周期的参考。

链接:https://developer.arm.com/documentation/ddi0439/b/Programmers-Model/Instruction-set-summary/Load-sto... t。

调试文件夹中有一个 FPU.lst 文件,您可以在其中 CAN 看到上述项目的汇编级别代码,并且 CAN 计算每个函数占用的时钟周期数。

对于您的情况 CAN 您尝试在声明中添加“f”,请参阅以下内容:

float a=555.0f;

希望这会有所帮助,让我知道它并不能解决问题。

最好的问候
Pradeep。

 

 

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

谢谢 Pradeep,

将 " float A=555;更改"为"浮点数 a=555.0f;无济于"事,我还能测量同样的时间,sqrtf 函数的大约 390 个时钟周期

我并不是真的在追求函数所花费的确切周期数。 我只想减少项目中的循环时间。 我测量的大约 390 个时钟周期太长了。 根据下面的帖子,sqrtf 需要 21 个时钟周期,这比我的周期短得多。

https://community.infineon.com/t5/DAVE/How-do-I-use-the-FPU-for-fast-maths-functions-on-the-xmc4500-...

我希望你能帮助 CAN 我。

亚尔辛

 

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

@Yalcin_Haksoz

如前所述,我们尝试使用FPU指令,我们实现了多达30个平方根计算的时钟周期。

请执行以下操作,而不是使用 b=sqrtf (A);

__asm__("VSQRT.F32 %0、%1": " =t " (B): t (A));""

在上面的操作数是 " A",结果存储在 B 中 " "

上面直接使用 FPU 指令集,计算 " A 的平方根"并将其存储在 " B " 中。

请参考下图。

ppn_0-1695812667929.png

您 CAN 定义平方根的内联函数,如下所示:

__attribute__(always_inline)) 内联浮点数 sqrt_f32(float x)
{
float ans;
__asm__("VSQRT.F32 %0, %1" : "=t" (ans) : "t" (x));
return ans;
}

请参考下图:

ppn_1-1695812752967.png

通过直接调用 sqrt_f32(变量), CAN 获取值。

与上面类似的乘法,您 CAN 使用:

__asm__("VMUL.F32 %0、%1、%2": " =t " (C): t (B)、" t " (D));""

操作数中有 " B " " 和 " D,结果存储在 C 中 " "

有关 FPU 指令集,请参阅以下链接:

链接:https://developer.arm.com/documentation/ddi0439/b/BEHJADED

希望这会有所帮助,如果您还有其他疑问,请告诉我。

最好的问候
Pradeep。

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

效果很好,谢谢。 我在系统中测量的是250ns的平方根计算,也就是20个周期。

我有几个相关的问题:

  1. 我们还需要启用 FPU 吗 " SCB-> CPACR |= 0x00f00000;?" 无论有没有这条线,时间都不会改变。
  2. 该行是否有 " c " 等效项 " __asm__("VSQRT.F32 %0、%1": " =t " (B): t (A));"""?请注意,我对微控制器和编程非常陌生,我不明白这条线是如何工作的
  3. 你能否也提供其他 FPU 函数的代码? 乘法、除法、正弦、余弦、对数?

感谢您的支持。

亚尔辛

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

嗨 @Yalcin_Haksoz

以上问题请参考以下内容:

1) 启用 FPU 的软件初始化是在启动代码中完成的,因此无需在 main.c 中使用。

以下代码用于在启动时启用 FPU。

                                                                                           

ppn_5-1695883200368.png

 

此代码在编译前处于禁用状态,CAN忽略。在运行时编译期间,启用 FPU 的代码将根据 mfloat-abi=softfp 还是 –mfloat-abi=hard(此指令将在构建设置中给出)激活。

2)上述指令没有C等价物,但 CAN 定义自己的平方根内联函数,如上一篇文章所述。

与上述汇编级指令相比,等效的 c (sqrtf) 效率不高。

3)当您 CAN 遵守ARM的标准库时,为sqrt,乘法,除法提供了FPU指令,但不包括sin,cos和log。

乘法:

__asm__("VMUL.F32 %0、%1、%2": " =t " (C): t (B)、" t " (D));""

"B " 和 " D " 是操作数,乘法结果存储在 C 中 " "

分区:

__asm__("VDIV.F32 %0、%1、%2": " =t " (C): t (B)、" t " (D));""

"B " 和 " D " 是操作数,B/D 结果存储在 C 中 " "

来到罪,Cos并记录你 CAN 使用数学.h 分别是 sinf、cosf 和 logf 的函数。

如果你想优化这一点,你 CAN 正确地构建一个sin查找表,但完全取决于你的应用程序。

希望这会有所帮助,如果您还有其他疑问,请告诉我。

最好的问候
Pradeep。

 

0 点赞
Translation_Bot
Community Manager
Community Manager
Community Manager

那帮了大忙,非常感谢 Pradeep

最诚挚的问候,

亚尔辛

0 点赞