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

【经验之谈】基于STM32 jlink RTT使用详解的经验分享

[复制链接]
STMCU小助手 发布时间:2022-12-11 15:27

1.什么是Jlink RTT。" W5 k% \& a0 [
全称为SEGGER’s Real Time Transfer(RTT),一种基于SEGGER公司的基于JLink调试器的交互式用户I/O的技术。故名思义,就是一种基于jlink的和用户进行交互的技术,可以直观的显示调试芯片的信息,以及可以让用户和调试芯片进行互动的技术。$ T* c4 G1 J0 }8 U

4 A! G- ~+ F, U) Q% r/ |2.为什么要使用Jlink RTT。
# m& L  F( w( O; Q4 s. p1 y1>不需要额外的引脚和硬件配置,支持SWD方式,两根线就可以使用。
+ S+ h/ O0 e! U4 f/ s2>速度快,与debug和run并行使用,平均一行文本可以在一微秒或更少的时间内输出。官方给出了一个速度对比图。
- q7 C; Z8 Y+ _: A0 P
: N8 w1 O8 D& o1 [$ ?1 F3>RTT的通信可以通过不同的应用程序完成,可以使用SDK集成到自定义的应用程序中,可本地连接,可远程连接。* d* ?: C" g. J. q
基于以上3个优点,如果你还在调试ARM芯片的时候傻傻的使用USART进行用户交互,那实在是效率太低了。0 E5 a! D5 C5 H- u
, s$ i/ S0 Q/ ~3 Z
3.Jlink使用RTT的准备/ `4 `. q! {3 ?: _/ i; h
1>jlink软件包

  N6 z8 d: `6 j, j( W
$ z# I& r2 b8 T& p
: s( P& ?' ~* W- K* f; z6 y' X$ v

2>Jlink仿真器一个,官网没找到到底哪一个版本的Jlink版本开始支持RTT的,看到网上说V9是支持的,我这里用的是Jlink V11的仿真器。
( n% @; o4 t$ i8 O; MHW:V11.00
: r/ f. P. i7 I. G% k- p7 ddll:V6.98c9 [, h7 a) w$ w3 r/ f. H; K
5 ]! G, c( |/ d$ D4 `% X) D. q
4.移植RTT的SDK代码到MDK的工作8 H# m5 E3 u- U9 B
1>在上一步Jlink软件的安装路径下找到RTT的SDK包,我这里在D盘安装的。
1 `! @! l  G/ f, S! |2 pD:\Program Files (x86)\SEGGER\JLink\Samples\RTT\RTT
' E2 c: r* J: I; R' W2 |4 z4 C1 E$ f  Y' [
, T% S3 G0 `/ O0 h+ D* ?2 Q, M+ ^
2>MDK工程下新建一个RTT的文件夹,把下面四个文件复制到RTT目录下,将这些文件添加到MDK的工程中。" v( b" S/ Z7 p6 w4 e- f8 d' W% W, Z
- H$ l/ s5 j9 C  e: `5 E

1 t3 f9 Y; x' V. ?* L1 t% g9 W将代码添加到工程中4 Q" W8 O0 k! T

# b2 V+ Q/ D' Q8 |9 u) O; l5 \$ }' `

" c* V# q. a" l5 R头文件包含
0 y' t1 |6 e" a1 ]/ Z) B2 N# T
# j* s0 H9 U4 C  X% f, b: l. e+ W
9 u9 L1 d, {0 E4 _; T& q
5.支持RTT的三个软件
# {9 H3 \6 A7 T. t, J4 k3 v1 TJlink提供了三个软件RTT Viewer、RTT Client、RTT Logger,这三个软件可以在SEGGER目录下找到:- n5 N  E& f% h# X- W

( Y* N; S1 v- n( ?
$ X" o3 V5 O" \7 b2 v6.使用RTT前的一些需要了解的几个概念。/ i2 l# H' e2 H2 c& C- `9 p
使用RTT需要了解两个概念,即所谓的channel和terminal。这里我也只是根据我现在的认知做了一个解释,不一定恰当。% q4 U% F/ H' y0 ]
由于没有详解RTT的内部运行机制,我在这里把channel和terminals理解为软件的概念。. T3 ^; m! p+ `4 Y9 N) E
RTT的SDK默认支持2个channel,分别是0和1。% c, }) b9 p! s% \9 T: t4 k0 I
每个channel支持16个terminal,分别是0-F。, C& h$ p  G; r% V! W2 I9 B4 O* w
在这两个概念的基础上,我把RTT Viewer、RTT Client、RTT Logger这三个软件做了一个对照表。了解下面这个表格,才能更好的使用和配置RTT。
% @/ c) Y: M5 o5 f
& M; ^2 M0 v) w+ y: T8 x) X
% p4 r/ }5 Y/ h% y
( P5 m# @' q2 ?8 f  k9 Q: q. k6 f- [7.MDK的代码编写
& V, e0 p/ p- d


  1. 3 ~; i; {9 \! E* k
  2. /*********************************************************************************************************
    . N- o' p4 X9 D, V; l% |
  3. *                                                主程序+ I- l7 `2 ~3 k- d

  4. + D4 r' Y# y% T9 N3 \
  5. *********************************************************************************************************/6 o; A3 G$ R" ~( J$ i+ F2 O
  6. int main (void)                                                                                 ; R3 w# k& L5 z
  7. {' d6 h! {: f( d
  8.   FLASH_ReadOutProtection(DISABLE);                                   //读保护& u+ a) R) X: q; x- |4 _6 C
  9.     SystemInit();                                                                            //CPU时钟初始化
    - s. b  b+ ~: T6 _* x+ \
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构)( B  H, g9 b4 Q4 J- r
  11.     SEGGER_RTT_Init();    3 R' n8 ]; \- e& b' c/ M6 o
  12.     #ifdef DEBUG_MODE                                                        //调试模式' z% w+ H* g' x
  13.     SEGGER_RTT_printf(0,"Demo Init!\r\n");" L7 E& n5 f4 V; {
  14.     #endif    2 q2 r" q4 y: A2 w- N  J1 F
  15. while(1)
    ( a! @, k/ F- y1 L, B6 a4 g
  16. {; o; s3 C" ?: s9 a3 D' w
  17.         SEGGER_RTT_SetTerminal(0);     
    + Y3 l  B: B7 `. G! P! l
  18.         SEGGER_RTT_printf(0,"Demo Run Terminal 0!\r\n");    # M" |. r5 x( s, q" {& q
  19.         SEGGER_RTT_SetTerminal(1);     ' a2 Y, B: Y" n3 r$ `+ F
  20.         SEGGER_RTT_printf(0,"Demo Run Terminal 1!\r\n");         
    4 ^0 S4 o/ p* K
  21. }: r% a- Q4 L  e6 B; b: W
  22.   return (0);
    2 {- j$ L# ?% V; I2 U
  23. }
复制代码

. G: ?. k3 e: N& v4 |' m
1>头文件引用#include "SEGGER_RTT.h"6 o8 a+ q. v) Z* Y6 R% p  r* F4 `4 T
2>RTT的初始化函数 SEGGER_RTT_Init();
7 K/ F) T( Z# V% G" A# r上面两项是通用代码,
下面是使用通道0,用RTT Viewer、RTT Client输出一段调试信息。


' M/ a6 {( o, d9 x+ O2 m

  1. ! u8 u1 q: p* b8 A, ^* l- Y
  2. /*********************************************************************************************************7 [5 Q5 j1 `  M# @' ~
  3. *                                                主程序
    1 b. u* B: T5 V& B9 `  D( _

  4. ) Q) v, S/ ~/ n" x( P  m
  5. *********************************************************************************************************/
    ( S) x+ E$ W$ k8 |& u  J3 l& e
  6. int main (void)                                                                                 8 G& v, D/ v4 T& c/ H3 x" n
  7. {2 Q  G: m, m/ i3 y; g
  8.   FLASH_ReadOutProtection(DISABLE);                                   //读保护0 {* Q' O5 K6 {" s4 i) p3 u% _
  9.     SystemInit();                                                                            //CPU时钟初始化
    4 \: n2 M# D* Y/ i
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构)
    0 y1 z% D7 P( j# c& ]# }
  11.     SEGGER_RTT_Init();   
    : u# V8 ^: D3 e8 i
  12.     #ifdef DEBUG_MODE                                                        //调试模式
    8 n+ u/ [! T  D/ B& L
  13.     SEGGER_RTT_printf(0,"Demo Init!\r\n");  E/ F3 a+ l4 Z' w
  14.     #endif    ( Z$ w1 F, x1 P; N+ C7 o
  15. while(1)4 u; w" F' D9 T/ Z( @* W9 m0 f4 {
  16. {
    ; n( s9 U# Q$ a5 D* X
  17.         SEGGER_RTT_SetTerminal(0);     / H9 ^+ Z' @7 @2 i5 K, D
  18.         SEGGER_RTT_printf(0,"Demo Run Terminal 0!\r\n");   
    6 D" o: G! d, u# A5 H2 W
  19.         SEGGER_RTT_SetTerminal(1);     
    5 O6 }6 o& v6 W
  20.         SEGGER_RTT_printf(0,"Demo Run Terminal 1!\r\n");         
    / |- x0 H  P3 W7 C+ f
  21. }
      S& W1 |& |, f; J1 ~7 \' g
  22.   return (0);
    ; i4 X% m! M1 I, ^, o- H( J
  23. }
复制代码
7 g- a% Y! l# }8 e/ \
0 B4 G9 n9 X8 e

上面的代码就是用通道0的terminal0和terminal1输出调试信息。RTT的SDK中默认已经配置好channel 0的参数了,我们使用channel 0的时候,直接使用打印函数即可。
2 u/ \9 j4 A. n6 @8 J0 t上述代码编辑后编译无错误,然后下载。
2 _+ U7 X* e- ]3 X6 q- Q( D7 D) e6 E; W
打开RTT Viewer后显示如下,按照实际情况配好参数后点击OK。

$ Y3 I8 k2 M/ l1 `3 U
9 q3 S! K/ C, t# B5 b8 U9 W: T

) ]4 F: m, w2 x; z
2 U% [* \3 I# n# H- M; M, G: v2 ~+ l可以看到控制窗口已经输出了调试信息。>前面的数字即为当前使用的terminal ID。

' V) s6 r* L" b* |  v
/ B9 T. T8 O6 v1 s
5 w+ v  b; W% f* N5 V) r3 `
% X" q# E& r2 x7 O0 m. i! y3 ~
打开RTT Client后显示如下:% n3 n' `" D* n% C4 W
- i& Q+ e: h) Y* E0 T2 t

" N6 B2 S4 D# P* a这时候会发现没有数据输出。不要着急,重点来了。
4 O7 n* }5 b) p( d2 S0 F1 `# E5 X- H
1)先关闭RTT Client,点击MDK的Debug按钮进去Debug模式。
3 l6 z; z) h) t  i: p" r. Z  H
. _) D# z% H: r  @4 d- c/ n* L  ?' j# P
% F$ A5 m7 q& U7 q; m
2)再次打开RTT Client,显示如下:7 g4 K/ s5 w( Y! K* O! t

, m/ j: S% u0 F, `
: \8 d  ?; ^+ {  @$ Z: x/ e' }% H9 I
3)点击MDK的Run全速运行。控制台开始输出调试信息。
' ~; m. S4 Q" ]1 z0 n% }9 }; X, u6 j' Z$ W4 ?9 q

. E+ E! j. l+ v& e5 Y$ E$ Y8 D; P& M7 h9 W& I
下面继续使用通道1,使用RTT Logger输出调试信息在log文件中。因为RTT Logger使用的是通道1,RTT的SDK中是没有给通道1分配缓存区和名称的,必须进行手动设置。) k' p$ T( v7 t0 v7 e5 O4 i
还有要注意的是,通道0和通道1是并行的,两者输出调试信息是不冲突的。
/ V$ k5 o" F, A, O+ N. j5 e使用通道1的代码如下所示:


( u4 K, K4 K: {, i

  1. uint8_t _UpBufferCH1[64] = {0};5 Z% x8 S4 I. q/ r
  2. uint8_t _DownBufferCH1[64] = {0};0 J! H1 h8 z5 m8 ]9 ^( h& a3 s
  3. 4 S' n/ W+ ^9 x6 l: H
  4.   N, s5 s; m& {; v
  5. /*********************************************************************************************************
    ' u( H# L/ k( X3 c" C
  6. *                                                主程序
    , a: t& F5 Y8 l+ Q! Y' B: Y: M
  7. *********************************************************************************************************/
    , Z$ a4 `4 v8 T$ ?6 G7 E! H
  8. int main (void)                                                                                 
    9 t) w& J) W0 R2 V$ k. F) G
  9. {
    : \0 ?% R1 Q- f9 G- x
  10. 4 w9 @: D+ h/ W4 ~7 l6 C

  11.   z+ M  N( ]1 E5 m" v0 t
  12.   FLASH_ReadOutProtection(DISABLE);                                   //读保护
    : M( Y, \3 ~  x" q( D% y( m

  13. ( R: n. a! ?* B, e
  14. 0 r0 d0 w$ u8 ~& ^" Z8 d3 @# b
  15.     SystemInit();                                                                            //CPU时钟初始化0 t: x/ e# O/ b) h
  16.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构)
    7 v8 j7 @: L6 R& W/ F( M" B
  17. & s' l& ~; ]0 t7 E: L4 Q" G) ]
  18.     SEGGER_RTT_Init();   : x7 j. z- H( U* _6 i8 Y4 w/ z

  19. 2 \) w" H) E9 P$ X! J

  20. & O( f  T; F, j' `, ^
  21.     /* 配置通道1,上行配置(STM32->RTT Viewer软件) */
    3 e/ |2 [! c: J: f
  22.     SEGGER_RTT_ConfigUpBuffer(1, "RTTUP", _UpBufferCH1, 64, SEGGER_RTT_MODE_NO_BLOCK_SKIP);( K' ^! z6 R7 e1 F& J

  23. ' N6 i- q' h5 B7 P5 b
  24.     /* 配置通道1,下行配置(RTT Viewer软件->STM32) */   + p; D2 d3 ?+ c
  25.     SEGGER_RTT_ConfigDownBuffer(1, "RTTDOWN", _DownBufferCH1, 64, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
    & J! ?" C: g5 @% O8 p! p: S* |

  26. 4 e5 t, B' p% Z9 n! m
  27.     #ifdef DEBUG_MODE                                                        //调试模式+ s4 d1 s& l. C
  28.     SEGGER_RTT_printf(0,"Demo Init!\r\n");
    ! X8 \% S$ N% m1 P2 z
  29.     #endif   
    8 O- x* z' i* I1 u9 b0 ^
  30. ! W  R' T6 O4 F+ T$ m1 z  G+ D

  31. 1 f6 w4 ?# W" `( Y; o1 h
  32. while(1)! ]- ]6 n  Y6 ^/ D# U4 t
  33. {
    ' F+ J# t7 e& `$ ?
  34.         SEGGER_RTT_SetTerminal(0);     ' O" E& y3 f" _& G) E' {$ t! l
  35.         SEGGER_RTT_printf(1,"Demo Run Terminal 0!\r\n");   
    $ s! P/ ?$ `) t& U' F
  36.         SEGGER_RTT_SetTerminal(1);     3 }* L- d! s0 {2 r2 D
  37.         SEGGER_RTT_printf(1,"Demo Run Terminal 1!\r\n");         0 w. Q. d' s5 L, @! U4 |) b1 d
  38. }
    : e# j, f2 K; y

  39. ( E0 a6 x$ V7 h# y7 I! D" e
  40. + J" Y4 D; h9 A  @6 q2 R

  41. 2 @0 K0 b0 \0 w0 _! ?
  42.   return (0);
    ) I- g; C$ e$ R# p4 d
  43. }
复制代码

0 q) h2 M. n( l# b6 v3 j0 Z

上述代码编辑后编译无错误,然后下载。

打开RTT Logger后如下所示:: M1 D! a4 @5 L$ \% P" k6 x5 _
  I% t& \/ Y& Y5 C& W' h; W

* f9 ?/ `2 m; D
" J6 L/ l5 n- T# I这里要注意的是,在RTT Logger中,>后面可以自由输入>前面表示的参数,按回车键确认。无输入的情况下,按回车键跳过。& r. N. P, @  l9 o9 N
一直回车键,如果程序配置通道1正确的话,会出现下面图片的画面,不停的给log文件中写数据。
. V. x3 |& @$ Q- g, f2 O注意:如果程序中没有配置通道1,RTT Logger检测不到通道1的情况下就会自动关闭。
3 d4 k1 S- S2 c正确的RTT Logger显示画面如下:
' W/ p' O' ?( p( ?- j
3 H6 Z' p' d% T
+ t, d, Q& L9 l* N& ]: X+ }打开上述路径中的.log文件,里面的内容如下所示,这说明成功的生成了log文件。
6 Q  P9 Z* F- R9 L/ G6 c# g# F- V. Q0 \1 k! [# n+ i

# l) k6 M9 Q% }7 q) {
5 M: N; {8 d. D7 y, D只要弄懂上面的内容,你就可以很爽的使用RTT来输出调试信息了,我们一般只使用RTT Viewer这个软件就足够了。他还可以设置显示的颜色,格式化输出等,具体的函数说明可以查看
* x6 Q! E7 v2 ?) p$ P3 cJlink安装目录下的使用手册16.4.1章节即可。& N& P/ [3 N* `- N( z
手册路径如下:D:\Program Files (x86)\SEGGER\JLink\Doc\Manuals。

---------------------# J9 |5 v6 R3 W) v9 i& V
作者:xyz549040622

* l. a7 \* f- Q
收藏 评论0 发布时间:2022-12-11 15:27

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版