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

【经验分享】STM32开发,通过SWO功能输出Printf函数到Utility

[复制链接]
STMCU小助手 发布时间:2022-5-6 09:33
1 概述5 D" `* R- z, m9 d9 V  c
1.1 资源概述
; @$ N. U1 r9 y8 U! h
开发板:ST官方NUCLEO-F103RB开发板
; E1 |/ r7 Z8 v/ Q  \- QCUBEMX版本:1.3.02 U3 @# i; T; |. p" S) M( M1 p
MDK版本:5.23/ `. p- p4 }  ]. x% I! p* b
主控芯片型号:STM32F103RBT6
1 y) j# P& f8 Y. h9 E
( P4 g4 `* ?/ V+ n8 K {X`AM`Z~~2LPEW)NPKLWW.png
; t- ^7 u7 }# Y- `, [7 N. J' d0 I. [5 Z2 s7 N/ v
1.2 SWO功能简介3 Q- ^7 P5 ~& L" T- ]; R3 w+ u
SWO也叫做trace(跟踪)功能,通过此功能,只需要在SWD调试基础上增加一条SWO线缆,就可以实现类似串口输出功能,配合printf函数打印相应的信息到utility窗口中。此功能不占用串口资源,无需在中断中执行。0 `! @  ^* q$ S7 {
9 m* Q# \- d- G9 u
1.3 ITM(指令跟踪微单元)简介
- l$ F% G8 }7 b! N% a0 W. ]我们此次功能实现是通过调用ITM实现的。
( d) E( d4 n9 H! z) KITM是一应用驱动的跟踪源,它支持printf类的调试手段来跟踪操作系统(OS)和应用事件,并发布判定的系统信息。ITM以包的形式发布跟踪信息,它由以下部分组成:
- [+ d1 e2 W. C: _, v0 f  R● 软件跟踪:软件可以通过直接写ITM激发寄存器来发布包信息。
; I+ ]6 d+ B9 ^9 o: d● 硬件跟踪:ITM会发布由DWT产生的信息包。% w8 o8 p; f& C- o: [& c4 Q" ^. @
● 时间戳:时间戳被发布到相应的包上。ITM包含一个21位的计数器以产生时间戳。Cortex-M3的时钟或串行线观测器(Serial Wire Viewer)的位时钟率给计数器提供时钟。9 \8 S$ G* H9 w. H% _
由ITM发送的信息包输出到TPIU(Trace Port Interface Unit),TPIU再添加一些额外的包(参考TPIU),然后输出完整的包序列给调试器。1
2 l' W; f+ O7 g7 W; [# l
- d$ J7 O2 d$ {2 J0 m- c7 E1.4 实现功能% _, t1 {2 ~1 K; b+ U
本次程序实现的功能如下- u. _: f$ r: _* H0 D6 Y( B& t
1、复位后,向Serial Wire Viewer(utility)打印信息;$ q! [3 W- n6 H. ~1 l$ p
2、按按键BUTTON,LED2灯实现翻转;
/ N, @" F) B" F. @  s. |对于第二条实现,此次文档不详细描述。" G) w- X. x6 t4 w' s# w0 c' t

5 H6 K( ?2 W* h& \2 硬件连接以及CUBEMX配置
3 V% |% I5 {1 H) f3 P+ W
2.1 硬件连接
  t/ H- p( Y2 K
开发板内部已经将线接好,如下图所示
, T7 y! z% j' c' Z4 e) x  s  Q4 E$ o% }- o
对于目标板与STLINK仿真器分开的情况,我们需要使用5根线进行连接,如下表所示。: Y# ^9 \1 L4 c9 |3 e8 @' J/ s
. B' C3 p# t+ S  ]  w) s7 b. K
~S)7I4Z$OBTE~(VAQ4~J%6R.png ; q" a/ P5 ~) G8 {! W% g
! T0 o' {* ~! y. O4 S  C
2.2 CUBEMX配置
7 t9 g7 O3 i- p. }  J( @3 [选择异步跟踪模式,此时PB3将会自动定义为SWO端口。; c$ c1 t( |+ x! h' ]

' G, O% }# T* g- d7 y: M7 C 2BNOGTP)$Y@7M7@$JB07H`W.png ! r2 s7 Y, H$ d4 z
5 h) [: E, ?& R: C4 q1 ]
3 软件开发
& R/ l/ H: ^1 s( v7 }3.1 KEIL软件设置

' \: C  B: c7 `( a' }KEIL软件设置如下,这里由于程序使用的内部HSI,系统频率是64MHz,因此填写64MHz,需要根据实际情况进行填写。9 e6 _% W) i, d( a7 m

5 S2 q- w7 |& n0 i, J: l! g 94R{}LIQZ%R][HD_M_VT6$A.png . E; \1 ^) C% S; }7 }! g

% o2 B* C( e+ I: }0 q6 @; J3.2 程序设计
( ?7 Y! f9 y) o3 `8 V4 E使用CUBEMX生成代码。在主函数中进行修改。/ Z1 o& _9 u  N& S" _! R7 S7 `
主程序中包含stdio.h函数的头文件,否则将不能识别printf函数。
/ l: z4 n, ]! N  B* Y$ @. {" L+ L! O: y+ I1 T2 U, r7 d8 V4 G
  1. #include "stdio.h"
复制代码

" q) |$ p& r/ t: b5 ~fputc 函数宏定义。
' K+ P9 ^2 p; S9 Z9 f9 J
8 e8 [6 G+ @0 k
  1. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
复制代码
  {* k! O1 n, U. R8 S- ]4 |0 z8 u
函数定义,由于printf调用的是fputc函数,通过这么一个转换,printf函数就能调用ITM函数实现输出功能。
  1. PUTCHAR_PROTOTYPE
    $ h' @& W& W1 k9 S0 n
  2. {0 R1 O2 n% q+ m  s8 d
  3.   ITM_SendChar(ch);0 A$ E) R( n/ P; I/ {
  4.   return ch;
    ) G3 D) g$ [+ |, O* Y# k
  5. }
复制代码

  I1 |( A8 C1 ITIM_Sendchar()函数在core.cm3.h头文件中有进行定义,如下所述
4 K  V4 a1 m. z* _: b8 a, f% B  G  {1 U
  1. __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
    ( g* J% q/ t" |- I
  2. {9 s( z8 a0 F8 u9 ?# e  W
  3.   if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled */- G6 }' X( h3 e* m6 i" }) V
  4.       ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */
    6 V8 E4 D1 _7 C% p0 e4 q2 s4 c
  5.   {7 m  r: B' I: I8 B9 z2 O
  6.     while (ITM->PORT[0U].u32 == 0UL)
    . @' b0 l& D1 X# {0 P
  7.     {
    ) P( D1 n/ Q# r. t
  8.       __NOP();. k' @! \8 G) R0 v0 t
  9.     }3 ^3 O$ v" a/ R# F  ^
  10.     ITM->PORT[0U].u8 = (uint8_t)ch;/ \$ @% K" k' Y0 I; o3 r
  11.   }
    7 B9 E& a+ p( v. @0 v0 J
  12.   return (ch);% S! F  w# r( o
  13. }
复制代码
. x% j+ u( T$ d! |' `
在主函数main()中增加printf函数,实现输出。8 T% A) v. P6 n, Z6 H

4 h8 L& o! `! p: {3 b0 t4 d
  1. printf("** Test finished successfully. ** \n\r");
复制代码

5 e* k- x) d% _; Q1 c9 C) g4 实验结果与总结

8 o& W  a# j2 }* D4.1 实验结果

# O/ O2 m, M8 K  }+ L打开utility软件,点击printf via SWO viewer。5 N2 u8 p/ @9 m- {9 R/ H) o# H3 T' H
9 w2 ?8 E( J8 B' O( \7 c
Z_BSU4B137~`(900%S_WI$Y.png
9 X9 C1 b5 l0 [- ~& y/ u: A. c% G# `0 N) k
设置频率,点击Start,将调试板复位(程序设置只运行一次printf,因此每输出一次均需要重新复位),即可发现SWV窗口输出了相应的信息。
2 \- _  G% v! l0 w* ]0 Z" i3 i6 D; @$ x8 s# _# A9 L
S(7WHRURI(F7U{YX34V5_GO.png
6 K: I# _$ P! S2 c  x- {6 Q3 t1 ^& K. s( Y  H) X
4.2 总结
# z8 e  `& o, M  H6 r8 i& g在传统的调试中,我们可能偏向于断点分析或者LED灯的亮灭来判定程序运行状态,但是都不是太直观,对于程序越大越不好操作。使用这个SWO功能能很大程序解决这个问题。我们可以在各种错误处理函数增加相应的提示信息,协助我们进行软件开发工作。
+ I- B8 h+ c. i4 l4 }% ~+ h7 o( O- T, V7 F
) g5 |% ^  B' o7 k  P. A: v

% @" o% j0 X2 a& V
8P7$UNOG]BI_8I709}5B_B0.png
SZZ~WX0Z5%N4N8T8R1BSDAU.png
赞 收藏 评论0 发布时间:2022-5-6 09:33

举报

0个回答

所属标签

相似技术帖

官网相关资源

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