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

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

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

1.什么是Jlink RTT。" z! z6 r( d* a1 h3 g" g
全称为SEGGER’s Real Time Transfer(RTT),一种基于SEGGER公司的基于JLink调试器的交互式用户I/O的技术。故名思义,就是一种基于jlink的和用户进行交互的技术,可以直观的显示调试芯片的信息,以及可以让用户和调试芯片进行互动的技术。
8 @" z, |2 m& j) F7 @# {0 D3 B: I
2.为什么要使用Jlink RTT。) _9 ^& a& }$ _4 g, I! z( @
1>不需要额外的引脚和硬件配置,支持SWD方式,两根线就可以使用。
: m$ k1 T* A1 v3 O9 V4 I2 E2>速度快,与debug和run并行使用,平均一行文本可以在一微秒或更少的时间内输出。官方给出了一个速度对比图。
& _- o3 ^: X# \& q
* c+ p; ~5 ?* ?8 _5 m3>RTT的通信可以通过不同的应用程序完成,可以使用SDK集成到自定义的应用程序中,可本地连接,可远程连接。+ A. p& A: I0 F# A8 s; i) z- @
基于以上3个优点,如果你还在调试ARM芯片的时候傻傻的使用USART进行用户交互,那实在是效率太低了。- a( X+ X" L2 y" q2 Q9 A

( I! V2 A8 y7 E( y5 v3.Jlink使用RTT的准备
/ n. o; p5 ?: Q) K" `- s6 J1>jlink软件包


1 H# j4 @; q9 j4 F8 V" j% y* C  [7 B" _* {6 p: v
* K3 e, A3 W$ J! d5 M9 `1 {

2>Jlink仿真器一个,官网没找到到底哪一个版本的Jlink版本开始支持RTT的,看到网上说V9是支持的,我这里用的是Jlink V11的仿真器。" w- b* k0 n2 y* b1 ~% O1 h0 p
HW:V11.00  F8 G8 q  H; N3 E3 z7 J3 k, A5 Z
dll:V6.98c8 {2 _2 R7 O  D2 p* ^. @: H8 `

7 A) ^6 C& ?9 x, X4 V4.移植RTT的SDK代码到MDK的工作' @& B7 d1 N( G( M! L, u
1>在上一步Jlink软件的安装路径下找到RTT的SDK包,我这里在D盘安装的。) s4 y  `1 u. B& `3 E
D:\Program Files (x86)\SEGGER\JLink\Samples\RTT\RTT4 p+ x5 q0 ?2 L

3 e$ z2 |5 F$ j( r7 L, v
$ P1 V! |6 u4 i; n$ x+ O% @2>MDK工程下新建一个RTT的文件夹,把下面四个文件复制到RTT目录下,将这些文件添加到MDK的工程中。
$ a4 i' p, N* z0 Q" A9 i1 H3 Q2 L, S- P; ?# q8 e1 [
1 E* G5 z5 y+ J3 d% H! Z
将代码添加到工程中
7 A7 w  g: Z% a! `( }6 i7 g0 ~2 i0 k; k

; m6 H% k4 N+ y8 P3 `* S% B, c5 X7 V7 o  a0 T# u, O+ j+ J+ g
头文件包含' T5 B9 ~* X8 g2 T$ ^

2 r4 g. [0 y; F7 I
4 B: V. m- Z+ O% W% j
& V8 Y2 N4 l9 e( c5.支持RTT的三个软件
) [5 h& V5 Q1 {; Q' n3 |Jlink提供了三个软件RTT Viewer、RTT Client、RTT Logger,这三个软件可以在SEGGER目录下找到:- ]* O5 W( \5 Q3 {

- O0 C) e/ n6 x( d# V# k3 v" G% h" Z9 j7 j7 S' e; l
6.使用RTT前的一些需要了解的几个概念。
# \& I5 N" |# o( I  t& Y使用RTT需要了解两个概念,即所谓的channel和terminal。这里我也只是根据我现在的认知做了一个解释,不一定恰当。
6 i" P, J$ J& r4 E由于没有详解RTT的内部运行机制,我在这里把channel和terminals理解为软件的概念。
3 m4 Q: }6 f" |: e, }9 h% ~5 S. fRTT的SDK默认支持2个channel,分别是0和1。' p6 H: l; Y+ E, o1 i
每个channel支持16个terminal,分别是0-F。" O  O5 o/ e1 [4 m$ n
在这两个概念的基础上,我把RTT Viewer、RTT Client、RTT Logger这三个软件做了一个对照表。了解下面这个表格,才能更好的使用和配置RTT。
8 I, D: C  x& U5 x! `- ]* `/ q
1 }8 J+ o2 y" Z# x# g: ]" n# Z, `( o- P8 H+ t

9 ]- @$ z5 X# H) z+ K1 t! L: L7.MDK的代码编写: P" b7 L3 H' d/ s1 G, W

  1. 3 I* S$ v; q3 [- X! i2 O0 ]
  2. /*********************************************************************************************************
    - s! Y7 R0 Z2 B5 W/ ?
  3. *                                                主程序# |: w' Z+ R7 {3 P

  4. - I6 X# Z/ ~5 o# N# h+ N
  5. *********************************************************************************************************/
    ' d! A- \9 d4 b3 l3 j! t5 i
  6. int main (void)                                                                                 
    ' `' _2 E. Q0 i/ m# z3 r
  7. {
    " U* P) @* F- D( L
  8.   FLASH_ReadOutProtection(DISABLE);                                   //读保护
    0 \+ J2 ]) x9 ~$ L! @" V1 t
  9.     SystemInit();                                                                            //CPU时钟初始化
    . O# C4 y/ W& t: a% l# n
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构)
    4 Q  c# U& e$ C
  11.     SEGGER_RTT_Init();      L0 R2 F( D: I% r) \
  12.     #ifdef DEBUG_MODE                                                        //调试模式& F3 x3 {8 y6 U, q# g! k6 W* D
  13.     SEGGER_RTT_printf(0,"Demo Init!\r\n");0 O9 l6 C  z% p, n& O; s4 p+ p( H* X
  14.     #endif    . k: A: ], b2 ]7 V' b/ p
  15. while(1)
    + z$ \3 C" o+ F& N  x1 Y5 z' G
  16. {
    ( s) ~0 p% D( C
  17.         SEGGER_RTT_SetTerminal(0);     $ p# o- ^& y& j7 j+ H
  18.         SEGGER_RTT_printf(0,"Demo Run Terminal 0!\r\n");    : N# {# P7 K* V  y
  19.         SEGGER_RTT_SetTerminal(1);     * l  q! ~2 w! E: K$ y) W1 t/ u$ g% h
  20.         SEGGER_RTT_printf(0,"Demo Run Terminal 1!\r\n");         
    - T# x8 r1 P) c! @, J3 ^
  21. }
    - W& H& G' V' C  p+ v
  22.   return (0);- x- X5 l/ C  y: c0 |
  23. }
复制代码

& J) U: ~3 |) k9 {
1>头文件引用#include "SEGGER_RTT.h"
7 V# U2 {- L; z2>RTT的初始化函数 SEGGER_RTT_Init();1 u' x( @% p$ W6 f
上面两项是通用代码,
下面是使用通道0,用RTT Viewer、RTT Client输出一段调试信息。

! f- n& H5 ~' b1 U  M& U  A


  1. 5 b' U0 U( D4 L' G8 \
  2. /*********************************************************************************************************, D& B2 ]  y. x% T7 J9 v
  3. *                                                主程序
    7 h6 y2 K3 S3 i/ U! y/ V2 O
  4. 7 u6 G7 ~' U) K) x. U! d
  5. *********************************************************************************************************/+ ?+ V7 Y' w$ L1 X
  6. int main (void)                                                                                 
    2 ]- h/ @# o% `" X
  7. {
    3 u2 Q; j4 |* H% W! w$ g: |3 W
  8.   FLASH_ReadOutProtection(DISABLE);                                   //读保护5 b' `0 X& @/ J- `/ Y0 s
  9.     SystemInit();                                                                            //CPU时钟初始化
    # b5 l) d2 }/ t0 y7 P0 n8 _0 v
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构); F) I1 m" @. C4 ?9 F9 I
  11.     SEGGER_RTT_Init();   
    . i5 K, `. P, ~/ l: ?( W) a: a6 [
  12.     #ifdef DEBUG_MODE                                                        //调试模式
    # z) }: D4 P, F2 [4 j% ]9 u, M
  13.     SEGGER_RTT_printf(0,"Demo Init!\r\n");
    ' \& l, s8 f: m7 x4 X, D
  14.     #endif   
    : A9 q7 H3 \. u
  15. while(1)
    - ~+ {/ Q, j0 A/ S: x
  16. {# M- ]9 \+ S3 h" M5 B* X7 V  u/ V
  17.         SEGGER_RTT_SetTerminal(0);     % j3 B% ~% _; y
  18.         SEGGER_RTT_printf(0,"Demo Run Terminal 0!\r\n");   
    ( x7 X, f2 f& d9 W4 X1 M: x  q
  19.         SEGGER_RTT_SetTerminal(1);     
    6 g5 O  E# C# A
  20.         SEGGER_RTT_printf(0,"Demo Run Terminal 1!\r\n");         
    8 L' W6 Q0 |5 w1 C+ e0 x5 \: l
  21. }) c8 F+ |8 S3 o# p2 y8 ^! U" x
  22.   return (0);
    ) ]! Q0 y) Z  s! Q, I
  23. }
复制代码
3 ^6 i! R& ^6 v4 g+ F, j5 q
$ E( c+ F; u. ~; }) B

上面的代码就是用通道0的terminal0和terminal1输出调试信息。RTT的SDK中默认已经配置好channel 0的参数了,我们使用channel 0的时候,直接使用打印函数即可。4 }7 r: a5 q; ~; o
上述代码编辑后编译无错误,然后下载。
1 B8 G' f# `! K# |( `7 {- A0 w
9 a! g  |! ?# R  w% ~% E7 F& _打开RTT Viewer后显示如下,按照实际情况配好参数后点击OK。


) X( ~' O  n2 z5 m  A" Y3 L# r* T6 y3 V
% O) |8 m0 b( m0 s8 N$ J% r, Q. c

( y( I! q$ I# A9 a+ y1 ]可以看到控制窗口已经输出了调试信息。>前面的数字即为当前使用的terminal ID。


% h9 @( {) U0 Q+ t( N$ U9 M4 }; @5 h$ h5 R6 X! E' ~

4 N/ C# H: i1 Y" }+ t* B: V. q0 g; `7 e1 P( D' I: U4 l
打开RTT Client后显示如下:
: k0 _# V. _! P3 E8 B3 M  Z( I1 w3 k' ^1 `% O  N$ l0 k. N# {
, H4 D- v" S9 n* c
这时候会发现没有数据输出。不要着急,重点来了。
4 E! I$ m% M7 N  P% U
5 |9 w3 F* A! f# q1)先关闭RTT Client,点击MDK的Debug按钮进去Debug模式。: ]5 e) W0 a7 m3 v) Z1 b
. v0 Y- d% w$ t# f  q9 T7 i1 D# T% y

0 H& o0 \) C6 e( v$ T% }( z- _# {+ n' e3 @& s, ^+ _1 ~
2)再次打开RTT Client,显示如下:: [/ G* W1 e6 m( u5 _. g

4 e$ s( A4 d3 G- U, C( h1 x. Q' E- A+ d/ B* ]* }3 O+ {

! ~! n0 s9 s8 C( M! \8 r. l3)点击MDK的Run全速运行。控制台开始输出调试信息。
+ b, }. Q+ v3 {4 G0 b' E& c0 s) b7 D! O0 n! t/ H$ {$ }
0 R" b( {% U% [7 v- c+ {$ T+ @

+ Y& ^! i7 H' w3 J; T  T下面继续使用通道1,使用RTT Logger输出调试信息在log文件中。因为RTT Logger使用的是通道1,RTT的SDK中是没有给通道1分配缓存区和名称的,必须进行手动设置。. @5 {! \% B! K/ a  j" O- n  o
还有要注意的是,通道0和通道1是并行的,两者输出调试信息是不冲突的。
, p* [, g+ x4 D* ]使用通道1的代码如下所示:


# o' s/ C6 w# t% w

  1. uint8_t _UpBufferCH1[64] = {0};' Q( E- |1 f: Z7 `5 q3 }' T$ T
  2. uint8_t _DownBufferCH1[64] = {0};6 [$ u" \% M; r) h+ _, n9 u) n) n
  3. 8 c; Z7 s9 X9 m) h, n$ q
  4. 7 L# @# x: F9 L+ T1 ^2 _  w
  5. /*********************************************************************************************************
    * L0 U9 A" f8 p; I% w2 J
  6. *                                                主程序
    - F' z0 e4 R% M
  7. *********************************************************************************************************/# M" _! g' M* v' h" _
  8. int main (void)                                                                                 
    3 |9 h- y( p; @, A4 F
  9. {
    ) R. I2 c2 }- E/ B
  10. 1 o: q4 F0 m. R" e  E

  11. & K  B4 J; ?& _7 }
  12.   FLASH_ReadOutProtection(DISABLE);                                   //读保护$ b, V) I. G* E5 J! J( y

  13. 3 j  }: _/ F  K2 F% i; F2 _& y

  14. ( A; ]" s. Q( N+ \' H4 q
  15.     SystemInit();                                                                            //CPU时钟初始化" b- @- y9 [8 m* S+ Z
  16.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构)
    / z8 E; G* ~- [) F
  17. 1 x( G0 C2 ?6 Q. L5 U1 e6 `; ^/ Y
  18.     SEGGER_RTT_Init();   
    3 H: i6 {. E2 Y: L0 x3 d  e0 _2 v
  19. 5 X" l( f# D$ O5 c  d& k3 q

  20. 5 r$ ~+ \( ~. T# z
  21.     /* 配置通道1,上行配置(STM32->RTT Viewer软件) */
    # I3 W9 t# u8 M/ L+ f. @* {: D
  22.     SEGGER_RTT_ConfigUpBuffer(1, "RTTUP", _UpBufferCH1, 64, SEGGER_RTT_MODE_NO_BLOCK_SKIP);4 U  j0 ]1 S) o2 \, h! k

  23. ; H# F' x8 [5 o' u
  24.     /* 配置通道1,下行配置(RTT Viewer软件->STM32) */   $ T9 B+ U1 u2 w- K- k
  25.     SEGGER_RTT_ConfigDownBuffer(1, "RTTDOWN", _DownBufferCH1, 64, SEGGER_RTT_MODE_NO_BLOCK_SKIP);+ J; y- }. b, U  w0 w2 G

  26. 3 h; {. @, M; w* F
  27.     #ifdef DEBUG_MODE                                                        //调试模式8 y: a% R, S3 ?: |; t
  28.     SEGGER_RTT_printf(0,"Demo Init!\r\n");0 h  K% b* q# |3 r1 ]8 K( n
  29.     #endif   2 G3 f# }# j7 m* f3 T% r  S

  30. 6 z* ]( e0 e4 H! w+ e6 p

  31. * P6 T7 d. B1 c- M' D8 I
  32. while(1)& O- J7 ~: ^& h6 D3 \
  33. {
    9 F/ [3 M# f1 V; R( p+ w2 I% g6 S
  34.         SEGGER_RTT_SetTerminal(0);     % Y# r8 m  \; D( ?6 J
  35.         SEGGER_RTT_printf(1,"Demo Run Terminal 0!\r\n");   3 j2 A4 Q- p! P: v
  36.         SEGGER_RTT_SetTerminal(1);     6 g' L  e8 j, a
  37.         SEGGER_RTT_printf(1,"Demo Run Terminal 1!\r\n");         ; N3 L% ?/ t2 G/ F0 a! Z8 P8 X
  38. }. f- x) m* W- r. w2 }
  39. 3 g. N# t3 s! @" v* r: i; t3 E
  40. ) F7 f) r$ B! Q) J' J

  41. 6 H" o) Z' T' c$ @; n: B6 U
  42.   return (0);8 U0 ?) O' f0 n) t
  43. }
复制代码

* {; D+ S; J/ Q" @, H! _7 o0 L

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

打开RTT Logger后如下所示:
9 Q( a7 }# B$ D, z, ?. P$ s# T  ]2 |4 W; ^6 s8 C$ k7 d
! Z2 E  l! h5 Q" ^: F5 M# ^& P1 [
3 o* B& I! p( |' C5 z8 Y0 h
这里要注意的是,在RTT Logger中,>后面可以自由输入>前面表示的参数,按回车键确认。无输入的情况下,按回车键跳过。
+ v' G/ G. ], i' g. B$ e一直回车键,如果程序配置通道1正确的话,会出现下面图片的画面,不停的给log文件中写数据。
3 \" b9 ?. P& R" ]' ^0 {+ ~$ b注意:如果程序中没有配置通道1,RTT Logger检测不到通道1的情况下就会自动关闭。# W& X: r: F. y
正确的RTT Logger显示画面如下:
8 P) O& ?. D4 y- r7 s, M3 a; l$ Q' I! ^* K- T& K
9 J2 b% r% H4 K& s- P* G
打开上述路径中的.log文件,里面的内容如下所示,这说明成功的生成了log文件。! {* t/ P5 L( d& Y* j7 j
# ]( f1 @9 d! T
; z  K" ~3 q8 H/ y
. Z0 X- c' n2 H7 U
只要弄懂上面的内容,你就可以很爽的使用RTT来输出调试信息了,我们一般只使用RTT Viewer这个软件就足够了。他还可以设置显示的颜色,格式化输出等,具体的函数说明可以查看
# b- Z2 y# S. G* v- ], I9 {4 HJlink安装目录下的使用手册16.4.1章节即可。
. F# \5 a( E! @! P. h8 s手册路径如下:D:\Program Files (x86)\SEGGER\JLink\Doc\Manuals。

---------------------5 K! n2 d0 L; _. o0 L
作者:xyz549040622

7 a. X9 F5 U9 K7 g
收藏 评论0 发布时间:2022-12-11 15:27

举报

0个回答

所属标签

相似技术帖

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