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

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

[复制链接]
无敌帅帅帅 发布时间:2026-10-19 13:52
整个测试分为5部分:
0 t* D0 l) k  N# g+ t, H8 P
+ p+ \' V8 U( t. n1. flash 读取速度
+ y! Q6 J8 p8 \! W: F5 n( ~2. flash 写入速度4 g/ v* ]: Q( ]8 I& `7 s; \" X
3. SRAM读取速度# x) s- V  P/ [8 J4 L9 p( I$ d# Q
4. SRAM写入速度
7 f- L5 O& R* b1 g: h! O5. DMA传输速度' t% u% Y% K. M, _9 T  v  g. v

" p2 z' D; h; o1 O6 l这个测试的代码工程是基于前一篇分享文章做的,具体工程搭建可以参考上一篇文章查看。; ~  a- M# y" e
【STM32H5 评测】CPU核心性能 - STM32H5E5跑 RTOS,观察任务切换速度、中断响应快慢
/ [9 ?2 Q9 C; r3 u2 ^7 Z  c2 [% J, [* {
  • 1. flash 读取速度) t9 g$ l. I+ d9 d/ `& m2 D: S% ]( \
. N( y% A$ \% a, I) o9 e+ w
flash读性能测试,一次性读取32kbyte flash大小来测试耗时: V$ K9 `1 s( a3 @/ @! x6 g- F
  1. #define MEM_BUF_SIZE    (32u * 1024u)   /* 32KB,足够体现带宽,不超 SRAM */& [4 B* T  T2 l% e+ w! w- Q

  2. ! K8 E8 l" ~0 T; N% t
  3. static void run_flash_read_test(void)
    0 d/ g' \6 q, c
  4. {! X3 B, T" w- r- ~, |2 Z8 m8 w$ o
  5.     const volatile uint32_t *src = (const volatile uint32_t *)0x08010000;& n$ b+ i% v" ^/ k) {1 T
  6.     const uint32_t words = MEM_BUF_SIZE / 4u;
    / ~  k' W+ e7 o5 v- j

  7. . L. t7 \7 o3 P3 |. _- A2 B
  8.     uint32_t t0 = DWT_GET();
    3 ^( U- i" [2 o5 f. P8 I4 p
  9.     for (uint32_t i = 0; i < words; i++)' t3 R* ?5 C; v9 F8 [
  10.         mem_dst[i] = src[i];# a% \* t+ ?3 s! |; b
  11.     uint32_t cycles = DWT_GET() - t0;" k$ t' k# B5 r5 Q
  12. 5 _# y6 h  o6 W5 |' I% I, d: X0 u
  13.     printf("[3a] Flash Read  : %lu cycles -> %lu MB/s\r\n", cycles, cycles_to_mbps(MEM_BUF_SIZE, cycles));( ^% g" `1 |4 q5 E& W' D
  14. }
复制代码
  • 2. flash写入速度
    7 R  j! @0 n# A: y% u; e( t/ K

9 ^* H8 M" m& @4 c* g: vflash写入性能测试,这里将flash的擦除做了分别计时,写入的话只测了8kbyte大小。
# Y8 ^4 r1 E- `8 w
  1. static void run_flash_write_test(void)! f3 [/ X2 g& v
  2. {0 y, @. m+ N- G7 \4 y0 [" F
  3.     FLASH_EraseInitTypeDef erase = {0};: J6 j" e$ y* x9 S
  4.     uint32_t sector_error = 0;
    ' A. ^" Q1 E2 Y# m* `$ r4 i5 N& s2 V
  5.     uint32_t t0, erase_cycles, write_cycles;
    & Y' k. `4 R6 ^9 A
  6. : r" N% Z& j8 s1 I! |% R9 b
  7.     /* 擦除计时 */
    ; W; ?4 P% ~# G3 D6 N
  8.     HAL_FLASH_Unlock();
    - X4 C2 q  J  Y$ Z1 t
  9.     erase.TypeErase = FLASH_TYPEERASE_SECTORS;
    ) b( A. g. r: R5 [" B" J: k' q
  10.     erase.Banks     = FLASH_BANK_2;
    ! w9 R7 d5 |: Q( ^+ p
  11.     erase.Sector    = FLASH_TEST_SECTOR;0 X# n2 D9 k0 v
  12.     erase.NbSectors = 1;
    + w, f8 I6 C( I9 I9 K0 g+ ^
  13. # t- t$ T) D+ Q: B" p; m+ }& `
  14.     t0 = DWT_GET();( U( k" c- P0 ?2 W$ {6 C0 B
  15.     HAL_FLASHEx_Erase(&erase, &sector_error);
    7 W$ T* N+ ^5 l% v0 ~
  16.     erase_cycles = DWT_GET() - t0;2 c6 U" C9 P5 ]
  17. " |1 g! Q! @/ J6 H* P, z
  18.     if (sector_error != 0xFFFFFFFFu)
    5 L3 o  z; r& M' Y; R
  19.     {
    * I1 n8 c1 \% s5 o) ]8 N  o
  20.         HAL_FLASH_Lock();
    - C% f( z& F$ ~/ {1 Q* `
  21.         printf("[3b] Flash Erase : FAILED (sector error 0x%lX)\r\n", sector_error);# {2 Q7 ]0 v' X5 U4 S. z: T
  22.         return;/ ^! E3 p* x( K( N
  23.     }
    4 |1 N: t0 ~, s

  24. 6 ?2 y! M, z' K* ]/ Q7 s4 K+ A
  25.     /* 写入计时: 每次写 16 字节,共写 FLASH_TEST_SIZE 字节 */
    & G  T9 e8 h) P2 V% z+ t: i  p
  26.     uint64_t pattern[2] = {0xDEADBEEFCAFEBABEull, 0x0123456789ABCDEFull};1 y, h: O' w! p
  27.     t0 = DWT_GET();
    ) ^: W/ A8 H, d& j5 C7 [- h
  28.     for (uint32_t offset = 0; offset < FLASH_TEST_SIZE; offset += FLASH_WRITE_UNIT)5 `+ `# k4 `- G8 Y& B4 i, i
  29.     {4 F0 Z6 @+ q- Y. x
  30.         HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD,
    " `, Z2 r/ f: U9 {7 x; m
  31.         FLASH_TEST_ADDR + offset,. `. S. B5 ^- w% a/ k9 t
  32.         (uint32_t)pattern);! A' e7 T$ A" k0 j2 Y5 p3 Z. w4 K
  33.     }
    ( ]3 R: c; G3 b& @$ P% k
  34.     write_cycles = DWT_GET() - t0;
    $ L5 {; w( w$ K. K7 Z2 G0 P3 A
  35.     HAL_FLASH_Lock();
    9 K6 z9 V* v2 C5 S# B, t

  36. . n/ d' n3 e; ~! N# T/ j  s& G" Z( F
  37.     uint32_t erase_ms = CYCLES_TO_NS(erase_cycles) / 1000000u;
    & ~3 {2 n7 n& s! G0 p/ o7 j" b
  38.     printf("[3b] Flash Erase : %lu cycles = %lu ms  (8KB)\r\n", erase_cycles, erase_ms);) V. f6 ~9 P, U
  39.     printf("[3b] Flash Write : %lu cycles -> %lu MB/s  (8KB)\r\n", write_cycles,% S3 \" u, [2 i
  40.         (uint32_t)((uint64_t)FLASH_TEST_SIZE * CPU_FREQ_MHZ * 1000000u / ((uint64_t)write_cycles * 1024u * 1024u)));' i. e/ U0 t& o/ c9 z$ D9 I9 }
  41. }
复制代码
  • 3. SRAM读取速度
    - _+ g8 [* \" E( L

) B5 q) S' S" Q! V6 ISRAM读取速度是通过一次性读取32kbyte来测试耗时. O4 _2 D; _& C# y% p9 L4 `
  1. static void run_sram_read_test(void)4 X4 f8 @* l) ~! G9 ?: U, I
  2. {
    9 }; f' V( B) S9 @" V9 u
  3.     const volatile uint32_t *src = (const volatile uint32_t *)mem_src;8 m8 Z  J/ e% b/ p' }, z. m
  4.     const uint32_t words = MEM_BUF_SIZE / 4u;
      D# V: B- i+ Q6 ^% A" [
  5. / p% q7 ]$ B! d' h
  6.     /* 先填充,避免读到全零被优化掉 */$ [/ h/ [  I, i2 N" G* X- f! U
  7.     for (uint32_t i = 0; i < words; i++)* H* O  u. f& U
  8.         ((volatile uint32_t *)mem_src)[i] = i;
复制代码
  • 4. SRAM写入速度4 K6 G' f0 f0 s* a- q, Y: l, Y
4 h: g6 C! @- N
SRAM写入速度是通过一次性写入32kbyte来测试耗时% [" S  x0 F. }' q# h3 \
  1. static void run_sram_write_test(void)
    ) S: I( o" Z# e3 T
  2. {
    6 {# V" j! n: ^4 C4 Q
  3.     volatile uint32_t *dst = (volatile uint32_t *)mem_dst;3 p2 @! A: N3 s# A7 K! ]
  4.     const uint32_t words = MEM_BUF_SIZE / 4u;
    ' g6 ]4 N2 k" e% e7 Z

  5. 2 K- G& h1 O3 e& {& P4 n; t% o
  6.     uint32_t t0 = DWT_GET();
    ; t  b+ V1 p! a. a$ u
  7.     for (uint32_t i = 0; i < words; i++)
    " [$ ^% o4 }, Y9 O
  8.         dst[i] = i;
复制代码
  • 5. DMA传输速度
    % `& _! ~1 B, \7 t5 C
9 F6 D  T# P; n
DMA传输是通过两个32kbyte大小的SRAM之间搬运数据,计算耗时& g2 Z8 [3 F7 P/ E
  1. static volatile uint8_t dma_done;; J0 O# [) C% @: @% f
  2. 0 v$ I2 g& o' C2 ]. S9 j$ T2 z
  3. void GPDMA1_Channel0_IRQHandler(void)
    ' T1 l( e& M' o. q
  4. {
    . F0 J. Y& H; F0 H/ d+ c! f
  5.     GPDMA1_Channel0->CFCR = GPDMA1_Channel0->CSR;  /* 清除所有标志 */4 q: n7 {- c, s! s' U& m
  6.     dma_done = 1;
    ( o6 j) ~: p6 e' L8 c5 W1 ^
  7. }2 r' ]# o8 n& |$ }3 y8 C2 Z( k
  8. 5 H3 H' P1 S3 {: v9 P2 P
  9. static void run_dma_test(void)
    7 k& e9 s  O* [' D! f- M
  10. {
    . K6 V6 Q5 k. c
  11.     /* 使能 GPDMA1 时钟 *// f* u2 v7 q5 j$ u$ b
  12.     __HAL_RCC_GPDMA1_CLK_ENABLE();
    ) S+ g1 [- ]$ j6 {4 s/ m
  13. ! S4 x% M/ r$ P- y
  14.     /* 初始化源缓冲区 */6 u" }' V6 t) s' S5 W
  15.     for (uint32_t i = 0; i < MEM_BUF_SIZE; i++)
      G8 v% K' J& k+ [
  16.         mem_src[i] = (uint8_t)i;
复制代码
最后编译代码,观察串口打印日志:
$ c% H3 I8 ?4 f/ V& g2 O3 a6 Z! G9 B% j6 a) ~5 A9 h8 t4 k' w, ^
[3] Memory Bandwidth Test (32 KB buffer).... W5 t! I! w6 f, F7 O
[3a] Flash Read  : 61639 cycles -> 126 MB/s: h' n: P+ ^& W
[3b] Flash Erase : 408500 cycles = 1 ms  (8KB)3 W6 e+ U/ g3 T
[3b] Flash Write : 90731 cycles -> 21 MB/s  (8KB)
3 K, y, M! {) G[3b] SRAM Write  : 40971 cycles -> 190 MB/s* V$ A" I) V, o% n/ q5 }1 \  j% p
[3c] SRAM Read   : 49283 cycles -> 158 MB/s
6 K$ G8 H% g) h: Y0 p( b, d/ e[3d] DMA Transfer: 45942 cycles -> 170 MB/s  (32 KB)9 L( U# m" k& J

  t  a! `% Y1 u; s* j3 c; X# u, K( h5 z( s0 H5 C, z% P
从测试结果来看,性能还是非常不错的。( U, U3 o' \5 }5 K# T
6 k# X/ ~; c0 B# x6 f6 I) e
赞 收藏 评论0 发布时间:2026-10-19 13:52

举报

0个回答

所属标签

相似技术帖

官网相关资源

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