J-Link RTT使用
一、测试环境
1> 测试环境
系统:WIN7
MDK:keil v5.26
开发板:GD32F303C-EVAL
固件库:V1.0.2
FreeRTOS版本:V10.4.0
支持内核: ARM Cortex-M0/M0+/M1/M3/M4/M7/M23/M33 and Renesas RX100/200/600
更多详情可以参考官网:RTT
中文可以参考:仿真器代替串口打印
2> 找到JLINK驱动的安装目录。
解压后可以看到如下图所示文件,Example目录是参考的demo,RTT和Syscalls文件夹下就是移植所需要的文件
RTT目录内容:
Syscalls目录内容:
二、添加文件到工程
1> 在工程下新建一个文件夹,将上述中提到的文件放到这个文件夹中
2> 添加文件到工程
3> 添加头文件路径
三、测试使用
1>测试代码如下:
#include "gd32f30x.h"
#include "led.h"
#include "systick.h"
#include "timer.h"
#include <stdio.h>
#include "key.h"
#include "gpio.h"
#include "usart_shell.h"
#include "shell_port.h"
#include "gd25qxx.h"
#include <math.h>
#include <string.h>
#include "SEGGER_RTT.h"#if 0
/* USER CODE BEGIN 0 */
int test(int i, char ch, char *str)
{printf("input int: %d, char: %c, string: %s\r\n", i, ch, str);return 0;
}int func(int argc, char *agrv[])
{printf("%dparameter(s)\r\n", argc);for (char i = 1; i < argc; i++){printf("%s\r\n", agrv[i]);}return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), func, func, test2);//导出到命令列表里
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), test, test, test);/* USER CODE END 0 */
#endifvolatile int _Cnt=0;
unsigned char *out_float(double value, unsigned char decimal_digit, unsigned char *output_length);
int main(void)
{float value = 3.1415;unsigned char length;delay_init();/*添加上行数据缓冲区,函数原型:int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) 若BufferIndex=0,RTT组件将使用默认的缓冲和大小,其大小由SEGGER_RTT_Conf.h中的BUFFER_SIZE_UP决定,所以使用这个缓存区0比较简单,令BufferIndex=0,pBuffer=NULL,BufferSize=NULL方向:MCU-->PC同理:SEGGER_RTT_ConfigDownBuffer,和它一样,仅仅方向不同,PC-->MCU*/SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL);/*打印字符串函数*/SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample\r\n\r\n");SEGGER_RTT_WriteString(0, "###### Testing SEGGER_printf() ######\r\n");SEGGER_RTT_WriteString(0, "###### 中文 ######\r\n");SEGGER_RTT_printf(0,"value = %s \n",out_float(value,4,&length));/*与C库中printf类似,区别是不支持浮点数*/SEGGER_RTT_printf(0, "printf Test: %%c, 'S' : %c.\r\n", 'S');SEGGER_RTT_printf(0, "printf Test: %%5c, 'E' : %5c.\r\n", 'E');SEGGER_RTT_printf(0, "printf Test: %%-5c, 'G' : %-5c.\r\n", 'G');SEGGER_RTT_printf(0, "printf Test: %%5.3c, 'G' : %-5c.\r\n", 'G');SEGGER_RTT_printf(0, "printf Test: %%.3c, 'E' : %-5c.\r\n", 'E');SEGGER_RTT_printf(0, "printf Test: %%c, 'R' : %c.\r\n", 'R');SEGGER_RTT_printf(0, "printf Test: %%s, \"RTT\" : %s.\r\n", "RTT");SEGGER_RTT_printf(0, "printf Test: %%s, \"RTT\\r\\nRocks.\" : %s.\r\n", "RTT\r\nRocks.");SEGGER_RTT_printf(0, "printf Test: %%u, 12345 : %u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%+u, 12345 : %+u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%.3u, 12345 : %.3u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%.6u, 12345 : %.6u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%6.3u, 12345 : %6.3u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%8.6u, 12345 : %8.6u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%08u, 12345 : %08u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%08.6u, 12345 : %08.6u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%0u, 12345 : %0u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%-.6u, 12345 : %-.6u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%-6.3u, 12345 : %-6.3u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%-8.6u, 12345 : %-8.6u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%-08u, 12345 : %-08u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%-08.6u, 12345 : %-08.6u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%-0u, 12345 : %-0u.\r\n", 12345);SEGGER_RTT_printf(0, "printf Test: %%u, -12345 : %u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%+u, -12345 : %+u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%.3u, -12345 : %.3u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%.6u, -12345 : %.6u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%6.3u, -12345 : %6.3u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%8.6u, -12345 : %8.6u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%08u, -12345 : %08u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%08.6u, -12345 : %08.6u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%0u, -12345 : %0u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-.6u, -12345 : %-.6u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-6.3u, -12345 : %-6.3u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-8.6u, -12345 : %-8.6u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-08u, -12345 : %-08u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-08.6u, -12345 : %-08.6u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-0u, -12345 : %-0u.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%d, -12345 : %d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%+d, -12345 : %+d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%.3d, -12345 : %.3d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%.6d, -12345 : %.6d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%6.3d, -12345 : %6.3d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%8.6d, -12345 : %8.6d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%08d, -12345 : %08d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%08.6d, -12345 : %08.6d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%0d, -12345 : %0d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-.6d, -12345 : %-.6d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-6.3d, -12345 : %-6.3d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-8.6d, -12345 : %-8.6d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-08d, -12345 : %-08d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-08.6d, -12345 : %-08.6d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%-0d, -12345 : %-0d.\r\n", -12345);SEGGER_RTT_printf(0, "printf Test: %%x, 0x1234ABC : %x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%+x, 0x1234ABC : %+x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%.3x, 0x1234ABC : %.3x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%.6x, 0x1234ABC : %.6x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%6.3x, 0x1234ABC : %6.3x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%8.6x, 0x1234ABC : %8.6x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%08x, 0x1234ABC : %08x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%08.6x, 0x1234ABC : %08.6x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%0x, 0x1234ABC : %0x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%-.6x, 0x1234ABC : %-.6x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%-6.3x, 0x1234ABC : %-6.3x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%-8.6x, 0x1234ABC : %-8.6x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%-08x, 0x1234ABC : %-08x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%-08.6x, 0x1234ABC : %-08.6x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%-0x, 0x1234ABC : %-0x.\r\n", 0x1234ABC);SEGGER_RTT_printf(0, "printf Test: %%p, &_Cnt : %p.\r\n", &_Cnt);SEGGER_RTT_WriteString(0, "###### SEGGER_printf() Tests done. ######\r\n");do {_Cnt++;SEGGER_RTT_printf(0, "%d\r\n", _Cnt);delay_xms(100);} while (1);
}
/*
SEGGER_RTT_printf不支持浮点
这里引用网友写的一个浮点转字符的函数:
https://www.cnblogs.com/snowsad/p/12076740.html
Parameter:
Value Meaning
value 想要打印的数据
decimal_digit 数字小数部分的位数
_output_length 输出字符串的长度Return Value:
Value Meaning
unsigned char* 返回一个字符串指针
*/
unsigned char *out_float(double value, unsigned char decimal_digit, unsigned char *output_length)
{unsigned char _output[20];unsigned long integer;unsigned long decimal;unsigned char _output_length = 0;unsigned char _length_buff = 0;static unsigned char *return_pointer;unsigned char signal_flag;if (value < 0)signal_flag = 1;elsesignal_flag = 0;value = fabs(value);integer = (unsigned long)value;decimal = (unsigned long)((value - integer) * pow(10, decimal_digit));unsigned long integer_buff = integer;unsigned long decimal_buff = decimal;while (1){if (integer / 10 != 0)_length_buff++;else{_length_buff++;break;}integer = integer / 10;}for (int i = 0; i < _length_buff; i++){if (i == _length_buff - 1)_output[_output_length] = integer_buff % 10 + 0x30;else{//_output[_output_length] = integer_buff / 10 % 10 + 0x30;_output[_output_length] = integer_buff / (unsigned long)pow(10, _length_buff - i - 1) % 10 + 0x30;integer_buff = integer_buff % (unsigned long)pow(10, _length_buff - i - 1);//integer_buff = integer_buff % 10;}_output_length++;}_output[_output_length] = '.';_output_length++;_length_buff = 0;while (1){if (decimal / 10 != 0)_length_buff++;else{_length_buff++;break;}decimal = decimal / 10;}for (int i = 0; i < _length_buff; i++){if (i == _length_buff - 1)_output[_output_length] = decimal_buff % 10 + 0x30;else{_output[_output_length] = decimal_buff / (unsigned long)pow(10, _length_buff-i-1) % 10 + 0x30;decimal_buff = decimal_buff % (unsigned long)pow(10, _length_buff - i - 1);}_output_length++;}_output[_output_length] = 0x00;_output_length++;return_pointer = (unsigned char *)realloc(return_pointer,_output_length);*output_length = _output_length - 1;if (return_pointer == 0)return 0;else{if (signal_flag == 1){return_pointer[0] = '-';memcpy(return_pointer+1, _output, _output_length);}elsememcpy(return_pointer, _output, _output_length);}return return_pointer;
}
2>编译下载,重新上电,然后打开J-Link RTT Viewer,点击OK就可以看到输出结果,如果想仿真调试,需要先进入仿真状态,然后在点击OK。
3> 测试结果
4>将上面的代码编译,进入仿真,然后打开J-Link RTT Client软件,如下图,说明连接成功。
5>点击全速运行或单步调试就可以在窗口看到相应的打印信息。
6>client与viewer区别
client需要配合仿真使用,而viewer不需要。
client支持中文输出,而viewer不支持
四、输入测试
1>输入单个字符:
代码如下:
volatile int _Cnt;
volatile int _Delay;static char r;
char acIn[20];
int ReadNum=0;
uint16_t i=0;
/*********************************************************************
*
* main
*/
int main(void) {SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample\r\n");SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);while(1){/*读取一个键值的第一种方式*//*判断RTT的BUF缓冲区中是否有可用数据*/if(SEGGER_RTT_HasKey()){/*从RTT的BUF0的缓冲区内读取一个键值*/r = SEGGER_RTT_GetKey();if(r=='q'){SEGGER_RTT_WriteString(0,"input :q\r\n");}}/*读取一个键值的第二种方式*/
// do{// r = SEGGER_RTT_WaitKey();
// SEGGER_RTT_printf(0,"input key is: %c\r\n",r);
// }while(r != 'q');
// SEGGER_RTT_printf(0,"host has been read q\r\n");
}}
注意,这种读取键值的方式,只支持Terminal0,打开J-Link RTT Viewer进行如下配置:
如果没有自动连接,可以按F2再次进行连接,F3为断开连接。
测试结果:
2> 输入多个字符串
测试代码:
volatile int _Cnt;
volatile int _Delay;static char r;
char acIn[20];
int ReadNum=0;
uint16_t i=0;
/*********************************************************************
*
* main
*/
int main(void) {SEGGER_RTT_WriteString(0, "SEGGER Real-Time-Terminal Sample\r\n");SEGGER_RTT_ConfigUpBuffer(0, NULL, NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);while(1){/*判断RTT的BUF缓冲区中是否有可用数据*/if(SEGGER_RTT_HasKey()){/*从RTT的BUF0的缓冲区内读取一个键值*/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));}}}
这种方式支持多个Terminal,打开J-Link RTT Viewer进行如下配置:
测试结果:
五、使用小技巧
可以使用多个Terminal终端来输出不同的内容,比如终端0输出打印信息,终端1输出错误信息,J-Link RTT Viewer最多支持16个终端。
另外,还可以配置字体不同的打印颜色,方便识别,这个要远比串口好用的多。
测试代码如下:
static void _Delay(int period)
{int i = 100000*period;do { ; } while (i--);
}
int main(void)
{int cnt=0;while(1){SEGGER_RTT_SetTerminal(1);SEGGER_RTT_WriteString(0,RTT_CTRL_RESET"Red: "\RTT_CTRL_TEXT_RED"This text is red."\RTT_CTRL_TEXT_BLACK""\RTT_CTRL_BG_BRIGHT_GREEN"This background is green."\RTT_CTRL_RESET"Normal text again.\r\n");_Delay(200);cnt++;SEGGER_RTT_SetTerminal(0);SEGGER_RTT_WriteString(0,RTT_CTRL_RESET"Terminal:\r\n");SEGGER_RTT_printf(0,"%sCounter:%s%d\r\n",RTT_CTRL_RESET,RTT_CTRL_TEXT_YELLOW,cnt);if(cnt > 5){SEGGER_RTT_TerminalOut(0,RTT_CTRL_TEXT_RED"Counter overflow!\r\n");cnt=0;}}return 0;
}
测试结果:
这个是所有终端的信息,不过这个颜色是和我们想要测试的不同的,不过信息是正确的。
这里可以看出Terminal0, Terminal1这两个终端既是我们设置的颜色的输出。
J-Link RTT使用相关推荐
- java link_Java Link类代码示例
import org.nodes.Link; //导入依赖的package包/类 public static double sizeBetaCopying(DGraph graph, DGraph s ...
- mlink /j 当文件已存在时,无法创建该文件。
也是试错,没搞对路径顺序,算是踩坑了,不需要管理员 语法 > mklink 创建符号链接.MKLINK [[/D] | [/H] | [/J]] Link Target/D 创建目录符号链接.默 ...
- windows常用命令有哪些(整理)
windows常用命令有哪些(整理) 一.总结 一句话总结:其实这个好学,只要先弄懂主干,清除主干,那么枝叶的添加逻辑就很清除了 这种多内容的,散乱的,弄清除主干效率就高了 1.windows命令行的 ...
- 基础数据结构【三】————老鼠走迷宫问题————堆栈应用
假设:老鼠在一个二维地图中i行走,地图中大部分路径被墙阻断,无法前进.老鼠可以按照尝试错误的方法找到出口.只是,这只老鼠必须具备走错路时候就退回来,并且把走过的路记下来,避免下次走重复路,知道找到出口 ...
- ZOJ 2913 Bus Pass (近期的最远BFS HDU2377)
题意 在全部城市中找一个中心满足这个中心到全部公交网站距离的最大值最小 输出最小距离和满足最小距离编号最小的中心 最基础的BFS 对每一个公交网站BFS dis[i]表示编号为i的点到全部公交网 ...
- hdu 3449 Consumer 01背包
http://acm.hdu.edu.cn/showproblem.php?pid=3449 这个题AC的有点稀里糊涂(是1A过的),采用的01背包的方法: 思路:定义了两个数组用来存储最终结果和但购 ...
- 循序渐进Python3(十一) --6-- Ajax 实现跨域请求 jsonp 和 cors
Ajax操作如何实现跨域请求? Ajax (XMLHttpRequest)请求受到同源策略的限制. Ajax通过XMLHttpRequest能够与远程的服务器进行信息交互,另外XMLHttpReque ...
- Win7如何改变用户文件夹位置
现在装WIN7后第一件就是改变用户账户文件夹位置..因为里面存着一些软件的设定和信息等..不必要每次装后都手动改一次.. 已前用优化大师改.太麻烦.也不稳定有时有些目录不能完全改过来.. 通过命令mk ...
- pku 2195 Going Home KM最小权匹配问题
http://poj.org/problem?id=2195 在一个n*m的方格里有nx人(m)和ny个房子(H),(nx = ny)人每次可以向四周移动单位距离,花费1¥,求最小花费是每个人都能进入 ...
- POJ 2135 Farm Tour amp;amp; HDU 2686 Matrix amp;amp; HDU 3376 Matrix Again 费用流求来回最短路...
累了就要写题解,近期总是被虐到没脾气. 来回最短路问题貌似也能够用DP来搞.只是拿费用流还是非常方便的. 能够转化成求满流为2 的最小花费.一般做法为拆点,对于 i 拆为2*i 和 2*i+1.然后连 ...
最新文章
- android获取手机通讯录
- github使用教程及小问题
- JVM中OutOFMemory和StackOverflowError异常代码
- linux下java命令行参数_Java调用Linux命令行
- 华为P40系列全家福亮相:DxO冠军宝座已预订
- django学习笔记01
- LeetCode-326. Power of Three
- 自动化测试基础篇--Selenium多窗口、句柄问题
- 命令行打印二维码-pyqrcode
- java nio 下载网页_JavaNIO 下载网络文件保存本地报java.nio.file.AccessDeniedException:无权限操作...
- docker安装nginx并且部署前端项目
- 用python画滑稽表情_Python-画一个滑稽
- java图形用户界面基础
- 春天的致富梦ZZNU
- YouTube:如何删除油管频道Channel
- 百度算法发布历史列表
- 在线客服php技术,WeLive开源PHP在线客服系统、在线客服源码下载
- POE供电怎么用?常见PoE供电4种工程应用方法
- django用户注册、登录、注销和用户扩展
- Oracle教学辅助.数据库技术发展历史