RTT打印时间戳

news2024/10/3 2:24:22

官方的RTT VIEWER没有打印接收时间戳的功能,经过查找后发现可以有以下三种打印时间戳的方法。

  • 第三方的RTT上位机
  • ExtraPutty
  • 自己打印

第三方的RTT上位机

码云上有一个RTT_T2的仓库,基于python qt包写的画面,通过pylink来jlink通信。

  • 优点:可以打印时间戳
  • 缺点:基于Python,RTT的实现性大打折扣,无法打印us级别的时间,有点”卡“,需要安装很多的py包,占用内存。

ExtraPutty

rtt的数据可以通过telnet传输到其他软件进行显示,RTT VIEWER启动连接好STM后,默认就已经启动telent服务,可以在ExtraPutty里面选择telnet,IP填localhost, Port填19021,进入后,再在设置里面开启时间戳显示就可以了在这里插入图片描述
不想打开RTT VIEWER的话,可以在终端里面使用命令行启动telnet服务,修改stm的对应型号就行

JLink.exe -Device STM32F407ZE -if SWD -Speed 9600 -autoconnect 1

优点:Putty可以修改风格
缺点:telnet中转后,有ms级别的延时,打印时间戳不准确

自定义打印

在RTT打印的时间,在前面加上时间就行,可以做到us级别准确显示
在这里插入图片描述
优点:准确!
缺点:需要RTT传输额外字符
附上RTT打印的宏定义

#ifndef LOG_H
#define LOG_H
#include "SEGGER_RTT.h"
#if defined(USE_HAL_DRIVER)
extern uint32_t HAL_GetTick(void);
extern uint32_t HAL_GetUs(void);
    #define SYS_MS HAL_GetTick()
    #define SYS_US HAL_GetUs()
#else
    #define SYS_MS 0  // 如果不是使用HAL库 则使用自定义的时间源
    #define SYS_US 0
#endif

#define USE_LOG_DEBUG   1
#define PRINT_TIMESTAMP 1

typedef enum {
    LOG_TERMINAL0,
    LOG_TERMINAL1,
    LOG_TERMINAL2,
    LOG_TERMINAL3,
    LOG_TERMINAL4,
    LOG_TERMINAL5,
} LogTerminal_e;

typedef enum {
    LOG_ARR_BYTE1,
    LOG_ARR_BYTE2,
    LOG_ARR_BYTE4,
    LOG_ARR_FLOAT,
    LOG_ARR_INT,
} LogArrayType_e;

#if USE_LOG_DEBUG
    #if PRINT_TIMESTAMP
        #define LOG_PROTO(type, color, format, ...)                                                                                        \
            SEGGER_RTT_printf(0, "[%02d:%03d:%03d] %s%s" format "%s\r\n", (SYS_MS / 1000) % 60, SYS_MS % 1000, SYS_US % 1000, color, type, \
                              ##__VA_ARGS__, RTT_CTRL_RESET);
        // #define LOG_PROTO(type, color, format, ...)                                                                                                \
        //     SEGGER_RTT_printf(0, "[%02d:%02d:%02d:%03d:%03d] %s%s" format "%s\r\n", (SYS_MS / (60 * 60 * 1000)) % 24, (SYS_MS / (60 * 1000)) % 60, \
        //                       (SYS_MS / 1000) % 60, SYS_MS % 1000, SYS_US % 1000, color, type, ##__VA_ARGS__, RTT_CTRL_RESET);
    #else
        #define LOG_PROTO(type, color, format, ...) SEGGER_RTT_printf(0, "%s%s" format "%s\r\n", color, type, ##__VA_ARGS__, RTT_CTRL_RESET);
    #endif

    #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(pArr, len, logArrayType, terminal)                        \
        do {                                                                    \
            SEGGER_RTT_SetTerminal(terminal);                                   \
            for (int i = 0; i < len; i++) {                                     \
                switch (logArrayType) {                                         \
                    case LOG_ARR_BYTE1:                                         \
                        SEGGER_RTT_printf(0, "%02x ", *(uint8_t *)(pArr + i));  \
                        break;                                                  \
                    case LOG_ARR_BYTE2:                                         \
                        SEGGER_RTT_printf(0, "%04x ", *(uint16_t *)(pArr + i)); \
                        break;                                                  \
                    case LOG_ARR_BYTE4:                                         \
                        SEGGER_RTT_printf(0, "%08x ", *(uint32_t *)(pArr + i)); \
                        break;                                                  \
                    case LOG_ARR_FLOAT:                                         \
                        SEGGER_RTT_printf(0, "%f ", *(float *)(pArr + i));      \
                        break;                                                  \
                    case LOG_ARR_INT:                                           \
                        SEGGER_RTT_printf(0, "%d ", *(int *)(pArr + i));        \
                        break;                                                  \
                    default:                                                    \
                        break;                                                  \
                }                                                               \
            }                                                                   \
            SEGGER_RTT_printf(0, "\r\n");                                       \
            SEGGER_RTT_SetTerminal(0);                                          \
        } while (0)

    // 初始化
    #define LOG_INIT()               \
        do {                         \
            SEGGER_RTT_Init();       \
            LOG_CLEAR();             \
            LOG_INFO("RTT Inited!"); \
        } 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(pArr, len, logArrayType, terminal)
    #define LOG_INIT()
#endif

#endif

us计算为如下

__weak uint32_t HAL_GetUs() {
    uint32_t tms = SysTick->LOAD + 1;
    return (tms - SysTick->VAL) * 1000 / tms;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker - 常用容器部署命令大全(MySQL、Redis、RabbitMQ、ES、Kibana、Nacos、Sentinel)

目录 一、常用容器运行指令 MySQL Redis RabbitMQ ElasticSearch & kibana Nacos Sentinel 一、常用容器运行指令 MySQL docker run -d --name mysql -p 3306:3306 -e TZAsia/Shanghai -e MYSQL_ROOT_PASSWORD1111 mysql:5.7 -e TZAsia/Shanghai&#xff1a;指定…

商智C店H5性能优化实战

前言 商智C店&#xff0c;是依托移动低码能力搭建的一个应用&#xff0c;产品面向B端商家。随着应用体量持续增大&#xff0c;考虑产品定位及用户体验&#xff0c;我们针对性能较差页面做了一次优化&#xff0c;并取得了不错的效果&#xff0c;用户体验值&#xff08;UEI&…

“智慧”千里眼助力水泵站

泵站是为水提供势能和压能&#xff0c;解决无自流条件下的排灌、供水和水资源调配问题的唯一动力来源&#xff0c;在工农业用水、防洪、排涝和抗旱减灾等方面发挥着重要作用。一旦出现异常&#xff0c;对经济生产将造成难以估量的损失&#xff0c;给水利安全管理造成负担。因此…

VMware Tools 启动脚本未能在虚拟机中成功运行。如果您在此虚拟机中配置了自定义启动脚本,请确保该脚本没有错误。您也可以提交支持请求,报告此问题。

问题描述&#xff1a;今天打开centos7虚拟机就是直接打不开了报了下面的错误&#xff0c;也没有动任何东西&#xff0c;点确定后&#xff0c;也是依然没有反应 问题原因&#xff1a;可能是虚拟机中的内存满了&#xff0c;需要清理内存 解决方法如下 首先cmd打开终端敲入如下命…

【linux笔记】top、ps

【linux笔记】top命令 top&#xff08;Table of process&#xff09;是动态变化的。而ps是静态的。 PID — 进程id USER — 进程所有者 PR — 进程优先级 NI — nice值。负值表示高优先级&#xff0c;正值表示低优先级 VIRT — 进程使用的虚拟内存总量&#xff0c;单位kb。VI…

软件测试|深入学习 Docker Logs

简介 Docker 是一种流行的容器化技术&#xff0c;它能够帮助用户将应用程序及其依赖项打包成一个可移植的容器。Docker logs 是 Docker 提供的用于管理容器日志的命令&#xff0c;本文将深入学习 Docker logs 的使用和管理&#xff0c;帮助用户更好地监测和解决容器问题。 Do…

ArkTS - 网络请求

一、Axios请求 应用通过HTTP发起一个数据请求&#xff0c;支持常见的GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT方法。 前端开发肯定都使用过一个叫axios的第三方库&#xff0c;它是是一个基于 promise 的网络请求库&#xff0c;可以用于浏览器和 node.js&…

网络实训模拟考察题目和答案(华为eNSP综合实验考试)

拓扑中四个交换机五个路由器&#xff0c;共九个设备 答案是对应的九个脚本&#xff08;从设备命名到保存&#xff09; 全部复制粘贴后&#xff0c;从PC1、PC2都是能Ping通服务器的&#xff08;保及格&#xff09;&#xff0c;其他要求没检查 题目 VLAN信息 设备名称端口链路…

labview 与三菱FX 小型PLC通信(OPC)

NI OPC服务器与三菱FX3U PLC通讯方法 一、新建通道名称为&#xff1a;MIT 二、选择三菱FX系列 三、确认端口号相关的参数&#xff08;COM端&#xff1a;7.波特率&#xff1a;9600&#xff0c;数据位&#xff1a;7&#xff0c;校验&#xff1a;奇校验&#xff0c;停止位&#xf…

js中函数动态调用

文章目录 一、场景二、方法2.1、动态函数2.2、eval()函数 三、最后 一、场景 在JS开发中&#xff0c;例如有些场景下&#xff0c;后端要求一个功能要请求不同的接口&#xff0c;但是传参及后续逻辑其实都是一样的&#xff0c;有些同学可能会想到在接口url处统一处理就好&#…

开关电源启动电路图

1、常规启动电路 常规启动电路的电路形式如图 接通电源开关后&#xff0c;市电电压经整流、滤波后&#xff0c;获得约300V的直流电压&#xff0c;一路经开关变压器的一次绕组送到开关管的漏极&#xff1b;另一路经R1、R2对C1进行充电&#xff0c;当C1两端电压达到一定值时&…

ES -极客学习

Elasticsearch 简介及其发展历史 起源 Lucene 于 Java 语言开发的搜索引擎库类创建于 1999 年&#xff0c;2005 年成为 Apache 顶级开源项目Lucene 具有高性能、易扩展的优点Lucene 的局限性 只能基于 Java 语言开发类库的接口学习曲线陡峭原生并不支持水平扩展原生并不支持水…

Swift爬虫使用代理IP采集唯品会商品详情

目录 一、准备工作 二、代理IP的选择与使用 三、使用Swift编写唯品会商品爬虫 四、数据解析与处理 五、注意事项与优化建议 六、总结 一、准备工作 在开始编写爬虫之前&#xff0c;需要准备一些工具和库&#xff0c;以确保数据抓取的顺利进行。以下是所需的工具和库&…

每日一题——LeetCode1089.复写0

方法一 splice&#xff1a; 通过数组的slice方法&#xff0c;碰到 0就在后面加一个0&#xff0c;最后截取原数组的长度&#xff0c;舍弃后面部分。 但这样做是违反了题目的要求&#xff0c;不要在超过该数组长度的位置写入元素。 var duplicateZeros function(arr) {var le…

rust 注释文档生成 cargo doc

rust的cargo文档生成 只需要在每个函数写清楚注释&#xff0c;就可以自动生成文档&#xff0c;很方便 即不用写文档&#xff0c;又可以快速查看&#xff0c;是开发rust的必备技能 rust安装和开发环境配置&#xff0c;可以参考&#xff1a;链接 1.写注释的方法 连续三个 \ 即…

如何计算CAN通信波特率

目录 1、理论 2、实践 3、注意事项 在CAN总线系统中&#xff0c;波特率的计算是一个关键步骤&#xff0c;它确保网络上的所有设备能够以相同的速率进行通信。 1、理论 波特率的计算涉及到几个关键参数&#xff0c;包括CAN控制器的时钟频率、分频因子、以及位时间的不同部分…

es集群安装及优化

es主节点 192.168.23.100 es节点 192.168.23.101 192.168.23.102 1.安装主节点 1.去官网下载es的yum包 官网下载地址 https://www.elastic.co/cn/downloads/elasticsearch 根据自己的需要下载对应的包 2.下载好之后把所有的包都传到从节点上&#xff0c;安装 [rootlocalho…

我在 VSCode 插件里接入了 ChatGPT,从此代码写的如诗一样

编程是一门艺术&#xff0c;代码是程序员的诗篇。那么&#xff0c;如果我们能够让代码写作变得更加优雅、高效&#xff0c;甚至如诗一样流畅呢&#xff1f; 最近&#xff0c;我在我的 VSCode 编辑器中集成了 ChatGPT 插件&#xff0c;这个改变彻底提升了我的编程体验。在这篇博…

使用docker安装mysql 8.0

打开命令行&#xff0c;运行 ocker pull mysql:8.0.21 下载成功后&#xff0c;可以看到 进入cmd&#xff0c;输入 docker run -d --name mysql -p 3306:3306 -v /root/mysql/data:/var/lib/mysql -v /root/mysql/config:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORDabc12345…

5.vue学习笔记(数组变化的侦测+计算属性+Class绑定)

文章目录 1.数组变化的侦测1.1.变更方法1.2.替换一个数组 2.计算属性计算属性缓存vs方法 3.Class绑定3.1.绑定对象3.2.多个对象的绑定形式3.3.绑定数组3.4.数组与对象 1.数组变化的侦测 1.1.变更方法 vue能够侦听响应式数组的变更方法&#xff0c;并在它们被调用时出发相关的…