J-Link RTT的使用方法

J-Link RTT & JTrace

序言

Jlink可用直接输出调试信息,省去串口工具(配置麻烦+硬件接线乱+占用IO)

Jlink输出调试信息有两种

  • Jlink的Trace
  • Jlink的RTT (Real Time Transfer)

!!!待完善!!!


MDK 环境下:

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
#define ITM_Port16(n) (*((volatile unsigned short*)(0xE0000000+4*n)))
#define ITM_Port32(n) (*((volatile unsigned long *)(0xE0000000+4*n)))

#define DEMCR (*((volatile unsigned long *)(0xE000EDFC)))
#define TRCENA 0x01000000

int fputc(int ch, FILE *f)
{
if (DEMCR & TRCENA) {
while (ITM_Port32(0) == 0);
ITM_Port8(0) = ch;
}
return(ch);
}

RTT

Jlink RTT 官网资料

RTT其实原理就是读取RAM上某个Buff的数据,这个Buff可以通过RTT的CB(control block)找到。

教程

下载Jlink的工具后,安装后程序目录有Samples文件夹(default: C:\Program Files\SEGGER\JLink\Samples),文件夹内就有RTT的源码。

  1. 将源码的RTT/目录下 SEGGER_RTT_Printf.c SEGGER_RTT.c 两个文件添加到工程里,并解决头文件包含问题。
  2. Examples/目录下就有使用历程,移植到你的工程就好。可以参考Main_RTT_InputEchoApp.cMain_RTT_PrintfTest.c
  3. 打开 J-Link RTT Viewer软件,选择Device,输入RTT Control Block的地址connect即可。
    1. RTT Control Block的地址可以输入RAM的范围让J-Link RTT Viewer软件自己去搜索。
    2. 也可手动输入,而RTT_V754a的RTT Control Block_SEGGER_RTTfile:SEGGER_RTT.c line:279image-20210917214218565
  4. 一顿操作下来正常就可以收到数据了。

RTT 源码

Included files

  • RTT/
    • SEGGER_RTT.c - RTT的主要模块。
    • SEGGER_RTT.h - RTT的主要模块。
    • SEGGER_RTT_ASM_ARMv7M.S - ARMv7M 的优化实现
    • SEGGER_RTT_Printf.c - (‘ SEGGER_RTT_Printf() ‘)的简单实现。
  • Syscalls/
    • SEGGER_RTT_Syscalls_*.c - printf() 重定向
  • Config/
    • SEGGER_RTT_Conf.h - RTT配置文件。
  • Examples/
    • Main_RTT_InputEchoApp.c - Example application which echoes input on Channel 0.
    • Main_RTT_MenuApp.c - Example application to demonstrate RTT bi-directional functionality.
    • Main_RTT_PrintfTest.c - Example application to test RTT’s simple printf implementation.
    • Main_RTT_SpeedTestApp.c - Example application to measure RTT performance. (Requires embOS)

API

函数名称描述
SEGGER_RTT_Read()从输入缓冲区读取数据。
SEGGER_RTT_Write()将数据写入输出缓冲区。
SEGGER_RTT_WriteString()将\0结尾字符串写入输出缓冲区。
SEGGER_RTT_printf()将格式化的字符串写入输出缓冲区。
SEGGER_RTT_GetKey()从输入缓冲区 0 中获取一个字符。
SEGGER_RTT_HasKey()检查输入缓冲区 0 中是否有字符可用。
SEGGER_RTT_WaitKey()等待输入缓冲区 0 中的字符可用并获取它。
SEGGER_RTT_ConfigUpBuffer()配置向上(输出)缓冲区。
SEGGER_RTT_ConfigDownBuffer()配置向下(输入)缓冲区。
SEGGER_RTT_Init()仅使用 RAM 目标时初始化 RTT 控制块结构。
SEGGER_RTT_SetTerminal()将“虚拟”终端设置为通过 Write 和 WriteString 用于通道 0 上的输出。
SEGGER_RTT_TerminalOut()通过“虚拟”终端发送以\0结尾的字符串。

RTT 软件

image-20210918101414512

  • J-Link RTT Viewer软件用的比较多

  • J-Link RTT Logger软件可以将输出的数据保存到文件,并显示通信速率和通信数据量。

  • J-Link RTT Client可以在调试的时候,充当客户端,输出数据。据说支持中文

note:

  • 程序如果跑在RAM中,J-Link可能会错误地识别出init部分中的块,而不是数据部分中的实际块。为了防止这种情况,将SEGGER_RTT_IN_RAM的定义设置为1。现在,J-Link将在应用程序中调用第一个SEGGER_RTT函数之后找到正确的RTT缓冲区。建议在应用程序开始时调用SEGGER_RTT_Init()。

不同通道输出数据

1
2
3
4
5
6
7
8
9
10
11
12
SEGGER_RTT_TerminalOut(0, "SEGGER_RTT_TerminalOut 0\r\n");
SEGGER_RTT_TerminalOut(1, "SEGGER_RTT_TerminalOut 1\r\n");
SEGGER_RTT_TerminalOut(2, "SEGGER_RTT_TerminalOut 2\r\n");



SEGGER_RTT_SetTerminal(0);
SEGGER_RTT_printf(0, "SEGGER_RTT_printf 0\r\n");
SEGGER_RTT_SetTerminal(1);
SEGGER_RTT_printf(0, "SEGGER_RTT_printf 1\r\n");
SEGGER_RTT_SetTerminal(2);
SEGGER_RTT_printf(0, "SEGGER_RTT_printf 2\r\n");

输出带颜色的字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
//
// Control sequences, based on ANSI.
// Can be used to control color, and clear the screen
//
#define RTT_CTRL_RESET "\x1B[0m" // Reset to default colors
#define RTT_CTRL_CLEAR "\x1B[2J" // Clear screen, reposition cursor to top left

#define RTT_CTRL_TEXT_BLACK "\x1B[2;30m"
#define RTT_CTRL_TEXT_RED "\x1B[2;31m"
#define RTT_CTRL_TEXT_GREEN "\x1B[2;32m"
#define RTT_CTRL_TEXT_YELLOW "\x1B[2;33m"
#define RTT_CTRL_TEXT_BLUE "\x1B[2;34m"
#define RTT_CTRL_TEXT_MAGENTA "\x1B[2;35m"
#define RTT_CTRL_TEXT_CYAN "\x1B[2;36m"
#define RTT_CTRL_TEXT_WHITE "\x1B[2;37m"

#define RTT_CTRL_TEXT_BRIGHT_BLACK "\x1B[1;30m"
#define RTT_CTRL_TEXT_BRIGHT_RED "\x1B[1;31m"
#define RTT_CTRL_TEXT_BRIGHT_GREEN "\x1B[1;32m"
#define RTT_CTRL_TEXT_BRIGHT_YELLOW "\x1B[1;33m"
#define RTT_CTRL_TEXT_BRIGHT_BLUE "\x1B[1;34m"
#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "\x1B[1;35m"
#define RTT_CTRL_TEXT_BRIGHT_CYAN "\x1B[1;36m"
#define RTT_CTRL_TEXT_BRIGHT_WHITE "\x1B[1;37m"

#define RTT_CTRL_BG_BLACK "\x1B[24;40m"
#define RTT_CTRL_BG_RED "\x1B[24;41m"
#define RTT_CTRL_BG_GREEN "\x1B[24;42m"
#define RTT_CTRL_BG_YELLOW "\x1B[24;43m"
#define RTT_CTRL_BG_BLUE "\x1B[24;44m"
#define RTT_CTRL_BG_MAGENTA "\x1B[24;45m"
#define RTT_CTRL_BG_CYAN "\x1B[24;46m"
#define RTT_CTRL_BG_WHITE "\x1B[24;47m"

#define RTT_CTRL_BG_BRIGHT_BLACK "\x1B[4;40m"
#define RTT_CTRL_BG_BRIGHT_RED "\x1B[4;41m"
#define RTT_CTRL_BG_BRIGHT_GREEN "\x1B[4;42m"
#define RTT_CTRL_BG_BRIGHT_YELLOW "\x1B[4;43m"
#define RTT_CTRL_BG_BRIGHT_BLUE "\x1B[4;44m"
#define RTT_CTRL_BG_BRIGHT_MAGENTA "\x1B[4;45m"
#define RTT_CTRL_BG_BRIGHT_CYAN "\x1B[4;46m"
#define RTT_CTRL_BG_BRIGHT_WHITE "\x1B[4;47m"


SEGGER_RTT_WriteString(0,RTT_CTRL_RESET"Red: "\
RTT_CTRL_TEXT_RED"This text is red."\
RTT_CTRL_BG_BRIGHT_GREEN"This background is green.\r\n");

输入字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
if(SEGGER_RTT_HasKey())
{
char r = SEGGER_RTT_GetKey();
SEGGER_RTT_WriteString(0,"input:%c\r\n", r);
}


if(SEGGER_RTT_HasKey())
{
ReadNum = SEGGER_RTT_Read(0,&acIn[0], sizeof(acIn));
for(i=0;i<20;i++)
{
if(0x0A != acIn[i])
{
ReadNum++;
}
else
{
break;
}
}
SEGGER_RTT_Write(0,acIn,ReadNum);
ReadNum=0;
memset(acIn,0,sizeof(acIn));
}

J-Link RTT的使用方法
https://www.oikiou.top/2021/18d811b/
作者
Oikiou
发布于
2021年9月24日
许可协议