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

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

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

1.什么是Jlink RTT。! q$ [. X1 n+ G
全称为SEGGER’s Real Time Transfer(RTT),一种基于SEGGER公司的基于JLink调试器的交互式用户I/O的技术。故名思义,就是一种基于jlink的和用户进行交互的技术,可以直观的显示调试芯片的信息,以及可以让用户和调试芯片进行互动的技术。
. R9 b- v, ?0 ^$ ^- w5 V
8 X3 q# s/ `/ @/ {  O- M4 `- O2.为什么要使用Jlink RTT。; M3 \# i+ g4 a* L% M& g2 ~
1>不需要额外的引脚和硬件配置,支持SWD方式,两根线就可以使用。
( J) d, N, V) i+ k- r8 Y0 C; n6 [) L2>速度快,与debug和run并行使用,平均一行文本可以在一微秒或更少的时间内输出。官方给出了一个速度对比图。
0 S  A; l  J, v; {8 E8 J) y; C% b  ~
3>RTT的通信可以通过不同的应用程序完成,可以使用SDK集成到自定义的应用程序中,可本地连接,可远程连接。+ w7 w/ D0 B7 ?5 z
基于以上3个优点,如果你还在调试ARM芯片的时候傻傻的使用USART进行用户交互,那实在是效率太低了。
: ~: u8 f2 J8 z4 h" q* K: u3 t# W  |! r
3.Jlink使用RTT的准备
; v- A5 e7 |9 \2 [& w2 }1>jlink软件包

# F; H8 @. o; k  g/ m/ a

5 q: y6 k! F6 t5 |' t# R" i) F! r( L; V6 J/ }, C. Z- o+ O

2>Jlink仿真器一个,官网没找到到底哪一个版本的Jlink版本开始支持RTT的,看到网上说V9是支持的,我这里用的是Jlink V11的仿真器。
6 R8 h; @& S: q; T7 A7 r# U' w0 k" rHW:V11.00
' a; [) L+ ?  g: }# ]dll:V6.98c
+ B& q$ P/ `4 f1 o( k$ p: x
- R2 x! ^2 _8 ?( M$ y. E. D4.移植RTT的SDK代码到MDK的工作
- ?: {  n/ e6 K/ K8 |4 A# q( \! R1>在上一步Jlink软件的安装路径下找到RTT的SDK包,我这里在D盘安装的。: ]4 }! y1 Z6 k2 j0 R" w9 T5 S
D:\Program Files (x86)\SEGGER\JLink\Samples\RTT\RTT
& U# J8 S' u" u! f. Y( p! \
3 K# W0 l, w3 R/ c
* _6 M. e- K$ s2>MDK工程下新建一个RTT的文件夹,把下面四个文件复制到RTT目录下,将这些文件添加到MDK的工程中。) W, Z" S$ k; r2 C( L4 U4 ^
& Q$ J7 a  _0 |' @" K2 M  @+ W, H

6 q! F* e, ~' x# c: H将代码添加到工程中
2 D0 ]7 U2 n1 y9 |3 s% G0 H/ q4 z8 O9 Z/ w+ k3 `% H2 C

. F1 b! c4 `" }4 C5 ~, v7 i! V. Y; H% T5 x- e
头文件包含
1 Z1 P/ ^& r/ `+ i: X% a# H- I5 n6 D. M7 R  m1 m7 J$ n: z: g7 @! J8 q' I6 k

! J4 S5 C7 g  I7 l, X% C$ A! k* p! Q) ?8 M! w9 c
5.支持RTT的三个软件
' D8 y6 S, B. ^7 Y) P+ YJlink提供了三个软件RTT Viewer、RTT Client、RTT Logger,这三个软件可以在SEGGER目录下找到:  Y0 Y: L1 R1 Z- p

0 a1 |$ {& q  n3 _# L2 H6 z' {1 W1 u& J5 N+ ?  a- H9 Q5 L
6.使用RTT前的一些需要了解的几个概念。
1 W% l+ U# W8 o) x6 u使用RTT需要了解两个概念,即所谓的channel和terminal。这里我也只是根据我现在的认知做了一个解释,不一定恰当。) Z, e8 C4 j* t
由于没有详解RTT的内部运行机制,我在这里把channel和terminals理解为软件的概念。
( ~! n" @' R: O- ^) V8 y  QRTT的SDK默认支持2个channel,分别是0和1。+ L: c8 h# Y$ g  |5 A
每个channel支持16个terminal,分别是0-F。
/ u5 K# Z% A) u. J5 u! N$ y1 n  {在这两个概念的基础上,我把RTT Viewer、RTT Client、RTT Logger这三个软件做了一个对照表。了解下面这个表格,才能更好的使用和配置RTT。5 K' c: s! c+ y. D1 ?9 v. F
3 G$ h6 s* X; I6 Z/ v4 K0 q, W
! j7 F9 k" ^+ I7 A
3 y  E; C8 J% N+ ^9 T& j$ @3 t
7.MDK的代码编写
+ O, o4 ?, B7 j


  1. ) b# |- p# E. C
  2. /*********************************************************************************************************
    $ S' e/ X5 \0 `& @, U
  3. *                                                主程序9 Q- p6 O) ?4 l+ g( |# M2 w8 W$ J

  4. & |4 m% Z$ I2 [1 {5 ~; E' Z
  5. *********************************************************************************************************/
    & s, H7 }$ [, S* [. T7 S8 M+ V
  6. int main (void)                                                                                 
    " r' q. \; R: t$ W" j6 {/ d, x. D
  7. {% K* ~; t+ x6 t# ]: w4 a
  8.   FLASH_ReadOutProtection(DISABLE);                                   //读保护4 e% L6 w5 Y' q9 [; g9 }
  9.     SystemInit();                                                                            //CPU时钟初始化1 ?6 B# x8 t4 H  K
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构)
    , w6 z. M0 M# k* E  N) {
  11.     SEGGER_RTT_Init();   
    9 Z) ?9 \+ s: ]8 T, _5 I* R
  12.     #ifdef DEBUG_MODE                                                        //调试模式% s6 [& P7 \4 M7 m
  13.     SEGGER_RTT_printf(0,"Demo Init!\r\n");9 L* X* L5 @7 V- L0 g! w" g3 |
  14.     #endif   
    3 n0 ~* l+ o; T7 o, r( j0 P' `  N7 R0 \
  15. while(1)2 j0 h) V" Y6 b5 C5 ?& w2 |
  16. {
    $ X3 \- g  q& @' P
  17.         SEGGER_RTT_SetTerminal(0);     
    9 o; \3 {7 p' s- _9 Q- p
  18.         SEGGER_RTT_printf(0,"Demo Run Terminal 0!\r\n");   
    ( J% k5 f: s/ s/ r5 O2 M* k
  19.         SEGGER_RTT_SetTerminal(1);     " E2 w4 F: P* L' }3 t3 U5 a
  20.         SEGGER_RTT_printf(0,"Demo Run Terminal 1!\r\n");         
      u4 T+ d* ]9 M( q9 ~/ h
  21. }1 A* P/ U4 ^' i+ N0 f# O9 W
  22.   return (0);2 C" {6 l, v  O5 ~9 J, D
  23. }
复制代码

$ x5 J8 Y  |, o. D: m( l5 ^
1>头文件引用#include "SEGGER_RTT.h"$ }, I7 a& z3 E" {# \% f
2>RTT的初始化函数 SEGGER_RTT_Init();( E! F0 o- l: H) W6 S
上面两项是通用代码,
下面是使用通道0,用RTT Viewer、RTT Client输出一段调试信息。


* G! k& y# u9 G3 E


  1. ! U0 t8 M4 h) `" J- A
  2. /*********************************************************************************************************. _9 u9 V( H% o( v+ }
  3. *                                                主程序
    3 r  _1 B: ^; W( x. c

  4.   H- ~/ L4 D$ F# G% X
  5. *********************************************************************************************************/
    ( U; X! u2 N. b4 [; I
  6. int main (void)                                                                                 
    & E* E. }  x8 D3 h3 J+ a
  7. {: `6 c& R( i3 s9 {; P: _8 ~
  8.   FLASH_ReadOutProtection(DISABLE);                                   //读保护$ F: Q% z  G  N3 d/ g4 n
  9.     SystemInit();                                                                            //CPU时钟初始化
    ) u+ H6 {' i& j2 ]1 W& [
  10.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构), Z; A8 Q) h* V1 {; o9 W6 S2 I
  11.     SEGGER_RTT_Init();    9 d6 x4 d; ~! n' k* T
  12.     #ifdef DEBUG_MODE                                                        //调试模式7 g1 y6 e2 G9 P, N4 l
  13.     SEGGER_RTT_printf(0,"Demo Init!\r\n");
    - D/ U; b! ?) W5 N+ F* K( J: F6 v
  14.     #endif    8 b% _1 h0 o$ D8 \4 j8 P, C
  15. while(1)
    4 k# l6 X( q. i2 i4 V0 _% z; G
  16. {
    % d; E) R& n6 Q. i3 I
  17.         SEGGER_RTT_SetTerminal(0);     4 l6 s5 r9 S( T9 `; t' r
  18.         SEGGER_RTT_printf(0,"Demo Run Terminal 0!\r\n");   
    ) l1 J6 [8 V- e# @; ~
  19.         SEGGER_RTT_SetTerminal(1);       D; a' U, B5 t9 h* i0 p
  20.         SEGGER_RTT_printf(0,"Demo Run Terminal 1!\r\n");         
    : m) l, Y! w/ y, r
  21. }
    % V: f4 ?3 h( Y" L& s' o
  22.   return (0);1 u% y5 s  S; k4 @9 \# c
  23. }
复制代码

9 i4 h7 B( J% H- z. u% Q2 N, S& V% {! {* S4 {# {/ c; _

上面的代码就是用通道0的terminal0和terminal1输出调试信息。RTT的SDK中默认已经配置好channel 0的参数了,我们使用channel 0的时候,直接使用打印函数即可。
9 z8 q! Q% y6 W' a7 S& y4 J3 Q上述代码编辑后编译无错误,然后下载。
; u5 Z8 {" j/ h; O* t  H& f
# E9 m+ {# \0 {1 ]  u打开RTT Viewer后显示如下,按照实际情况配好参数后点击OK。

1 @- z7 g$ Q7 w# i+ j5 I
$ I6 W& `: v3 X- C: c( j$ m

( m/ @0 x3 X- T2 e( q
: Y0 r$ }3 D; b& o可以看到控制窗口已经输出了调试信息。>前面的数字即为当前使用的terminal ID。

8 v; `" _) y$ O0 N+ m3 z
* l$ P2 A; N6 G9 o: g7 I

5 u+ L' }  ]4 u5 A$ J2 g
( q2 `+ b8 R/ r5 f打开RTT Client后显示如下:9 Q! m5 H+ O& q( h( ?7 f2 a
3 Y' q: R! n# `( i! M

: v0 |( ?& o' \这时候会发现没有数据输出。不要着急,重点来了。  ~1 n7 Q2 h; q
$ U$ Q& u* W0 i/ ^+ ]- g) M' p
1)先关闭RTT Client,点击MDK的Debug按钮进去Debug模式。7 N; e: y2 N  K
* G: z* L$ f) f' a
% N1 j* o: Z. W8 \! a  o  J
4 o# d; i3 d2 a) s6 h; [6 }
2)再次打开RTT Client,显示如下:" J. A. M, }+ S# e
. l- N& e; S8 o& }+ J' H
5 _- J' h6 q0 R( _9 ]

6 l  E4 w  }; O3)点击MDK的Run全速运行。控制台开始输出调试信息。6 ~* K; b& H& v: W0 q% {
/ w" X" K5 f3 y9 v
! R# s/ n) g' ^; I/ S# {4 A
7 _% S5 I' R$ X4 F4 }
下面继续使用通道1,使用RTT Logger输出调试信息在log文件中。因为RTT Logger使用的是通道1,RTT的SDK中是没有给通道1分配缓存区和名称的,必须进行手动设置。
: S5 @3 R) B6 y7 u5 J6 m还有要注意的是,通道0和通道1是并行的,两者输出调试信息是不冲突的。
1 a0 y! ~; S  k8 e( g4 s4 V7 [4 N使用通道1的代码如下所示:

6 U1 ]  |7 ~  i2 G* c

  1. uint8_t _UpBufferCH1[64] = {0};# H0 C, P3 C$ l2 p
  2. uint8_t _DownBufferCH1[64] = {0};
    0 S7 U) m/ q1 W  x
  3. % Y  N* u, v8 I) N/ w) z

  4. * H4 z: }5 |; C1 _
  5. /********************************************************************************************************** F( K6 V! h& U& z1 U5 F' y
  6. *                                                主程序, V4 v$ Z- `" I1 m
  7. *********************************************************************************************************/
    2 Y1 l4 j. ?+ S- V
  8. int main (void)                                                                                 3 _" p6 l  t# y5 v
  9. {- Y& @$ v4 v& D% _7 L( Y3 e) K
  10. 4 h: c* l5 E* F3 t3 \+ m

  11. 4 d& T5 B4 _; l+ H5 j
  12.   FLASH_ReadOutProtection(DISABLE);                                   //读保护
    & z* o9 T3 t- b% R; \! @; u
  13. 9 h3 E" h, {- [9 ~  x5 a! X) d

  14. ( @6 p' i5 O* O# x  h* `
  15.     SystemInit();                                                                            //CPU时钟初始化- J6 n/ w9 ]2 _% D
  16.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);        //使用优先级组4(4:4结构)
    & O6 Y& X2 W% L: W
  17. , D; l2 F. K0 `0 p" A( u
  18.     SEGGER_RTT_Init();   & L$ \) U  d8 O  e2 J
  19. $ z5 s% \5 m& t

  20. + q9 _& t' o. c) E
  21.     /* 配置通道1,上行配置(STM32->RTT Viewer软件) */7 f3 H) j% J/ F" S
  22.     SEGGER_RTT_ConfigUpBuffer(1, "RTTUP", _UpBufferCH1, 64, SEGGER_RTT_MODE_NO_BLOCK_SKIP);4 N( P  n* j7 D9 c8 b
  23. " S# Z& N4 F1 W" \' w0 f: q
  24.     /* 配置通道1,下行配置(RTT Viewer软件->STM32) */   - x& x  C' @9 A
  25.     SEGGER_RTT_ConfigDownBuffer(1, "RTTDOWN", _DownBufferCH1, 64, SEGGER_RTT_MODE_NO_BLOCK_SKIP);7 Z6 H& Q( W7 D$ l8 N0 E% M

  26. 7 ]; h# L  _3 X+ p1 A9 F
  27.     #ifdef DEBUG_MODE                                                        //调试模式
    ( H( j' e+ s& o7 n
  28.     SEGGER_RTT_printf(0,"Demo Init!\r\n");- D8 O: S0 s) G! g& H' B7 \; f& y
  29.     #endif   6 _# k  S" ?+ f7 ]1 G6 c9 a! s

  30. 0 W: V4 q# d! B8 Z# \7 [
  31. 2 Y; X  h+ f+ L+ g9 W
  32. while(1)
    ! C+ N7 [/ u5 L
  33. {
    ' m' |+ I+ t4 `* x. Z4 w! f
  34.         SEGGER_RTT_SetTerminal(0);     1 Q  F7 |# o/ E. a
  35.         SEGGER_RTT_printf(1,"Demo Run Terminal 0!\r\n");   
    0 f8 s# b6 ?- f0 w$ j6 Z
  36.         SEGGER_RTT_SetTerminal(1);     
    % |% w$ H1 G! S# Q! r2 Y+ o
  37.         SEGGER_RTT_printf(1,"Demo Run Terminal 1!\r\n");         
    ; |6 ?  L7 Q& j. A
  38. }9 N. w4 I( }1 {+ t

  39. ( [% j7 S" ?$ }* g
  40. * a" R# ?4 {1 _0 p* L
  41. & W! `4 ^" d& L$ k% i" l$ L* C
  42.   return (0);  @5 X! f4 e1 _5 f$ Z- j* W. [0 O( w# u
  43. }
复制代码
3 l2 E3 k- n- I- s0 ]* C

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

打开RTT Logger后如下所示:2 M  r9 \$ z/ Q0 U
3 _4 F* G$ |$ R: b6 h* j

  e* _) H8 X2 Q* i
6 C& }6 ^* N5 j7 y! a5 R0 x这里要注意的是,在RTT Logger中,>后面可以自由输入>前面表示的参数,按回车键确认。无输入的情况下,按回车键跳过。" C. A. B1 s/ {
一直回车键,如果程序配置通道1正确的话,会出现下面图片的画面,不停的给log文件中写数据。
4 {" Y9 y/ j" F; z) \注意:如果程序中没有配置通道1,RTT Logger检测不到通道1的情况下就会自动关闭。& c6 T2 V3 L( T' O
正确的RTT Logger显示画面如下:
* Q6 ]; n- s4 H! E, {
* n0 V4 j( w- Z. \, [' B" A' K0 I3 P1 @) _0 ^8 O
打开上述路径中的.log文件,里面的内容如下所示,这说明成功的生成了log文件。
( B4 m( c' b. ?. T8 v
. D; D/ A) g- M) y
8 L- X( R, ~* ]2 N& z. r2 R
) R9 g( n" H3 u- N只要弄懂上面的内容,你就可以很爽的使用RTT来输出调试信息了,我们一般只使用RTT Viewer这个软件就足够了。他还可以设置显示的颜色,格式化输出等,具体的函数说明可以查看$ f2 ?; Z1 G+ e+ r" B& J3 S' V/ p
Jlink安装目录下的使用手册16.4.1章节即可。% {2 ^. |3 W% }* h5 F- M3 @: q% |
手册路径如下:D:\Program Files (x86)\SEGGER\JLink\Doc\Manuals。

---------------------% U9 q7 j1 b/ f! v! n$ ^
作者:xyz549040622

0 e5 x' @3 B3 Z) H( V$ }5 `8 B
赞 收藏 评论0 发布时间:2022-12-11 15:27

举报

0个回答

所属标签

相似技术帖

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