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

基于STM32H7芯片的矩阵运算应用示例

[复制链接]
yumeii 发布时间:2019-12-27 15:12
在STM32的应用开发过程中,我们有时可能涉及到DSP应用,需要使用到相关DSP函数。这里基于STM32H743芯片的Nucleo开发板,做个有关矩阵运算应用的演示,简单的演示下两个矩阵相乘的实现过程。, G& @) H' ]+ r4 {

2 K8 w5 B$ a( n8 J) C开发环境选择的是ARM MDK,当然你也可以选其它的,比方IAR, STM32CubeIDE等。
) j: Y; g5 J* c2 m" s- A
  x) ]& T2 v; e

, {7 Z1 _. U: X3 [0 L  e1 j我们要用到ARM提供的DSP函数库,该库在STM32的Cube库或标准库里都可以找到。+ ^+ V* }- _/ |1 W2 G2 U1 m

9 K3 `; O3 n$ M9 `6 W
) z7 g+ Y, Z1 P/ n# |
以STM32CubeH7的库为例,相应的DSP函数库一般在下面位置:
& Y% N. b) p+ h* B" r+ `
, m. H2 d. N1 Y  N' |
2 {+ Q2 H: g  C! t7 |6 g) @
1.png 1 J# `' A) v: k! V: k7 p
7 C4 p" g1 o1 `/ K; g6 Z* ~

4 H0 @3 U# O% F8 r上图中绿色方框内的函数即为跟矩阵相关的函数库文件。, P/ Z4 b$ I4 L6 |5 W. B

$ s7 x# i4 O1 f6 ]8 T5 e
# U8 L& m1 F. F8 A+ Z3 [) U+ u
具体使用时,我们直接添加相应的lib库进来即可,不过,添加该lib库文件时要注意两点:
0 n6 ?% u' Y! W" O; t- B' p, n  ]5 U: v: I# e
' y1 j6 ~- y2 {% F% {, H* ~
你选择的库文件要跟你芯片类型一致,内核类型、大小端模式、是否支持浮点运算。5 X! f* D5 {9 o) w
$ j' X, _" `& l
  C9 ]. @+ |# y' N) E
你选择的库文件还要跟你所使用的编译器匹配,即IDE是MDK还是IAR等。# Z% e& f1 _  f

% b2 f( [4 {6 T' P7 M

' l2 s; I8 X( }( m! H6 O基于上面两点我们添加arm_cortexM7lfdp_math.lib文件【corex M7、小端模式、支持硬件浮点单元】。8 ~4 h1 l3 K9 k+ o$ f
8 M+ p& L9 x  X2 R4 u

( x$ R/ H1 G- d8 o% S' M1 n; I" z 2.png % x" p" s: g; N
  Q& u, R  f$ s$ Q

( Z2 d! q3 F, I8 F8 \) f* a! g6 J在我们的main()文件里添加arm_math.h头文件。记得在IDE环境的配置里添加相应的搜索路径。启用硬件浮点运算单元。开启有关宏定义。【宏开关不用特别去记,缺少的话编译时会报错】. q* y( i$ K' _$ ?2 t- f

' I$ d* E( I6 w( H) }

; Y* s- A3 S: a9 R- O 3.png
- k: j) w% Y9 Z' K
/ f, o" w9 T7 A
/ w8 X& Z+ {: V2 q
下面构造三个矩阵,A矩阵的数据表示某家芯片代理商为他的8个客户分别提供四种不同规格的芯片,数据以包为单位。不同型号的包装规格不一样。A矩阵为8X4矩阵。+ E' z/ u  H# D2 c
$ z) ?& I- X' z# |

, L7 ^4 H' l; V* N# LB矩阵表示A矩阵中各类包装每包的数量、价格、运费、重量,为4X4矩阵。. X5 @$ f( d$ x+ V3 V

: x5 Q) J5 _) v

0 H: L' J' X7 u, d/ p& L二者的矩阵乘积表示各个收货方收到芯片的总数、应付货款、运费、以及货物总重量,将构成8X4矩阵。矩阵里的数据使用浮点数,数据随意设计的。
* L! v: Y) U7 }( X/ U! ^3 b. |  D' S! @( `
我们知道,两个矩阵可乘有个前提,比方A*B,矩阵A的列数应该等于矩阵B的行数,相乘后所得的乘积矩阵的行数等于矩阵A的行数,其列数等于矩阵B的列数。) q* H1 g) L' Y7 s6 d

# r3 U3 X# s9 g
% i7 i+ N1 s6 I( s
具体到这里,矩阵A的行数为8,列数为4,矩阵B的行数、列数均为4。A*B所得矩阵的行数为8,列数为4.
7 e8 V- d. ~2 P. I$ M- A5 `" [6 z  `! k

) q; m. y7 z6 g& a  ?' f; Y1 T4 w) d 4.png * f! \* A6 m1 `; P
/ ^! p6 v6 q- C4 I: j
  {! |7 Z# w# K$ V' i) m
5.png 4 y; N. J3 M# A  i

, Q. f8 v0 P3 s
; {5 v0 s0 E2 m
下面做相关代码的准备。0 W& d( ]0 a* a- w0 P  K& r
- h1 x1 a# m8 Y& {

& Z2 q) D/ }+ P1 X定义三个数组,pDataA[32]数组对应矩阵A, pDataB[16]数组对应矩阵B,第3个数组pDataC[32]对应矩阵AB乘积所得的新矩阵。$ T- c; {1 r( h" w8 j; J, t

! `; c7 c1 B6 A7 s1 T( Z# U
, c# K+ _" c4 R3 M& _  n
6.png   r5 |9 ]0 M0 F' U+ \! W) b  B7 h0 s7 U

6 f! X# v4 f3 Z+ f: v. L

8 M4 d  x$ F6 K5 ?( d基于上面的3个数组定义3个如下矩阵变量:+ E9 E/ P+ P* G% G& `( F7 `

! C4 }& }6 L0 ?+ y# ~- x5 ~# E

  |4 j/ F' e8 ~" J! ]1 {) C% t 7.png 6 V3 G& s0 F, e0 k

$ d2 f/ [0 M% E1 J  L* x

3 L3 ]: |% w/ z5 h1 R( U关于结构体arm_matrix_instance_f32的定义和说明,可以在arm_math.h中看到。
' W& f8 S8 s  |- D( e0 r! M( o' H  F" I8 ~( ]( O
8 x6 r# _& K! O" k
8.png * H; O; B8 ^. r% I4 W) g: z
2 W+ C8 j5 U) c7 x' ]- F" {( [: G7 E

% z4 `0 v. y% ~$ V* {; g接下来对3个矩阵进行初始化,注意行、列数别给错了。# }* t9 ?0 ^' _. N, m: K

- q9 p  c' j0 A# G# b+ E$ |( x

. g0 j3 S- ?, u. V/ G5 }( Q9 F 9.png
. j/ {% q# `7 @7 C/ ^$ P! l7 X, `
2 A+ c! U- O+ v7 y: V( D/ k  W8 o" }( F
一切都准备好了,就可以进行矩阵乘法计算了,调用库函数中arm_mat_mult_f32()函数。/ h) p6 P2 Z% u
6 F0 C' [- l( b( @
1 ~( C$ O$ ]0 l* Z6 C( D
10.png . ^+ D% n3 ?  g& o. u  t
  E' R+ z- d: Q3 ^  l" @7 M
) F4 D$ Z5 H. o" c6 m
矩阵相乘后的运算结果存放在数组pDataC[32]里面,按8*4的矩阵摆放。; ~8 }, h; U& a7 Q' `/ m6 q' J# {: L

9 f% Q0 @) L) W' [" X) K& B5 i

8 E, [, t% y- c  a! ~8 U 11.png
/ i" V9 _/ a. C  L  P
% k! R* p3 a" \% x  P' K
: B1 h* M& s1 m( c
上述运算结果跟使用MATLAB数学工具通过矩阵乘法得到的结果整体上非常一致。数据会稍有些小出入,毕竟是基于浮点运算所得结果。; `9 x- o- h# [4 Z5 o( w, ^  Z
( X+ i" `2 G9 J
我们知道,STM32H7是带Cache和FPU的。不妨基于该矩阵乘法应用比较不同情况下的运行时间。以定时器的计数时钟为单位。根据Cache和FPU的开启与关闭的不同组合进行测试,可以做些相对比较,让我们有些直观的感受。测试时ARM MDK的优化等级为-o3。顺便提醒下,如果不开启硬件FPU,调用的DSP库函数应选择另外一个不支持硬件浮点单元的函数库。
1 l4 B! a8 L; T7 _: U' D6 p( @' w/ S
1 \0 b5 R# ]% q
12.png   k  Z* s. S1 o- [

: t6 [4 S2 {# w7 B+ L) Y" c# U3 l# m
+ T3 X5 v4 C& g& j+ r7 k
下面数据是基于上面测试代码所得到的,其中红色数据为十进制数据。
* ?2 ^( l3 c& g) \! N, }" z, V: E
9 }9 B! S* `- H. q! {6 M7 q, c
  ^8 @/ w  p$ \  h: b* c% |
13.png
0 b! Q3 c$ g, A7 \; K6 f3 X
1 j5 K2 I' x% [: i; v4 H

8 w  p" f+ J3 r* \从这里我们可以看出,同时开启硬件FPU和Cache与同时关闭二者,运行时间相差将近40倍;开启Cache与关闭Cache运行时间上相差4倍左右;使用FPU和不用FPU,运行时间相差8倍左右。当然,或许基于不同的应用,上述数据可能存在些差异,但可以肯定,开与不开Cache、启不启用硬件FPU,运行速度上的差别还是很明显的。
) [8 L8 {1 i  n) I3 a- o. Y' J! N0 ]4 F0 y
% y5 M# T8 q" k+ Z& ?$ i4 _
好,关于利用STM32及相关DSP函数库进行矩阵运算的演示就介绍到这里,请留意上文中谈到的那些提醒。其它更多细节,有兴趣的话可以进一步阅读和研究相关资料。) w8 ^) Y0 V5 j9 {1 J. c, h& ~
% [+ g2 |) _* |: C( i- i
赞 收藏 1 评论0 发布时间:2019-12-27 15:12

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版