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

【STM32H5 评测】内存读写性能 - STM32H5E5实测Flash,SRAM读写速度,用DMA搬运大块数据

[复制链接]
无敌帅帅帅 发布时间:2026-10-19 13:52
整个测试分为5部分:
  x$ N5 s* K4 n* L! Z& C/ q) X4 K& q3 _; N8 B( \1 G
1. flash 读取速度
6 N) B. w+ C) I% |  ]( B2. flash 写入速度
# m0 E% i. l- x: Q" }" n; f3. SRAM读取速度
  Y) U1 w% h0 Z  V2 `4. SRAM写入速度
% l( b) c9 T1 i- {6 Z8 b0 O. T' A7 H5. DMA传输速度
3 ^4 W; ^  |% F
6 A+ ?4 a: V# w; F% ^- G" e9 ^这个测试的代码工程是基于前一篇分享文章做的,具体工程搭建可以参考上一篇文章查看。: r% c( K) n) j- E
【STM32H5 评测】CPU核心性能 - STM32H5E5跑 RTOS,观察任务切换速度、中断响应快慢
9 v, w" E. @: c5 C) W# Y* V, c
# z6 c, ~+ t1 @; a, j* `+ Z+ U/ e2 j
  • 1. flash 读取速度
    - y8 }6 `/ w3 ]- T7 |& J6 E( o
3 ^/ a4 C% b) o8 I
flash读性能测试,一次性读取32kbyte flash大小来测试耗时3 M5 @5 F9 N3 p
  1. #define MEM_BUF_SIZE    (32u * 1024u)   /* 32KB,足够体现带宽,不超 SRAM */
    ( [8 T6 d! D( e& @1 B+ Q

  2. % c, N6 e9 e# X% l4 M
  3. static void run_flash_read_test(void)+ f( P4 h2 P) O
  4. {
    0 A) f3 m2 |, X- R
  5.     const volatile uint32_t *src = (const volatile uint32_t *)0x08010000;
    % P5 z3 K/ u4 j. V3 p4 c
  6.     const uint32_t words = MEM_BUF_SIZE / 4u;* _, }$ G3 e; _- I( P$ w

  7. % |  Y& \5 u5 \
  8.     uint32_t t0 = DWT_GET();
    * {% n1 v# p' b
  9.     for (uint32_t i = 0; i < words; i++)/ h4 m4 H- W# b6 y, R8 ~; O
  10.         mem_dst[i] = src[i];
    # O5 W& h& \; L  p5 Y. _6 ?0 ^
  11.     uint32_t cycles = DWT_GET() - t0;
    % j/ ~; w( j: ^5 z: k7 ~% D7 t

  12. ' r& g( U6 b% E% `
  13.     printf("[3a] Flash Read  : %lu cycles -> %lu MB/s\r\n", cycles, cycles_to_mbps(MEM_BUF_SIZE, cycles));
    + r* J  _  ^- |/ X; H
  14. }
复制代码
  • 2. flash写入速度
    8 `6 ]4 t, N4 s
/ d% b; a# E0 r, K8 d
flash写入性能测试,这里将flash的擦除做了分别计时,写入的话只测了8kbyte大小。* I4 D% U+ }. m" d, k0 x
  1. static void run_flash_write_test(void)
      O3 F9 c& c8 v: I3 w  R
  2. {
    * Z5 Q3 p" w' E& O, K
  3.     FLASH_EraseInitTypeDef erase = {0};  p8 q0 u7 N+ A1 G5 s* k6 ^
  4.     uint32_t sector_error = 0;
    & E& F; b. S: C! B$ A  r* ]
  5.     uint32_t t0, erase_cycles, write_cycles;: k& H2 a" S4 S

  6. 5 ^+ A' \  `6 w/ H+ l. G% T
  7.     /* 擦除计时 */
    5 f! r/ J% H' R; c. a
  8.     HAL_FLASH_Unlock();
    ( [- J1 [- C% w9 ~0 D
  9.     erase.TypeErase = FLASH_TYPEERASE_SECTORS;
    ' A( z5 W6 c. M+ B, K/ n
  10.     erase.Banks     = FLASH_BANK_2;
    " V1 v: t( ~! S% d3 z' ^, g& o
  11.     erase.Sector    = FLASH_TEST_SECTOR;, f6 [* O7 Y: ~/ _0 Z3 J
  12.     erase.NbSectors = 1;( K5 `7 b; H' F& G0 D7 w

  13. $ t  z4 i) u8 \# ~
  14.     t0 = DWT_GET();
    9 L3 C' V. h7 t) ?( d
  15.     HAL_FLASHEx_Erase(&erase, &sector_error);
    $ y( [1 m% f0 f# s6 f, ^6 F( {3 b
  16.     erase_cycles = DWT_GET() - t0;0 _" P% e3 k4 g( W# t: S4 |3 d+ U- z$ ~

  17. 3 W/ U% c/ z% u2 A; z
  18.     if (sector_error != 0xFFFFFFFFu)
    $ S- i$ q) R" L8 K
  19.     {; _# |! g0 f: O+ I  g  s% U
  20.         HAL_FLASH_Lock();6 @9 g: C9 j6 F2 n9 s& q
  21.         printf("[3b] Flash Erase : FAILED (sector error 0x%lX)\r\n", sector_error);
    $ W7 n" \+ q: X& ^4 G/ z3 O
  22.         return;
    2 F; x0 Q+ w1 L8 \1 B" t
  23.     }8 l; Y' g7 N# A# i/ B4 o* @1 ]
  24. 4 b) M. p- R8 f5 q9 f: b% n. d& o: }
  25.     /* 写入计时: 每次写 16 字节,共写 FLASH_TEST_SIZE 字节 */
    4 I" f' P7 ^/ `$ G
  26.     uint64_t pattern[2] = {0xDEADBEEFCAFEBABEull, 0x0123456789ABCDEFull};: r4 j" h- H5 |( |  v
  27.     t0 = DWT_GET();
    7 [) ]) j: U4 Q, T& @" g6 Y
  28.     for (uint32_t offset = 0; offset < FLASH_TEST_SIZE; offset += FLASH_WRITE_UNIT)
    ' x( g+ T* m/ U8 J. A  e3 B
  29.     {
    " I5 s6 g# D, Y1 I0 X
  30.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD,
    . G1 d! Y2 \( L" h" p5 s
  31.         FLASH_TEST_ADDR + offset,# v& Q7 }  ^, p( J
  32.         (uint32_t)pattern);
    / Y4 M6 l/ N  c. Z7 I3 r
  33.     }
    0 Y! d5 X' u+ s0 A" o
  34.     write_cycles = DWT_GET() - t0;
    0 A" K2 R0 W4 y3 n
  35.     HAL_FLASH_Lock();0 s8 o$ d" `2 j- ]
  36. 2 `. l+ `$ J1 W* ^2 j# x$ N! M
  37.     uint32_t erase_ms = CYCLES_TO_NS(erase_cycles) / 1000000u;- G7 S5 l. C7 T+ j) W. L1 y
  38.     printf("[3b] Flash Erase : %lu cycles = %lu ms  (8KB)\r\n", erase_cycles, erase_ms);
    5 r) n0 f& t1 W" P8 }
  39.     printf("[3b] Flash Write : %lu cycles -> %lu MB/s  (8KB)\r\n", write_cycles,# ~  o( J. {6 m  B# l
  40.         (uint32_t)((uint64_t)FLASH_TEST_SIZE * CPU_FREQ_MHZ * 1000000u / ((uint64_t)write_cycles * 1024u * 1024u)));. Q3 j6 p" {- V! c! S
  41. }
复制代码
  • 3. SRAM读取速度
    - J$ D: h6 @0 ~- K
+ O& I. Z+ o/ @7 D) _: @. Y4 Q7 F9 ~
SRAM读取速度是通过一次性读取32kbyte来测试耗时* ^4 i7 L: a. S. ~) m9 {: ]6 y
  1. static void run_sram_read_test(void)
    - y. u; h) n; Y! {3 S& C4 E) t
  2. {2 r2 q% n  d, }
  3.     const volatile uint32_t *src = (const volatile uint32_t *)mem_src;! K2 \. {$ X" l0 j1 N% h! r# }
  4.     const uint32_t words = MEM_BUF_SIZE / 4u;6 P$ q& y' I1 }! C  N- Z1 Y2 @
  5. ! @7 u* y  u+ m/ L' s
  6.     /* 先填充,避免读到全零被优化掉 */
    " }& v% i( R3 B6 D& q
  7.     for (uint32_t i = 0; i < words; i++)
    0 E# K$ S1 ]' U
  8.         ((volatile uint32_t *)mem_src)[i] = i;
复制代码
  • 4. SRAM写入速度- M# q( L) W8 L/ B9 f

" J1 \' R- m2 ~9 ^% w! N6 t* NSRAM写入速度是通过一次性写入32kbyte来测试耗时
) w5 N7 c/ ]! r( w7 h2 H" m
  1. static void run_sram_write_test(void)9 w$ o% m7 r6 V
  2. {
    3 t  A( `0 @  Z/ t  y, X1 [
  3.     volatile uint32_t *dst = (volatile uint32_t *)mem_dst;3 H( z9 ?4 W7 W
  4.     const uint32_t words = MEM_BUF_SIZE / 4u;6 e5 ]8 Q4 X  Y6 P

  5. ' H7 o, y- U8 d7 k% [6 A
  6.     uint32_t t0 = DWT_GET();
    ! ?/ e1 T, Q$ J$ W9 d
  7.     for (uint32_t i = 0; i < words; i++)7 J* `( k) s+ H, h7 n! W
  8.         dst[i] = i;
复制代码
  • 5. DMA传输速度; g& g( O$ p1 J5 {
5 Y* _) x) _& Q9 g
DMA传输是通过两个32kbyte大小的SRAM之间搬运数据,计算耗时4 t* B& a1 p, D. S, @
  1. static volatile uint8_t dma_done;
    8 G' ?  ]% \. L( P! ]

  2. 1 \  d" a, N  X4 Z
  3. void GPDMA1_Channel0_IRQHandler(void)
    % Y- g) J% L6 A) l
  4. {
    ; t9 j/ C, Z" J5 c! T
  5.     GPDMA1_Channel0->CFCR = GPDMA1_Channel0->CSR;  /* 清除所有标志 */& \7 i% D$ ?* y) S4 Z7 V
  6.     dma_done = 1;
    # h1 [3 U% c( ~; g$ x1 ]4 |
  7. }6 `) y5 C7 [: a
  8. ; o; f6 [% Q+ N
  9. static void run_dma_test(void)" c# G' ^# Z" H  C! O- ~
  10. {1 A" i9 q* _  Q" B2 y* i2 n
  11.     /* 使能 GPDMA1 时钟 */9 i9 v7 j" e6 |+ @( q* L! U; w6 Q
  12.     __HAL_RCC_GPDMA1_CLK_ENABLE();  B$ c6 z! ]& T- N
  13. . Y1 h: _2 o/ G- r+ H3 r( K
  14.     /* 初始化源缓冲区 */, Y, R6 _. W; ?% j6 }( N2 C
  15.     for (uint32_t i = 0; i < MEM_BUF_SIZE; i++)( e0 N$ k5 @0 o. e
  16.         mem_src[i] = (uint8_t)i;
复制代码
最后编译代码,观察串口打印日志:0 ^! t" p# [' p7 S9 d6 I0 _

( B' c+ M; B1 H1 v[3] Memory Bandwidth Test (32 KB buffer)...
2 G* I5 {. F/ x$ R[3a] Flash Read  : 61639 cycles -> 126 MB/s
# F' @: B0 k5 l, u2 }7 z[3b] Flash Erase : 408500 cycles = 1 ms  (8KB)
( {+ a: t2 F8 X1 k6 ?[3b] Flash Write : 90731 cycles -> 21 MB/s  (8KB)
, {/ {" ^$ V  v/ v' W[3b] SRAM Write  : 40971 cycles -> 190 MB/s
  Z( ~5 c; o$ k[3c] SRAM Read   : 49283 cycles -> 158 MB/s
# G% i% c/ p, L  ^! D$ \[3d] DMA Transfer: 45942 cycles -> 170 MB/s  (32 KB)
/ @0 e/ Y- ?! Z2 @! d7 E6 }# y* n$ b6 b+ u/ n0 b3 K# y

# I5 ~" z$ u4 G/ D, R9 l从测试结果来看,性能还是非常不错的。
0 j) w: l+ x! p, c; _! d. `
  D7 R- V) q0 o, M+ N
赞 收藏 评论0 发布时间:2026-10-19 13:52

举报

0个回答

所属标签

相似技术帖

官网相关资源

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