一文读懂RTT – 作者:LEdge1

最近在调试一块芯片的时候要实时读取芯片内部的数据而且没有串口。看完了@Parad0x 大佬的《通过设备UART接口调试获取shell》之后突然想起Jlink仿真的时候可以实时读取数据,那么应该也可以当作串口,结果一找还真的发现了RTT(Real Time Transfer)这个比串口还厉害还好用,后面翻译制作了一些文档给大家食用。

什么是RTT

使用 RTT,可以从目标MCU输出信息,并以极高的速度向应用程序发送输入,而不会影响目标的实时行为。SEGGER RTT 可用于任何J-Link设备和任何支持的目标处理器,允许后台内存访问。

RTT 支持双向多个通道,这些通道可用于不同的目的,并为用户提供尽可能的自由。

默认实现使用每个方向一个通道,用于可打印终端输入和输出。使用 J-Link RTT 查看器,此通道可用于多个”虚拟”终端,允许仅使用一个目标缓冲区打印到多个窗口(例如标准输出的窗口、错误输出的窗口、调试输出的窗口)。例如,可以使用额外的向上(到主机)通道发送分析或事件跟踪数据。

图片[1]-一文读懂RTT – 作者:LEdge1-安全小百科

RTT 通信

可通过不同的应用程序与目标上的 RTT 实现进行通信。该功能甚至可以使用 J-LINK SDK 集成到自定义应用程序中。
在目标应用程序中使用 RTT 是很容易的。实施代码可免费下载,并可集成到任何现有应用程序中。
要通过 RTT 进行通信,可以使用任何 J-LINK。通过终端(通道 0)进行通信的简单方法是在激活与 J-Link(例如通过调试会话)的连接时,与 Telnet 客户端或类似客户端创建连接。J-Link 软件包附带一些针对不同目的的更高级的应用程序。

J-LINK RTT VIEWER

J-LINK RTT VIEWER 是主要的 Windows GUI 应用程序,用于在调试主机上使用 RTT 的所有功能。
RTT 查看器可以单独使用,打开与 J-Link 和目标的连接,或与运行调试会话平行。

RTT 查看器支持 RTT 的所有主要功能:

第 0 频道的终端输出

向通道 0 发送文本输入

最多 16 个虚拟终端,只有一个目标通道

控制文本输出:彩色文本,擦除控制台

在第 1 频道记录数据

图片[2]-一文读懂RTT – 作者:LEdge1-安全小百科

J-LINK RTT Client

J-Link RTT 客户端充当 Telnet 客户端,但在调试会话关闭时自动尝试重新连接到 J-Link 连接。J-LINK RTT 客户端是用于 Windows、Linux 和 macOS 的 J-LINK软件和文档包的一部分,可用于简单的 RTT 使用案例。

图片[3]-一文读懂RTT – 作者:LEdge1-安全小百科

J-LINK RTT LOGGER

使用 J-Link RTT 记录器,可以读取上通道 1 中的数据并记录到文件。
例如,此通道可用于向主机发送性能分析数据。J-Link RTT 记录器打开指向 J-LINK的专用连接,可以单独使用,无需运行调试器。
该应用程序是Windows、Linux 和 OS X 的 J-LINK软件和文档包的一部分。
J-Link RTT 记录器的源可用作在其他 PC 应用程序(如调试器)中集成 RTT 的起点,并且是J-Link SDK 的一部分。

图片[4]-一文读懂RTT – 作者:LEdge1-安全小百科

RTT 的工作原理

目标实现

实时传输使用目标内存中的 SEGGER RTT 控制块结构来管理数据读取和写入。控制块包含一个 ID,以便通过连接的 J-Link 在内存中找到它,并为每个可用通道提供环缓冲结构,描述通道缓冲区及其状态。
可在编译时间配置可用通道的最大数量,并且每个缓冲区可以在运行时由应用程序配置和添加。上下缓冲区可以单独处理。
每个通道可以配置为阻止或非阻止。在阻止模式下,应用程序将等待缓冲区已满,直到所有内存都能够书写,导致应用状态受阻,但防止数据丢失。在非阻止模式下,只有适合缓冲区或根本没有的数据将被编写,其余的数据将被丢弃。这允许实时运行,即使没有调试器连接。开发人员不必创建特殊的调试版本,代码可以在发布应用程序中保留。

图片[5]-一文读懂RTT – 作者:LEdge1-安全小百科

定位控制块

当 RTT 在主机上处于活动状态时,无论是直接通过 RTT 查看器等应用程序使用 RTT,还是通过 Telnet 连接到使用 J-Link(如调试器)的应用程序,J-Link 会自动搜索目标已知 RAM 区域中的 SEGGER RTT 控制块。也可以通过主机应用程序设置 RAM 区域或控制块的特定地址,以加快检测速度,否则无法自动找到该块。

内部结构

图像显示了目标中的简化结构。
可能有任意数量的”上缓冲区描述符”(目标 ->主机),以及任意数量的”向下缓冲区描述符”(主机 -> 目标)。每个缓冲区大小都可以单独配置。缓冲区的灰色区域是包含有效数据的区域。对于向上缓冲区,写入指针由目标编写,读取指针由调试器(J-Link,主机)编写。当读写指点指向相同的元素时,缓冲区为空。

要求

SEGGER RTT 不需要任何额外的引脚或硬件,尽管 J-Link 通过标准调试端口连接到目标。它不需要目标的任何配置或调试环境中,甚至可以以不同的目标速度使用。
RTT 可与运行调试会话平行使用,无需入侵,也无需任何 IDE 或调试器。

RTT 性能

SEGGER RTT 的性能明显高于用于将数据输出到主机 PC 的任何其他技术。平均文本行可以在一微秒或更短的时间内输出。图片[6]-一文读懂RTT – 作者:LEdge1-安全小百科

速度比较是在STM32F407 M4运行在168 MHz。

传输速度

输出数据发送到主机的最大速度取决于目标缓冲器大小和目标接口速度。即使小目标缓冲区为 512 字节,与高接口速度和 0.5 MiB/s 的 RTT 速度也有可能与常规 J-Link 设备

图片[7]-一文读懂RTT – 作者:LEdge1-安全小百科

RTT 向上通道的缓冲器可能相对较小。所需的最小缓冲大小可以与一毫秒内写入的数据量和一个写入动作的最大值相近。如果数据发送频率较低,缓冲区应该有足够的空间来处理一个写入发送的数据。如果数据发送更频繁,缓冲区大小应足以在一毫秒内编写的最大数据量。该图显示发送不同数量的数据时所需的最小缓冲大小,均匀分布,每100us发送一次和每1毫秒发送。

每发送100us

字节每写

字节每毫秒

缓冲区大小

1

10

6

2

20

11

5

50

31

10

100

61

20

200

101

50

500

401

每1毫秒发送一次

字节每写

字节每毫秒

缓冲区大小

10

10

11

20

20

21

50

50

51

100

100

101

200

200

201

500

500

501

图片[8]-一文读懂RTT – 作者:LEdge1-安全小百科

用J-LINK PRO V4=36MHz JTAG 速度测量的值。目标:SEGGER emPower(NXP K66) 运行在 168 MHz

内存足迹

RTT 实现代码用于RAM控制块中每个通道的500字节ROM和24字节ID+24字节。每个通道都需要一些缓冲区内存。建议的尺寸为1kByte用于上行通道,16至32字节用于下行通道,具体取决于内/输出的负载。

Memory

Usage

ROM Usage

~500 Bytes

RAM Usage

24 Bytes fixed + (24 + SizeofBuffer) Bytes / channel

RTT 实现

SEGGER RTT 实现以 ANSI C 编写,可以使用代码集成到任何嵌入式应用程序中,可在下面下载。

RTT 可以通过简单易用的 API 使用。甚至可以覆盖使用 RTT 的标准打印功能。使用 RTT 将print()所花的时间缩短到最低,并允许将调试信息打印到主机 PC,而应用程序执行时间关键、实时任务。

SEGGER RTT 实现包括print()的简单实现,可用于通过 RTT 编写格式化字符串。SEGGER_RTT_Printf() 比大多数标准库打印件实现要小,不需要堆栈,只需要可配置的堆栈量。

SEGGER RTT 实现完全可配置,并具有预处理器定义。

API 功能

功能名称

描述

SEGGER_RTT_Read()

从输入缓冲区阅读数据。

SEGGER_RTT_Write()

将数据写入输出缓冲区。

SEGGER_RTT_WriteString()

将零终止字符串写入输出缓冲区。

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()

设置”虚拟”终端,通过书写和写弦在通道0上用于输出。

SEGGER_RTT_TerminalOut()

通过”虚拟”终端发送零终止字符串。

示例代码

RTT 保持很简单,无需任何配置即可使用。

/********************************************************
*    SEGGER MICROCONTROLLER GmbH & Co KG         *
*    Solutions for real time microcontroller applications *
**********************************************************
*                                                        *
*    (c) 2014  SEGGER Microcontroller GmbH & Co KG       *
*                                                        *
*     www.segger.com   Support: [email protected]       *
*                                                        *
----------------------------------------------------------
File: RTT.c
Purpose : Simple implementation for output via RTT.
          It can be used with any IDE.           
--------  END-OF-HEADER  ---------------------------------*/

#include "SEGGER_RTT.h"
static void _Delay(int period) {
  int i = 100000*period;
  do { ; } while (i--);
}
int main(void) 
{ do
{ SEGGER_RTT_WriteString(0, "Hello World from SEGGER!\r\n"); _Delay(100); } while (1); return 0; } /**************** End of file ************************/

RTT 可用于任何目标,该目标由 J-Link 支持,并允许在目标运行时访问后台内存。

Core

RTT

Cortex-M0

Cortex-M0+

Cortex-M1

Cortex-M23

Cortex-M3

Cortex-M33

Cortex-M4

Cortex-M7

RX100

RX200

RX600

RTT in PC Applications

使用颜色进行文本输出

通过 RTT 读取的所有数据都像从目标中读取一样冲洗,无需任何修改。
这允许打印 RTT 数据的应用程序处理 ANSI 控制序列,以粗体显示数据或更改其颜色。在 Linux 控制台中支持在终端应用程序中处理 ANSI 控制序列。
在 Windows 上,需要像 ANSICON(http://adoxa.altervista.org/ansicon这样的包装应用程序,并可用于呼叫 RTT 客户端。

图片[9]-一文读懂RTT – 作者:LEdge1-安全小百科

来源:freebuf.com 2021-06-29 10:45:26 by: LEdge1

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论