01 DSP简介) U F3 Q3 C1 i, o
提到DSP,作为电子专业的学生,大部分第一时间想到的是DSP芯片,DSP芯片的内部采用程序和数据分开的哈佛结构,具有专门的硬件乘法器,广泛采用流水线操作,提供特殊的DSP指令,可以用来快速的实现各种数字信号处理算法。
; ` @' x3 b8 H- a7 f ^, G$ A; g9 | w/ g4 E4 P6 M, P
! i. X0 G: i+ M3 E* J+ ^! p
实际上,DSP的全称是数字信号处理(DigitalSignalProcessing,简称DSP)。在过去的二十多年时间里,数字信号处理已经在通信等领域得到极为广泛DSP技术图解的应用。/ X( T9 @5 A) O9 h! v) C
. b! z% s' `: H7 ?$ ]6 U
/ ]. f4 \0 k6 I
如下面ARM官方描述的,ARM处理器是支持DSP的。
/ l; W) W6 j3 K+ q7 z) k0 e8 ?" U# Y主要是在cortex-R和Cortex-M内核支持。
/ c4 ^: k+ F# p, ]* A; X5 ~1 J) a- dArm 的数字信号控制器Cortex-M4、Cortex-M7、Cortex-M33、Cortex-M35P和Cortex-M55处理器满足了对高性能通用代码处理以及数字信号处理应用的需求。! X2 `+ w+ M- E: W% I
向Thumb 指令集添加DSP 扩展和可选浮点单元(FPU),旨在提高数值算法的性能。此外,它们提供了直接在 Cortex-M处理器上执行信号处理操作的机会,同时保持Cortex-M程序员模型的易用性。
# S& Z; Q" r( b. y Q6 @! V0 B( V; Q2 c8 J! D
02 IAR中DSP Libary的使用6 R; E7 p7 m B8 P: j
! G, X. q" z2 W; V2 u2 a6 h+ l0 D) e% D; V0 D k9 r6 i
ArmCortex-M3 /M4处理器提供信号处理指令,例如SIMD(单指令多数据)。特别是Cortex-M4专为DSP应用而设计,它支持高级SIMD,MAC(乘法和累加)指令。此外,Cortex-M4F器件具有FPU(浮点单元),用于处理浮点计算。( [, P# X. v; [( {" E/ K$ W
3 M+ Y: v1 C: ^8 M$ x' a
5 b: ?) S- H7 N1 d9 Q9 F有几种方法可以使用这些指令,例如使用汇编程序例程或内部函数,但最实用的方法之一是使用ArmCortex微控制器软件接口标准(CMSIS)DSP库。CMSIS-DSP库专为Cortex-M处理器而设计,它为数字信号处理提供优化的功能,如矩阵函数,统计函数,高级数学函数等。: g2 X4 {# W" @1 Y
/ [' @9 E1 |' I n X1 k0 C
e2 {7 B$ F* a, i' ]
IAREmbedded Workbench forArm中提供了预构建的CMSIS-DSP库及其源代码,在本文中,我们将了解如何将CMSIS-DSP库与IAREmbedded Workbench for Arm一起使用以及如何改进性能。7 j Y; f; t/ [" a
. ]7 ?) B" U% E0 v# N5 ~
; [( A+ L) @6 v1 f( ZConfiguringthe CMSIS-DSP library* T) @( t( e. n+ V
# L) M* N! Q7 F2 O( O+ |6 e
- ` ?. n9 ?9 O. Z2 ?* u+ S
配置CMSIS-DSP库
. H. j) T. q7 b3 D# n; [! T g让我们看看如何调用CMSIS-DSP功能及其性能。这里我们将使用sqrt(平方根)函数并与标准数学函数进行比较:1 p, J: N' C) Y: ^
- ' l& Z" z4 I! B3 h H- E4 o% _
- //#define DSP_Lib4 }7 x4 t% v4 m+ N
+ I1 t, u! G) S1 c+ z- #ifdef DSP_Lib
& I' g8 Z& b% Y2 Z6 j! A) e3 z - #include <arm_math.h>
& m9 i [, p! A& q+ I - #endif* F1 D. t; Z' T* q# R
* b( H0 U/ P& R( I# U& ?; v- #include <math.h>0 U3 Z2 {1 Q. M! U* v, @
- #include <stdio.h>0 e) s$ S2 q( {$ r5 f, {" N
- int main()' P) e: a0 }2 e1 P0 p" M
- {: c7 K+ h p3 Q0 }$ ~
- #ifdef DSP_Lib
" l! G/ ~ G/ q- L2 y7 d - float32_t f_input_cmsis_dsp = 2;7 m9 A2 w6 t, K! f2 x
- float32_t f_result_cmsis_dsp;: i6 z+ L* x/ h
- #endif
( f- P! L; p) ` -
3 H9 Z7 X5 j2 O( A$ b/ j& \6 L - float f_input = 2;0 x' f& k" W h) t% b
- float f_result;
: z( b% `; s$ {- k& D H9 q - 1 G, i) Q/ Q8 y# g/ i+ Z% v+ K% l
- & G/ G% H( I! i8 L
- #ifdef DSP_Lib
& @! A0 w. f' { - /* Using CMSIS-DSP library */+ G5 V: L. l! ~) o0 g
- arm_sqrt_f32(f_input_cmsis_dsp,&f_result_cmsis_dsp);
/ W: B( B) H% q - printf("f1: %f\n",f_result_cmsis_dsp);
1 ]* ~( M( ?3 s0 I - #endif
% I7 ?4 R4 c2 @8 q' @, ~/ w -
6 g* [3 Z" J+ n0 W2 e - /* Standard math function */
$ K* B7 j1 ?0 L# ] R! U! Q - f_result = sqrt(f_input);
) q5 @0 s8 _- [' G7 z - printf("f2: %f\n",f_result); v- J% U. Y% W% V+ z8 M, U
-
7 w9 V P( V/ F8 l9 K - return 0;
6 m, X! [7 r) T" p( F - }
复制代码 结果如下
# R6 ^9 E- L1 q# {3 M4 `- f1: 1.414214 7 Q5 M0 k+ u3 D) g3 z8 E/ o% }
- f2: 1.414214
复制代码 接下来,让我们来看看性能。
# A+ X1 b% y$ y) Q
1 ?# L( R. F' \0 z$ F( }! C2 m
4 u8 u+ a. \, GIAREmbedded Workbench中的CYCLECOUNTER寄存器可用于检查正在运行的代码所消耗的周期数。在检查上次执行的C/ C ++源代码或汇编程序步骤期间的循环次数时,CCSTEP寄存器非常方便有用。3 d* L( M9 J9 k7 K, U/ X
设置断点并记下sqrt函数的CCSTEP值:
C& |. N" |+ K; w: d在这种情况下,CMSIS-DSPsqrt功能比标准数学函数快10倍以上。
& F. n. A! ^/ F" l4 H& s- arm_sqrt_f32 : 52 cycles
: |2 p* H1 g" M* _* N ] - sqrt : 752 cycles
复制代码 从这个简单的例子中,我们可以看到CMSIS-DSP非常易于使用,并且显着提高了性能。' K6 ?+ Q! N, P# Q
$ q# P v* S( y
5 M" Y. @$ {8 r; V; l0 r' p |