整个测试分为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
- #define MEM_BUF_SIZE (32u * 1024u) /* 32KB,足够体现带宽,不超 SRAM */& [4 B* T T2 l% e+ w! w- Q
! K8 E8 l" ~0 T; N% t- static void run_flash_read_test(void)
0 d/ g' \6 q, c - {! X3 B, T" w- r- ~, |2 Z8 m8 w$ o
- const volatile uint32_t *src = (const volatile uint32_t *)0x08010000;& n$ b+ i% v" ^/ k) {1 T
- const uint32_t words = MEM_BUF_SIZE / 4u;
/ ~ k' W+ e7 o5 v- j
. L. t7 \7 o3 P3 |. _- A2 B- uint32_t t0 = DWT_GET();
3 ^( U- i" [2 o5 f. P8 I4 p - for (uint32_t i = 0; i < words; i++)' t3 R* ?5 C; v9 F8 [
- mem_dst[i] = src[i];# a% \* t+ ?3 s! |; b
- uint32_t cycles = DWT_GET() - t0;" k$ t' k# B5 r5 Q
- 5 _# y6 h o6 W5 |' I% I, d: X0 u
- 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
- }
复制代码- 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- static void run_flash_write_test(void)! f3 [/ X2 g& v
- {0 y, @. m+ N- G7 \4 y0 [" F
- FLASH_EraseInitTypeDef erase = {0};: J6 j" e$ y* x9 S
- uint32_t sector_error = 0;
' A. ^" Q1 E2 Y# m* `$ r4 i5 N& s2 V - uint32_t t0, erase_cycles, write_cycles;
& Y' k. `4 R6 ^9 A - : r" N% Z& j8 s1 I! |% R9 b
- /* 擦除计时 */
; W; ?4 P% ~# G3 D6 N - HAL_FLASH_Unlock();
- X4 C2 q J Y$ Z1 t - erase.TypeErase = FLASH_TYPEERASE_SECTORS;
) b( A. g. r: R5 [" B" J: k' q - erase.Banks = FLASH_BANK_2;
! w9 R7 d5 |: Q( ^+ p - erase.Sector = FLASH_TEST_SECTOR;0 X# n2 D9 k0 v
- erase.NbSectors = 1;
+ w, f8 I6 C( I9 I9 K0 g+ ^ - # t- t$ T) D+ Q: B" p; m+ }& `
- t0 = DWT_GET();( U( k" c- P0 ?2 W$ {6 C0 B
- HAL_FLASHEx_Erase(&erase, §or_error);
7 W$ T* N+ ^5 l% v0 ~ - erase_cycles = DWT_GET() - t0;2 c6 U" C9 P5 ]
- " |1 g! Q! @/ J6 H* P, z
- if (sector_error != 0xFFFFFFFFu)
5 L3 o z; r& M' Y; R - {
* I1 n8 c1 \% s5 o) ]8 N o - HAL_FLASH_Lock();
- C% f( z& F$ ~/ {1 Q* ` - printf("[3b] Flash Erase : FAILED (sector error 0x%lX)\r\n", sector_error);# {2 Q7 ]0 v' X5 U4 S. z: T
- return;/ ^! E3 p* x( K( N
- }
4 |1 N: t0 ~, s
6 ?2 y! M, z' K* ]/ Q7 s4 K+ A- /* 写入计时: 每次写 16 字节,共写 FLASH_TEST_SIZE 字节 */
& G T9 e8 h) P2 V% z+ t: i p - uint64_t pattern[2] = {0xDEADBEEFCAFEBABEull, 0x0123456789ABCDEFull};1 y, h: O' w! p
- t0 = DWT_GET();
) ^: W/ A8 H, d& j5 C7 [- h - for (uint32_t offset = 0; offset < FLASH_TEST_SIZE; offset += FLASH_WRITE_UNIT)5 `+ `# k4 `- G8 Y& B4 i, i
- {4 F0 Z6 @+ q- Y. x
- HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD,
" `, Z2 r/ f: U9 {7 x; m - FLASH_TEST_ADDR + offset,. `. S. B5 ^- w% a/ k9 t
- (uint32_t)pattern);! A' e7 T$ A" k0 j2 Y5 p3 Z. w4 K
- }
( ]3 R: c; G3 b& @$ P% k - write_cycles = DWT_GET() - t0;
$ L5 {; w( w$ K. K7 Z2 G0 P3 A - HAL_FLASH_Lock();
9 K6 z9 V* v2 C5 S# B, t
. n/ d' n3 e; ~! N# T/ j s& G" Z( F- uint32_t erase_ms = CYCLES_TO_NS(erase_cycles) / 1000000u;
& ~3 {2 n7 n& s! G0 p/ o7 j" b - printf("[3b] Flash Erase : %lu cycles = %lu ms (8KB)\r\n", erase_cycles, erase_ms);) V. f6 ~9 P, U
- printf("[3b] Flash Write : %lu cycles -> %lu MB/s (8KB)\r\n", write_cycles,% S3 \" u, [2 i
- (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 }
- }
复制代码- 3. SRAM读取速度
- _+ g8 [* \" E( L
) B5 q) S' S" Q! V6 ISRAM读取速度是通过一次性读取32kbyte来测试耗时. O4 _2 D; _& C# y% p9 L4 `
- static void run_sram_read_test(void)4 X4 f8 @* l) ~! G9 ?: U, I
- {
9 }; f' V( B) S9 @" V9 u - const volatile uint32_t *src = (const volatile uint32_t *)mem_src;8 m8 Z J/ e% b/ p' }, z. m
- const uint32_t words = MEM_BUF_SIZE / 4u;
D# V: B- i+ Q6 ^% A" [ - / p% q7 ]$ B! d' h
- /* 先填充,避免读到全零被优化掉 */$ [/ h/ [ I, i2 N" G* X- f! U
- for (uint32_t i = 0; i < words; i++)* H* O u. f& U
- ((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 \
- static void run_sram_write_test(void)
) S: I( o" Z# e3 T - {
6 {# V" j! n: ^4 C4 Q - volatile uint32_t *dst = (volatile uint32_t *)mem_dst;3 p2 @! A: N3 s# A7 K! ]
- const uint32_t words = MEM_BUF_SIZE / 4u;
' g6 ]4 N2 k" e% e7 Z
2 K- G& h1 O3 e& {& P4 n; t% o- uint32_t t0 = DWT_GET();
; t b+ V1 p! a. a$ u - for (uint32_t i = 0; i < words; i++)
" [$ ^% o4 }, Y9 O - 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
- static volatile uint8_t dma_done;; J0 O# [) C% @: @% f
- 0 v$ I2 g& o' C2 ]. S9 j$ T2 z
- void GPDMA1_Channel0_IRQHandler(void)
' T1 l( e& M' o. q - {
. F0 J. Y& H; F0 H/ d+ c! f - GPDMA1_Channel0->CFCR = GPDMA1_Channel0->CSR; /* 清除所有标志 */4 q: n7 {- c, s! s' U& m
- dma_done = 1;
( o6 j) ~: p6 e' L8 c5 W1 ^ - }2 r' ]# o8 n& |$ }3 y8 C2 Z( k
- 5 H3 H' P1 S3 {: v9 P2 P
- static void run_dma_test(void)
7 k& e9 s O* [' D! f- M - {
. K6 V6 Q5 k. c - /* 使能 GPDMA1 时钟 *// f* u2 v7 q5 j$ u$ b
- __HAL_RCC_GPDMA1_CLK_ENABLE();
) S+ g1 [- ]$ j6 {4 s/ m - ! S4 x% M/ r$ P- y
- /* 初始化源缓冲区 */6 u" }' V6 t) s' S5 W
- for (uint32_t i = 0; i < MEM_BUF_SIZE; i++)
G8 v% K' J& k+ [ - 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
|