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

【STM32H5 评测】CPU核心性能 - STM32H5E5跑 RTOS,观察任务切换速度、中断响应快慢

[复制链接]
无敌帅帅帅 发布时间:2026-10-19 10:53
很高兴收到了 NUCLEO-H5E5ZJ 开发板,参与评测。$ R: Q+ l4 V: g% N- G* o/ M8 q7 b

$ P' L, x+ x8 ?; C- g0 t, u这个新的开发板我遇到过两个问题:
  y' h2 n$ k$ F) ^1. STlink无法识别连接0 R6 m' h" K9 N

stlink

stlink

' {) M) w! S' B1 R, T2 L# f刚开始遇到这个问题我还以为是板子坏了,后来一想新板子怎么会坏呢,会不会是芯片太新了导致没识别到,后来升级了CubeProgrammer版本之后可以成功连接了- U, j2 k6 a7 @  ^9 j
2. 代码无法编译- D5 K; q6 x# ~' k
3795e2_image.png : h6 C" w8 k2 l+ L* A
编译报了一个故障,这里同样也是升级了CubeIDE版本之后解决的。4 k  f) Z$ J8 m3 d( P* s( P
3 X9 p6 W5 `3 V( ?" w0 _
用ThreadX作为RTOS测试) x/ z1 B+ J% x* e) P# ?% w
  • 接下来进行测试,首先创建工程代码:
    ( G9 W& i' T7 C4 @, Z, ?
8 e. X' m2 ~' q1 _; `2 }9 W1 J4 f
打开CubeMX工具,选择Board,这里选择H5E5ZJ板子,然后Without TrustZone,默认外设都选上。
$ r7 \, C8 n* P) ]2 O  ]1 w$ s 1.jpg 3.jpg 3 W% b: o8 d/ v' t
2.jpg 4 [/ U$ f: c9 F0 O
因为要用的RTOS,所以这里我选择了ThreadX作为测试用的RTOS。
) U9 v- |  Q4 s" T: |) T) V 4.jpg ( W. E* t' N) t5 Q; e* u4 W
配置的话修改了两个地方,一个是RTOS内存大小为10240,另外就是打开了初始化APP任务9 v, ~* k$ B9 S# ~# L3 l
5.jpg
# a( R* f& Y# R. [0 ]% i) L+ X3 cRTOS会用到systick中断,所以HAL原有的时基需要修改,这里改成TIM6为HAL使用
3 l8 P1 n. T. ^* B 6.jpg
6 K: v* |2 h& n最后就是需要修改时钟为250Mhz,这里填写250之后会自动解决时钟问题
; |; R4 o1 ]$ \; H 7.jpg
5 ?. G" l2 t& }( j: k我是生成的CubeIDE代码,生成完之后打开工程进行了一下编译,通过之后就可以写代码了。. t! g; i1 J: r0 Q! ?2 N, Q- \

2 e6 I) f7 u* X  [7 H' K
  • 第一项测试:任务切换速度
    7 }# t( K9 t# ]: ?
3 G8 n' z' D7 i" v! s8 R
核心思路: 用两个任务 + 两个信号量,构造一个"乒乓"结构,精确测量从一个任务放弃CPU到另一个任务真正开始运行之间的时间,使用DWT计时。# X& g9 V% P- F( T' L, v0 d" Q
DWT 计时是 Cortex-M 内核自带的 Data Watchpoint and Trace (DWT) 模块中的 CYCCNT 周期计数器来实现的高精度计时方法。
& E  v  y, E+ O* k: n7 P0 x4 R; T2 P
4 D+ [6 u# A9 W* BCPU 主频 = 250MHz
9 S$ K$ v/ y& w0 W  d# R) W! m% l1 个周期 = 4ns4 |# ]7 N& R3 ^5 U5 N

% D9 ^  J* N0 F
  1. static void task_a_entry(ULONG arg)
    / h& N6 x* h3 }0 y! w2 H; F+ C7 G
  2. {
    2 i* m* C$ X6 h  K6 e4 n+ F! ?+ Q0 ^% N
  3.     (void)arg;
    , v- M. Y' N4 Q7 D# G8 B& ]
  4.     while (switch_count < SWITCH_ITERATIONS)
    $ a! M8 o) g: g6 S, Z7 |" H, e
  5.     {
    " q7 j: z, w# g3 u: k
  6.         switch_start_cycle = DWT_GET();
    1 y; Q' U* Z3 Z, T
  7.         tx_semaphore_put(&sem_a2b);' S+ D0 i" ]4 S. w
  8.        tx_semaphore_get(&sem_b2a, TX_WAIT_FOREVER);. o" `% d$ e0 ?) ^5 V1 u8 m2 G
  9.     }
    - |7 O5 R& H- M9 ^
  10.     tx_thread_suspend(&task_a);
    4 d$ Y8 k0 `- j' J: A
  11. }! ?: F4 F% c; s& r  a3 l

  12. 9 O7 k# ^  y  Z0 X
  13. static void task_b_entry(ULONG arg)
    8 p( ?5 n) Y) f  M5 x& d
  14. {; H+ T9 o1 s0 V6 C# n
  15.     (void)arg;
    : r  O3 ~: B) m' G: D+ |/ K9 M* @
  16.     while (switch_count < SWITCH_ITERATIONS); h" h3 p9 I6 q: X9 D, p5 n9 k
  17.     {
    ! A, S# y5 X! x6 \  C6 v
  18.         tx_semaphore_get(&sem_a2b, TX_WAIT_FOREVER);3 [1 E1 S/ d' {( C% J  o2 f% J
  19.         switch_samples[switch_count] = DWT_GET() - switch_start_cycle;
    2 l" z, W- r# v+ u3 u1 I5 w
  20.         switch_count++;
    * j  V- s6 r0 ^) S" L
  21.         tx_semaphore_put(&sem_b2a);
    : ]$ `( c# E, Q* e
  22.     }
    1 I5 o3 m5 [3 j! X
  23.     tx_thread_suspend(&task_b);
    ' L& Y4 Y  I' A: Q% p# O
  24. }
复制代码
A/B任务优先级都是1,高于定时器线程之外的一切,一共测试1000次。这里使用的信号量来回切换任务
, G1 ?9 r% c: R! B  E7 x8 e" T! K* l
  • 第二项测试:中断响应速度
    " r% r4 Q% u! b/ p' [

% {# V+ i5 Q( Q3 A2 S! C主要测试的是从触发中断的那条指令执行完到ISR 第一条指令开始执行之间的时间,同样使用DWT计时。3 b0 H. {7 l4 j  G  R+ E/ j
这里直接使用NVIC_SetPendingIRQ,写 NVIC 的 pending 寄存器,绕过外设,测出来的是纯粹的 CPU 中断响应时间,更干净。
* c/ g& P# A# a- r  M9 b$ Q$ p7 }
  1. #define TEST_IRQ_NUM    TIM7_IRQn   /* 软件触发,TIM7 未被项目使用 */6 k7 X% v( I" R7 o1 m/ J, m
  2. % P. R1 G; V2 _2 ~( o
  3. void TIM7_IRQHandler(void)
    * }/ v8 w' i& m) y: R9 m; ^( e" L
  4. {, p# l, h3 n, s0 ^' ~$ y* L$ d
  5.     irq_samples[irq_count] = DWT_GET() - irq_trigger_cycle;6 Z7 y4 H; O2 M/ j
  6.     irq_count++;
    . n, W+ T+ ]* @( S% T; Y& s2 g
  7.     NVIC_ClearPendingIRQ(TEST_IRQ_NUM);
    ( z5 u! h+ A5 V3 E
  8. }
      s; `- o; E1 Q
  9. static void run_irq_test(void). a: J: {' F- u6 o- V
  10. {
    " O+ L' @4 d# o: A% {2 R
  11.     irq_count = 0;
    $ l9 K! [& s4 F7 W. c

  12. & d# w2 U: H6 w& _) ?) b
  13.     NVIC_SetPriority(TEST_IRQ_NUM, 0);/ v  @: ?6 I( p' M; {/ Q6 h
  14.     NVIC_EnableIRQ(TEST_IRQ_NUM);: Z9 R9 J$ D: {8 h, j" J6 q- B
  15.     for (uint32_t i = 0; i < IRQ_TEST_ITERATIONS; i++)" V/ }3 C& [" b9 l; j0 d
  16.     {
    7 F0 g* I# k  c9 N% s, i/ ]6 T* V% w
  17.         irq_trigger_cycle = DWT_GET();
    - ~% n% n! h' a7 F; O! {
  18.         NVIC_SetPendingIRQ(TEST_IRQ_NUM);, I3 F/ V/ l/ s1 o5 g: ~
  19.         while (irq_count <= i)
    - g  k* v5 f5 o' q3 {
  20.             __NOP();  p. J& V- Q; m* a) r
  21.     }. g" |$ {& O/ @5 A$ F+ h+ N& k9 r% h. F
  22.     NVIC_DisableIRQ(TEST_IRQ_NUM);4 `# o# Q5 q( M/ [
  23.     print_percentiles("[2] IRQ Latency", irq_samples, IRQ_TEST_ITERATIONS);
    $ \: Z8 t1 |6 L" G
  24. }% b1 K4 Q3 o$ s7 Z+ h
复制代码
也是测量1000次。
3 P+ k( ?2 b" ~& f8 @& }8 K) Z: R  `然后编译运行结果如下:1 @% Y8 ?. T, ~9 J# b: ~6 M

+ p+ x) i! s$ Y+ ~7 K========================================
) Z% C& A0 f- M  STM32H5E5 CPU Performance Test' U4 k0 C/ w8 U
  Core: Cortex-M33 @ 250 MHz
" f+ u7 L+ |4 ?& N; ^! y: W" q: P  RTOS: Azure RTOS ThreadX
; z+ K9 a3 k, H* J; M========================================! G/ e# v1 X; y9 j" }$ f3 U# d
9 i! t% N& B9 o& c/ l
[1] Task Context Switch Test (1000 iterations)...  j/ b# k! d4 `3 A; Z# E
[1] Task Switch (n=1000):
# L, c0 B, `' x, a. X. b" S' V4 x  P50  =  656 cycles =  2624 ns
! x- b/ {6 _6 J$ e+ a& Q  P95  =  656 cycles =  2624 ns& e2 A; a2 N6 i- U8 \! a3 K
  P99  =  656 cycles =  2624 ns
5 _' W5 [/ c9 ?# ?* o! z" T  MAX  = 6586 cycles = 26344 ns3 R$ ^' R& {! ]2 l6 T8 L- A

4 S, [8 w1 J1 k9 o[2] IRQ Response Latency Test (1000 iterations)...1 V' N# K. z' u  l( i7 l8 s
[2] IRQ Latency (n=1000):! V* l" j5 v8 j) m2 p  N
  P50  =   47 cycles =   188 ns) {4 ]4 N1 E9 v
  P95  =   47 cycles =   188 ns& ~5 A% O4 P1 q8 s
  P99  =   47 cycles =   188 ns
9 m: O4 A/ T3 u6 u0 O( o6 x& s  MAX  =   90 cycles =   360 ns- B- `) o2 \0 Z2 \: K( F% [* K

' W( p: ~3 t$ m5 w! K7 g3 k# x3 f# U1 J
* V0 S& n/ F1 [; T9 K% W$ q这里P50/P95/P99表示在这1000个点中有百分之多少的值小于等于后面的值,比如P50 = 656cycle,也就是有50%的值小于等于656cycle。
9 O& {+ j4 U( @所以数据看着还是很稳定的,99%的值都是稳定的,MAX这个值就是异常值,我猜测可能是systick中断插入其中导致的,这个可以忽略。' j. B# L/ M: Z, {" w' q5 v

+ c) c; v: _: |7 F# e但是这个测量值会不会有点长,任务切换需要2.6us,以前也没测过这个,看看能不能优化一下,比如改改编译配置什么的。& p8 E4 @% P( L
% l# s8 ]9 [4 ?" m9 @
于是我尝试修改编译优化,关闭FPU,因为FPU上下文保存会占用cycle,修改如下:
7 @( b, i# u0 F, N- H# a 8.jpg 9.jpg
4 s7 L! w6 x: c8 {& b0 x6 o然后重新编译烧录运行结果如下:% g( H' |: M% K: q9 {

, \/ O3 B$ ~2 w========================================, ~5 L2 K! o' k2 E0 T2 g
  STM32H5E5 CPU Performance Test
% ^2 j" X8 v; h) A1 @) c2 B  Core: Cortex-M33 @ 250 MHz
- I  g& m$ m6 ?; n8 A/ ~  RTOS: Azure RTOS ThreadX4 \5 h: v& h5 P; B
========================================& E2 d! z  I- B5 a/ L% \' h, B7 ~

+ z1 Q4 b4 O9 h( w7 F5 Z[1] Task Context Switch Test (1000 iterations)...0 a& F" b7 n( b/ Y2 n
[1] Task Switch (n=1000):
# N( p; V& }+ _+ H* \  P50  =  380 cycles =  1520 ns1 l- h5 X+ |9 {( T9 h% X
  P95  =  380 cycles =  1520 ns. D1 B. D/ r: \+ h/ _9 Y2 u$ S
  P99  =  380 cycles =  1520 ns5 E5 U- U8 \6 v+ N2 T, M" F# B% k6 Z
  MAX  = 5833 cycles = 23332 ns
% t6 a3 c  F  `. x# y
- L( W, u1 ]. h; ][2] IRQ Response Latency Test (1000 iterations)...
, X& o' \, v% w# g1 d[2] IRQ Latency (n=1000):
  F1 g/ S8 s" w6 h  P50  =   22 cycles =    88 ns/ A/ \2 [! R7 p
  P95  =   22 cycles =    88 ns/ N2 ]: w# k5 Y/ Z* Z' f
  P99  =   22 cycles =    88 ns
& X/ `/ A0 b# D0 z, c  t: P/ Q  MAX  =   41 cycles =   164 ns
& t: _& f( G6 z$ D
0 U) Q/ h0 Q3 y
7 _' A' v" o2 F! N/ M6 `! K8 A修改之后确实快了很多啊,P99就能看出性能还是非常稳定的。
" x( L5 Y9 V) k整个测试还是比较简单,当然应该还有不同的测试方法,可能还可以继续优化提升性能。( g- A  C; m% _+ l$ \
. O, ^4 \' |& C1 a

0 F/ [/ c, v, J" v5 ^6 M  e" V7 T1 s: r$ X4 }4 q1 B+ h
赞 1 收藏 评论0 发布时间:2026-10-19 10:53

举报

0个回答

所属标签

相似技术帖

官网相关资源

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