你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

实战解惑,对STM32浮点运算单元FPU有疑问?

[复制链接]
STMCU-管管 发布时间:2021-5-17 10:27
今天谈一谈对STM32浮点运算单元FPU,有人利用STM32芯片做些DSP处理,在启用FPU单元进行调试、验证过程中可能会遇到些小问题、小困惑,这里通过STM32F4芯片一个具体的应用示例简单分享下,希望顺便能给同仁提供些帮助或提醒。0 I& T# o% O) a* R  x/ `$ I( M
% H9 X, b. y. d# g) ^5 Q' V

& c5 v; v: ?6 y; j+ ~1 w$ R; C我这里通过调用DSP库里的FFT相关函数实现1024点的FFT运算,样点数据及运算结果均为浮点数。
; T: w0 @& K- _( I; V, r$ G' F0 V
1.png
上图中A区代码是做样点数据准备,B区代码完成FFT运算。我们来一起看看基本的配置以及不启用硬件浮点单元和启用硬件浮点单元执行B区代码的时间上的差别。
# m8 r8 l( O# s+ K
+ g! `  _% _/ u4 G9 ?
* t! S. x( J) U" w3 Q
程序里要调用一些数学函数,而这些数学函数往往集成在相应的数学函数库里。我们选用ARM公司的DSP数学库,该库系专门针对AMR核芯片及指令系统而组织的代码,相比IDE自带的通用数学函数库会更优化、高效。! o& ^% q) c) V1 @* d% w

& Z# G3 o( f" C. i7 k

) V0 o# q/ @' V) z$ c$ h3 k' c目前该DSP数学库包括基本数学函数、复数数学函数、滤波函数、矩阵函数等几大块,详细内容可以去ARM网站阅读比较方便。【可点击左下方原文链接前往】
4 M3 D5 h9 N5 ^/ e% m2 s9 W. j
2.png
: x% a6 d8 ]3 g! A. t, ^  W

) o3 \4 U0 X  q; k我们开发时,这些文件具体在哪里呢?在各个编译环境的安装目录下都不难找到。不妨看看ARM keil MDK环境下它们所在位置。# Z1 W4 {! c7 d( I/ C* n
3.png
上面我们看到的是DSP库源文件所在目录,在另一个目录存放着基于不同内核、不同存储端格式以及是否支持硬件浮点单元而编译出来的库文件。我们在开发时,直接添加合适的库文件进工程即可,不必逐个查找源文件来添加。下图就是可以用于ARM MDK环境的库文件。【对于不同IDE,库文件名后缀略有差异】
& N: K' l: h& J3 B" R( _
3.png
这里以用于M4内核的DSP数学函数库稍作解释,详见下面表格。7 W% d3 `& h' y  s& }1 N$ s! ~% @
4.png
从上表可以看出,基于Cortex M4内核芯片进行DSP运算可以能用到的库有四个,但具体到STM32 基于M4内核的芯片可以选用的只有两个,即xxxM4l_math.lib或xxxM4lf_math.lib,因为STM32芯片的存储设计都是小端模式。所谓小端模式,简单点说就是指多字节数据在内存中存储时,按照低位字节对应地址低位来存放,反之则为大端模式。
5 f7 e; J$ @, `0 v$ \* k- w4 U+ e3 W5 J+ g+ T) [* T

' E1 I/ t# |! b3 [& d* r# \在上面截图中,我还截取了对应M0内核可用的DSP数学库,它为什么只有两个?这是因为M0内核没有FPU硬件单元,不存在FPU是否启用的可选情况。; I9 A# }3 S  O, K

- T- O4 Q' N7 Y. s; Y3 i
: z; A- q9 \  }7 ?7 i: [
现在就利用STM32F429开发板,基于开篇的截图代码进行测试,并用定时器测量下面执行代码在不使用FPU和使用FPU分别所花费的时间,并计算二者的时间比。【注:STM32F429芯片自身是带硬件FPU的】5 A1 E" ~1 d- b/ f
5.png
/ l7 \/ D7 X  n
4 ^2 x1 r- B2 L, [$ U
必要的配置和文件包含及添加,如下表所示:
( x( H! `$ g$ F! P8 O4 T- g
6.png

* f5 a+ K0 D: [! }& Y1 Z! S( A
4 |* C& D0 {; R' y) w' Z
基于上面条件执行FFT运算代码,不使用FPU和使用FPU的时间比为16。
" f( g6 a0 \! J7 J" `4 h* k+ ^4 V; F6 I

  R5 A8 P1 o; i' R/ I) @( @采用相似的条件,基于IAR环境对相同功能代码段进行测试,不使用FPU和使用FPU的时间比为11。
9 |5 @; |+ t9 S
6 R$ `5 o1 H# t7 D, y" O0 W4 B1 W
) g# H6 K! V; B9 [) `: b) E
关于这个时间比,除了跟是否使用微库、优化等级、浮点精度等有关外,跟你所选取的测试代码也有很大关系,因为有些代码只能靠CPU执行的话,开不开FPU硬件单元对这部分时间是没有影响的。不难理解,被测试代码里只能靠CPU运行的代码占比越多,上面的这个比值就会越小。一般来说,我们不必太过纠结这个值的大小,知道有这个硬件浮点单元,既减轻了CPU负荷,又可以提升计算速度就好。. {: q) ~( w( I; T$ w8 o* j
  Q& [) _; d8 p" s, d' L% `- h& N/ {2 D
' Q9 D4 {' t" D! X0 Z. s7 |
另外,我们在做DSP相关应用时,注意添加的DSP库既要跟所用芯片匹配,还要跟IDE里的配置匹配。还是以上面测试代码为例,本意是想启用FPU,结果添加的DSP库却是基于不使用FPU硬件的数学库,那会怎么样呢?. J  Y2 }, Y6 A8 V1 ]
7.png
本应该添加arm_cortexM4lf_math.h的,结果弄错了。如果按照上面条件构建ARM MDK工程,一路编译下来没有任何警告或错误提示。程序也能流畅运行,FFT运算结果似乎也出来了。/ L9 i% X/ M$ z
8.png

% i) N- j8 W$ }* w9 j3 [
. J, @+ E' S# y3 a! ]2 N
但仔细查看结果,跟之前正确配置的运行结果明显不一样。经验证核对,这次运算结果是错的。为此我特意添加一行计算90°的正弦值代码,它算出来结果竟然是1.5!逆天了。
! w* i0 T# w* Y6 m5 ?0 K
9.png
如果说在不知情的情况下这一路下来,估计要被摧残一顿了。毕竟很多数学函数结果常人是无法一眼能看出对错的,即使看出错了若没未及时想到库问题的话,恐怕还得折腾折腾。
* T2 S+ g8 P$ |; }
6 s1 c& A) x" n1 W; c: h/ F
  r3 T5 g- N$ W: O8 U$ c! k5 R6 F1 J* @! [
针对这种情形,基于同样代码于IAR环境下测试,情况相比ARM MDK貌似要好点。至少编译时有警告提示,提示引用冲突之类的。计算结果没有MDK的那么具有隐蔽性【至少对于本次测试是这样】,基本是清一色的0,颇有冲击效果!当然,此时让它计算90°的正弦值结果也是明显错的。
/ n) Z7 K" q9 ^: K" A1 {
10.png
  p+ g  S' P" T+ [/ D1 H4 }' N

* l+ D& X# e* t0 F1 d4 V感觉上,这种情形下,使用IAR时挖的坑似乎稍微浅些,更容易让人警醒怀疑哪里出问题了。
0 s' O2 T" n- a/ C* W( Q8 z& v5 }, E2 C, X+ I+ ~. r" }
赞 收藏 评论1 发布时间:2021-5-17 10:27

举报

1个回答
胤幻1988 回答时间:2021-5-18 16:27:05
因吹斯汀,谢谢分享~3 `6 G" E* y' l5 [' n! k4 N
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版