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

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

[复制链接]
STMCU小助手 发布时间:2022-5-6 09:33
1 概述
: ^) s& G/ c# _6 N3 p1.1 资源概述
/ W1 z4 ?2 U7 Q; C" g2 u
开发板:ST官方NUCLEO-F103RB开发板
( K! ^0 A) k3 Y6 i, Y6 C  `CUBEMX版本:1.3.0
" T2 c! O7 {6 @" D! T3 V! EMDK版本:5.23
2 e+ J1 ~9 K) ?$ W9 k4 w5 h主控芯片型号:STM32F103RBT60 X5 t  o$ v) i+ c% b1 g5 U1 Y2 G3 L
  I' _) |' s) A: T0 \; G
{X`AM`Z~~2LPEW)NPKLWW.png # n3 `0 W6 S  M1 P/ P; W2 v) n
! O4 z4 ?) V# ]* g
1.2 SWO功能简介
5 @( g" b( ?% Q' V% U' ]: v) w8 ^SWO也叫做trace(跟踪)功能,通过此功能,只需要在SWD调试基础上增加一条SWO线缆,就可以实现类似串口输出功能,配合printf函数打印相应的信息到utility窗口中。此功能不占用串口资源,无需在中断中执行。
6 m/ j/ Z3 z' G* Q7 D7 b* {0 u+ v/ |0 C& ^) K, X# z$ u0 o; s  H+ [1 n4 X
1.3 ITM(指令跟踪微单元)简介
, w$ e6 `" u( a4 Y+ d- U4 _: |我们此次功能实现是通过调用ITM实现的。' v/ Q" v. k2 E; N3 p
ITM是一应用驱动的跟踪源,它支持printf类的调试手段来跟踪操作系统(OS)和应用事件,并发布判定的系统信息。ITM以包的形式发布跟踪信息,它由以下部分组成:
% j% A9 G( F. f3 C5 o. _● 软件跟踪:软件可以通过直接写ITM激发寄存器来发布包信息。
. v% f, g* u0 R( s● 硬件跟踪:ITM会发布由DWT产生的信息包。3 G- S1 f" ?7 U! p) O2 ?. l& r: E5 u
● 时间戳:时间戳被发布到相应的包上。ITM包含一个21位的计数器以产生时间戳。Cortex-M3的时钟或串行线观测器(Serial Wire Viewer)的位时钟率给计数器提供时钟。3 L  Q: R( {5 u. ?' t9 W
由ITM发送的信息包输出到TPIU(Trace Port Interface Unit),TPIU再添加一些额外的包(参考TPIU),然后输出完整的包序列给调试器。11 k7 _- k2 ~0 b0 N* _
# g. Q4 [: ~1 H) h+ k6 m2 g
1.4 实现功能7 l7 C" A6 f- L3 j8 W# @
本次程序实现的功能如下9 T# y1 S1 o8 \4 ?% p- M# P
1、复位后,向Serial Wire Viewer(utility)打印信息;
& w9 G$ }' y5 m' J4 s5 @2、按按键BUTTON,LED2灯实现翻转;
8 a: [. e; K5 {" y. X+ W9 p; N. v% t对于第二条实现,此次文档不详细描述。
/ o: M4 _) f0 |9 J/ M* t8 L
6 Q! D  ?" `; O5 R5 q" b2 硬件连接以及CUBEMX配置
$ _' D; Q0 \  U7 l  W: L
2.1 硬件连接
1 D) x9 r  Q: m2 y: ]& h: O* t( s
开发板内部已经将线接好,如下图所示
; O) H$ Z6 O: d0 U7 d! \
  W' f8 n0 W* u; t1 O/ @对于目标板与STLINK仿真器分开的情况,我们需要使用5根线进行连接,如下表所示。" C6 i4 X0 T" Q- ]# W% e2 L

& q1 U! s* G% S" f1 v$ h1 U0 S- ] ~S)7I4Z$OBTE~(VAQ4~J%6R.png
' U) b1 ?6 a5 q$ A2 F6 G4 n2 `. p+ _$ x# U; I
2.2 CUBEMX配置
) M4 k) ?6 `4 I9 y. |选择异步跟踪模式,此时PB3将会自动定义为SWO端口。8 |/ }$ C( o2 F4 A  Q3 r! H

. O8 K. g2 p/ o+ y 2BNOGTP)$Y@7M7@$JB07H`W.png
" C, r1 i5 t0 z# K4 @: G9 ^& U" Q3 b6 B4 v; l, X
3 软件开发2 Z/ R3 [5 R4 |. L. ~: J5 W7 @6 ^  _
3.1 KEIL软件设置
+ M# n' w0 H, i/ g1 F+ S, H
KEIL软件设置如下,这里由于程序使用的内部HSI,系统频率是64MHz,因此填写64MHz,需要根据实际情况进行填写。$ {2 U* s3 U, \3 T" e9 f: p" p- A5 w1 A

, K; W2 O  K- v$ R 94R{}LIQZ%R][HD_M_VT6$A.png 6 l6 B5 a  \* d1 @7 e
' k" e/ h; z, h; [* |' c
3.2 程序设计
  |5 F! A! x3 K4 O/ X% \使用CUBEMX生成代码。在主函数中进行修改。
% X0 P% s2 U% z8 v: x主程序中包含stdio.h函数的头文件,否则将不能识别printf函数。4 B/ g0 t4 @4 J, O% I
3 H+ U* f' l% R
  1. #include "stdio.h"
复制代码
9 ?  G8 l# h. `3 L
fputc 函数宏定义。
. r4 a' h+ p, ^& R
/ \6 C% }# V& ^- X: R* }
  1. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
复制代码

0 {7 b, W, P# A7 x0 A函数定义,由于printf调用的是fputc函数,通过这么一个转换,printf函数就能调用ITM函数实现输出功能。
  1. PUTCHAR_PROTOTYPE
    & R# I, L; Z: f: g8 d
  2. {
    9 |  o; e' \" d, v7 l7 T2 y
  3.   ITM_SendChar(ch);* V1 R$ N( [2 w! [0 Z
  4.   return ch;
    ( {: ^0 Q- Z, Q' _! M
  5. }
复制代码
+ y; I( R( P0 r7 t7 ^- M' `1 j
TIM_Sendchar()函数在core.cm3.h头文件中有进行定义,如下所述
) j  W! I' I5 ]# x8 C0 t7 G
2 H! d+ b) {0 }* f% N
  1. __STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)( p% |- v* C1 J- Q7 q+ o
  2. {) |- b9 U5 L0 n  v# f" j2 L
  3.   if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) &&      /* ITM enabled *// y5 C6 }2 D2 b2 E9 c
  4.       ((ITM->TER & 1UL               ) != 0UL)   )     /* ITM Port #0 enabled */- J2 L. r' D1 q3 w! c4 i1 f! z
  5.   {1 \# E# c& Y, [$ L% v) ^0 u: p
  6.     while (ITM->PORT[0U].u32 == 0UL)" g9 ]; E6 i1 f& _2 @! F7 B
  7.     {
    , h9 s2 i& ^- V0 y6 ?0 n6 [
  8.       __NOP();
    . ?5 N1 K; N2 U+ H
  9.     }! u6 o; c( t9 _: \
  10.     ITM->PORT[0U].u8 = (uint8_t)ch;
    ; ?; G% ]% I9 b% S; ]& z; N
  11.   }$ |* B) z* X  {6 }7 C6 C  R! v. F( z0 p# ~
  12.   return (ch);. \& e3 U: G7 Z: {
  13. }
复制代码
, F( L3 M* b7 J9 e; g6 Y
在主函数main()中增加printf函数,实现输出。8 i$ p& L2 M0 [) }; q" i
% {9 {+ e" x& B7 E6 j5 O
  1. printf("** Test finished successfully. ** \n\r");
复制代码

0 b0 H! J9 T5 `* l, D$ o4 实验结果与总结

1 P; J5 a, j* j9 L& H, ]3 _1 W! t/ [4.1 实验结果
8 d9 U; x1 I3 p; `/ ^% g! r
打开utility软件,点击printf via SWO viewer。$ ^! @3 X/ ?5 {9 S) G( K; ?% b; }
' z) q2 I5 i% q; I1 }1 N2 R3 W: ~
Z_BSU4B137~`(900%S_WI$Y.png : l! |! M7 d' r4 A$ S

- Y! n, _: Y$ E5 ?8 |5 O6 _设置频率,点击Start,将调试板复位(程序设置只运行一次printf,因此每输出一次均需要重新复位),即可发现SWV窗口输出了相应的信息。
: W0 b  v/ q* l8 A/ R3 l0 J# ^
6 N6 l" L! P8 f! f S(7WHRURI(F7U{YX34V5_GO.png + {2 Y( R% J# i  i! y8 U- l' }
. U1 n+ e& M! _$ P
4.2 总结  o9 P+ n: ^, B; b
在传统的调试中,我们可能偏向于断点分析或者LED灯的亮灭来判定程序运行状态,但是都不是太直观,对于程序越大越不好操作。使用这个SWO功能能很大程序解决这个问题。我们可以在各种错误处理函数增加相应的提示信息,协助我们进行软件开发工作。
1 n0 Q6 f/ x% J( h8 |
9 s5 D' ?# s9 f! R: Q9 G" F1 X3 M! t( r; _1 |7 I5 t1 w
# m% S  C! ~2 e6 _( U
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 手机版