RTT打印在分区跳转后无法打印问题

场景:

RTT打印仅占用JLINK的带宽,比串口传输更快更简洁,同时RTT可以使用jscope对代码里面的变量实时绘图显示波形,而采用串口打印波形无法实时打印。同时可以保存原始数据到本地进行分析,RTT在各方面完胜串口。


问题描述

正常使用RTT没有太大的问题,而对FLASH进行分区后,跳转不同的分区需要重新连接RTT才可以输出,造成极大的不便。


原因分析:

RTT跳转后,都会重新初始化RTT的block地址,就会导致RTT VIEWER不能及时识别新的blcik地址,从对应的地址取数据显示了。那么通过固定RTT的block地址是不是就可以了,打开SEGGER_RTT.c在290行的位置,注销_SEGGER_RTT _acDownBuffer _acUpBuffer的初始化,将其固定在0x2000000的地址,如下:

// #if SEGGER_RTT_CPU_CACHE_LINE_SIZE
//   #if ((defined __GNUC__) || (defined __clang__))
//     SEGGER_RTT_CB _SEGGER_RTT                                                             __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
//     static char   _acUpBuffer  [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)]   __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
//     static char   _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)] __attribute__ ((aligned (SEGGER_RTT_CPU_CACHE_LINE_SIZE)));
//   #elif (defined __ICCARM__)
//     #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
//     SEGGER_RTT_CB _SEGGER_RTT;
//     #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
//     static char   _acUpBuffer  [SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_UP)];
//     #pragma data_alignment=SEGGER_RTT_CPU_CACHE_LINE_SIZE
//     static char   _acDownBuffer[SEGGER_RTT__ROUND_UP_2_CACHE_LINE_SIZE(BUFFER_SIZE_DOWN)];
//   #else
//     #error "Don't know how to place _SEGGER_RTT, _acUpBuffer, _acDownBuffer cache-line aligned"
//   #endif
// #else
//   SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT));
//   SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer  [BUFFER_SIZE_UP]));
//   SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN]));
// #endif__attribute__((section(".ARM.__at_0x20000000"))) SEGGER_RTT_CB _SEGGER_RTT;
__attribute__((section(".ARM.__at_0x200000B0"))) static char _acDownBuffer[BUFFER_SIZE_DOWN];
__attribute__((section(".ARM.__at_0x200000C0"))) static char _acUpBuffer[BUFFER_SIZE_UP]; 

但是发现还是不行,每次烧录完芯片都要重新连接RTT,而且要很久,RTT每次都要搜索地址很费时间,搜索block后,分区都已经跳转完毕,跳转前的信息无法查看。最后需要RTT VIEWER中的地址为固定地址后就实时打印跳转的信息了。
在这里插入图片描述


结果:

测试后发现分区跳转后可以打印,但是还是存在偶尔打印缺失的情况,查找后发现block中还有内容未被RTT VIEWER读取就执行了跳转,block里面的内容被重置,也就无法读取了,在跳转前判断一下block是否还有内容就Ok了,跳转的内容如下:

uint32_t *inputAddr;  // !声明为全局变量,防止执行__set_MSP后,变量被释放
uint32_t jumpAddr;    // !设置MSP后改变了栈底地址,导致原来的局部变量范围出了新栈的空间,被系统释放void JumpToCode(uint32_t addr) {inputAddr = (uint32_t *)addr;jumpAddr  = *(uint32_t *)(addr + 4);if ((*inputAddr & 0x2FFE0000) == 0x20000000) {// 等待rtt打印完毕 超时退出, rtt viewer中需要指定block地址,避免搜索地址耗费太长时间uint32_t start = HAL_GetTick();while (SEGGER_RTT_GetBytesInBuffer(0) > 0) {if (HAL_GetTick() - start > 100)break;}HAL_RCC_DeInit();HAL_DeInit();__set_FAULTMASK(1);__set_CONTROL(0);__set_MSP(*inputAddr);((void (*)(void))jumpAddr)();}
}

在这里插入图片描述
最后附上方便打印的宏,类似ROS里面的开头

#ifndef LOG_H
#define LOG_H
#include "SEGGER_RTT.h"#define USE_LOG_DEBUG 1#define TERMINAL_0    0
#define TERMINAL_1    1
#define TERMINAL_2    2
#define TERMINAL_3    3
#define TERMINAL_4    4
#define TERMINAL_5    5#if USE_LOG_DEBUG#define LOG_PROTO(type, color, format, ...) SEGGER_RTT_printf(0, "  %s%s" format "\r\n%s", color, type, ##__VA_ARGS__, RTT_CTRL_RESET)#define LOG_INFO(format, ...)               LOG_PROTO("[INFO]:", "", format, ##__VA_ARGS__)                           // 无颜色日志输出#define LOG_DEBUG(format, ...)              LOG_PROTO("[DEBUG]:", RTT_CTRL_TEXT_BRIGHT_GREEN, format, ##__VA_ARGS__)  // 绿色日志输出#define LOG_WARN(format, ...)               LOG_PROTO("[WARN]:", RTT_CTRL_TEXT_BRIGHT_YELLOW, format, ##__VA_ARGS__)  // 黄色日志输出#define LOG_ERROR(format, ...)              LOG_PROTO("[ERROR]:", RTT_CTRL_TEXT_BRIGHT_RED, format, ##__VA_ARGS__)    // 红色日志输出#define LOG_CLEAR()                         SEGGER_RTT_WriteString(0, "\r\n" RTT_CTRL_CLEAR)                          // 清屏// 打印数组#define LOG_ARRAY(pbuf, len, terminal)                \do {                                              \SEGGER_RTT_SetTerminal(terminal);             \uint8_t* _pbuf = (pbuf);                      \int _len       = (len);                       \for (int _i = 0; _i < _len; _i++) {           \SEGGER_RTT_printf(0, "%02x ", _pbuf[_i]); \}                                             \SEGGER_RTT_printf(0, "\r\n");                 \SEGGER_RTT_SetTerminal(0);                    \} while (0)#else#define LOG_INFO(format, ...)#define LOG_DEBUG(format, ...)#define LOG_WARN(format, ...)#define LOG_ERROR(format, ...)#define LOG_CLEAR()#define LOG_ARRAY(pbuf, len, terminal)#endif#endif

同时RTT不能打印浮点数,RTT的格式化字符串函数没有对浮点进行格式化,可以手动添加即可,参考了某论坛的(找不到出处了),在SEGGER_RTT_printf.c的523行switch的default语句前面添加下面的case

                case 'f':  // 添加输出浮点数的功能。默认带两位小数。case 'F': {float fv = (float)va_arg(*pParamList, double);  // 取出输入的浮点数值if (fv < 0)_StoreChar(&BufferDesc, '-');                                    // 判断正负号v = abs((int)fv);                                                    // 取正整数部分_PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags);  // 显示整数_StoreChar(&BufferDesc, '.');                                        // 显示小数点v = abs((int)(fv * 100));v = v % 100;_PrintInt(&BufferDesc, v, 10u, 2, FieldWidth, FormatFlags);  // 显示小数点后两位break;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/210332.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot+vue热带野生动物园景点预约门票订票系统

热带野生动物园景点预约订票系统为野生动物园提供景点管理服务的系统&#xff0c;通过登录系统&#xff0c;管理该野生动物园所有的景点信息、景点分类信息、野生动物园新闻、通知公告、回复会员留言等&#xff0c;并可以通过订单管理查看会员预定的订单信息&#xff0c;对订单…

阿里云经济型e实例云服务器怎么样?性能测评

阿里云服务器ECS推出经济型e系列&#xff0c;经济型e实例是阿里云面向个人开发者、学生、小微企业&#xff0c;在中小型网站建设、开发测试、轻量级应用等场景推出的全新入门级云服务器&#xff0c;CPU采用Intel Xeon Platinum架构处理器&#xff0c;支持1:1、1:2、1:4多种处理…

OpenLayers实战,WebGL图层鼠标经过要素高亮显示,根据变量自动修改WebGL图层要素的透明度、大小和颜色

专栏目录: OpenLayers实战进阶专栏目录 前言 本章讲解OpenLayers使用WebGL图层情况下,鼠标经过要素高亮显示,根据变量自动修改WebGL图层要素的透明度、大小和颜色的功能。 webgl图层的样式并不像普通矢量图层直接修改或者切换样式就可以的,而是要预先通过webgl的运算符编…

springboot使用redis缓存乱码(key或者 value 乱码)一招解决

如果查看redis中的值是这样 创建一个配置类就可以解决 package com.deka.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; i…

kettle获取系统信息和获取当前时间

在同步数据表的时候要更新插入时间和更新时间&#xff0c;使用kettle的获取系统信息组件 添加插入时间和更新时间 点击类型&#xff0c;选择不同时间&#xff0c;如下图所示&#xff0c;类型处选择信息类型&#xff08;系统日期&#xff09; 获取系统信息 1、系统日期(可变)&a…

设置滚动条样式

滚动条样式&#xff1a; 下面是代码&#xff1a; <!doctype html> <html lang"en"><head><meta charset"UTF-8"><title>CSS3自定义滚动条</title><style>header {font-family: Lobster, cursive;text-align: c…

介绍一个功能强大的shopify app——TINYIMG

各位观众老爷&#xff0c;南来的北往的&#xff0c;东去的西走的&#xff0c;今天给大家推荐一个功能很强大的shopify app 当当当 那就是 tinyimg 这个app有多牛逼呢&#xff0c;且听我慢慢道来 首先这个app可以用来优化图片大小&#xff0c;给你的网站提提速 然后这个app还可…

YOLOv5改进: Inner-IoU基于辅助边框的IoU损失,高效结合 GIoU, DIoU, CIoU,SIoU 等 | 2023.11

💡💡💡本文独家改进:Inner-IoU引入尺度因子 ratio 控制辅助边框的尺度大小用于计算损失,并与现有的基于 IoU ( GIoU, DIoU, CIoU,SIoU )损失进行有效结合 推荐指数:5颗星 新颖指数:5颗星 💡💡💡Yolov5/Yolov7魔术师,独家首发创新(原创),适用于…

2014年9月26日 Go生态洞察:使用Docker部署Go服务器

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Linux python安装 虚拟环境 virtualenv

根目录创建 venvs 文件夹 sudo mkdir /venvs 进入 /venvs 目录 cd /venvsp 创建虚拟环境&#xff0c;前提要按照 python3 安装 的 命令 sudo apt install python3 sudo python3 -m venv 虚拟环境名 激活虚拟环境 sourcepippip /venvs/zen-venv/bin/activatepinpi 安装flask pip…

oracle数据库常见巡检脚本-系列一

简介 作为数据库管理员&#xff08;DBA&#xff09;&#xff0c;定期进行数据库的日常巡检是非常重要的。以下是一些原因&#xff1a; 保证系统的稳定性&#xff1a;通过定期巡检&#xff0c;DBA可以发现并及时解决可能导致系统不稳定的问题&#xff0c;如性能瓶颈、资源利用率…

大数据预处理技术

文章目录 前言 大数据技术成为前沿专业 也是现在甚至未来的朝阳产业&#xff0c;大数据有分别是 数据预处理 数据存储 大数据处理和分析 数据可视化 部分组成 &#xff0c;大数据行业有数据则称王&#xff0c;大数据的核心是数据本身 怎么获取有价值的数据呢&#xff1f;本章讲…