DAPLINK 之 RTT 输出日志

前言

  • 1)RTT(Real Time Transfer,实时传输):SEGGER 的 Real Time Transfer (RTT) 是一种经过验证的技术,用于嵌入式应用中的系统监控和交互式用户 I/O。它结合了 SWO(Single Wire Output)和半主机模式(semihosting)的优点,同时提供了非常高的性能。

大致原理是 RTT 在 MCU 的 RAM 中使用 SEGGER RTT 控制块结构管理数据读写。通俗地说,就是 SEGGER RTT 在 RAM 创建一个区域,MCU 将日志写入到这个区域,外部程序使用调试器,通过 SWD/JTAG 协议,访问 MCU 的 DAP,进而读取 RAM 中该区域的日志。

1 安装 SEGGER RTT

  • 1)下载:https://www.segger.com/downloads/jlink/

  • 2)安装完成后,在 \SEGGER\JLink_V794j\Samples\RTT 目录下可找到 RTT 源码。

废弃原因:
首先是我这里使用的 DAPLINK 而非 JLink,而且 DAPLink 的源码已经完整支持 SEGGER RTT,不再需要我们手动移植 SEGGER RTT 代码,所以可以不用安装 SEGGER RTT。
其次,OpenOCD 源码中也包含了对 RTT 的支持,那么我们也就不需要 J-Link RTT Viewer 了(虽然它的 GUI 看着着实不错)。

2 OpenOCD 下的 rtt

  • 1)本来通过 《通过DAPLink和STLink使用RTT输出日志》 这篇文章研究 JLink 的 SEGGER RTT 怎么应用到 DAPLink 上,文章提到在没有 JLink 的情况下,可以使用 PyOCD + ST-Link 实现。

  • 2)突然想起在研究 OpenOCD 源码时偶然好像见过 rtt_server_register_commands() 注册了 rtt 相关命令,搜索了一下后,看到了这篇文章《配合OpenOCD的RTT使用Trice日志库》,遂尝试了一下后果然可以

2.1 调试环境

  • 1)DAPLink 源码可以到 github 上搜索 “DAPLINK air32”:

  • 2)添加宏定义:

    • (1)查看 DAPLink 源码发现,要想使用 SEGGER RTT 输出日志,需要声明两个宏定义:

      • 另外,DAPLink 提供了两个用于输出日志的宏定义 debug_msg() 和 debug_data()
    • (2)那么我们在 /records/hic_hal/stm32f103xb.yaml 文件中添加 DAPLINK_DEBUG 和 DAPLINK_DEBUG_RTT 两个宏定义。

    • (3)使用 __FILE__ 宏定义输出文件信息时,全路径太长,那么我们可以在该文件中这样修改:

    使用 __FILENAME__ 宏定义来输出不携带路径信息的文件名。Keil 中可以使用 __MODULE__ 宏定义,而 CMake 中本来应该使用 cmake 内置函数在编译期处理的,但可能由于 DAPLINK 中的 cmake 模板问题,导致一直无法成功,只能在运行期解决,影响性能,不要使用在生产环境。

    • (4)还有最后一点,如果使用 CMake,那么需要注释掉 /records/tools/gcc_arm.yaml 中的 -Werror 项,否则编译时警告信息将转换为错误导致无法编译通过。
  • 3)根据自已常用的 IDE 生成 stm32f103xb_bl 和 stm32f103xb_stm32f103rb_if 项目(我这里使用基于 cmake 的 CLion):

    progen generate -t cmake -v -p stm32f103xb_bl
    progen generate -t cmake -v -p stm32f103xb_stm32f103rb_if
    
  • 4)下载或编译最新版本的 OpenOCD(见其它文章)。

    openocd --version
    Open On-Chip Debugger 0.12.0-00006-ga7204e9bf-dirty (2024-02-12-14:47)
    Licensed under GNU GPL v2
    For bug reports, read
            http://openocd.org/doc/doxygen/bugs.html
    
  • 5)最后还要准备一个调试器,我这里使用的是 PWLINK。

2.2 输出日志

  • 1)新建一个 rtt.cfg 文件,添加如下内容:

    init 
    # rtt setup <address> <size> <ID>. setup RTT
    rtt setup 0x20000000 0x1000 "SEGGER RTT"
    
    rtt start
    # rtt server start <port> <channel>. Start a RTT server.
    rtt server start 8888 0
    
    • (1)该文件可以放置到 OpenOCD 的 scripts/ 目录下,以便 OpenOCD 可以找到。
    • (2)上述命令也可以通过 telnet 127.0.0.1 4444 连接到 OpenOCD Server 后逐条输入,只是每次都手动输入比较麻烦罢了。
    • (3)rtt setup 命令用来设置 SEGGER RTT 控制块在 RAM 中的位置,如果不知道,那么就设置 RAM 的最大地址范围。
  • 2)命令行运行如下命令:

    openocd -d2 -f interface/cmsis-dap.cfg -f target/stm32f1x.cfg -f rtt.cfg
    
    • 这里指定日志级别为 2 级 Info;调用接口为 cmsis-dap;目标芯片为 stm32f1x;rtt.cfg 为 RTT 的配置。
    • 当日志中有 “Control block found at 0x200003dc” 以及 8888 端口的监听等内容时表示成功
  • 3)然后,我们随便添加几行日志,编译并下载到开发板中:

  • 4)最后,通过 telnet 127.0.0.1 8888 连接到 OpenOCD RTT Server 后,即可看到日志内容:

  • 5)至此,学习 DAPLINK 源码的准备工作已经完成了。

3 关于日志中的文件名

  • 1)我们知道在 C 语言中,__FILE__ 宏定义输出的是文件的全路径名,观察输出日志可以确认。大多数情况下,我们只需要知道文件名而不需要路径。

  • 2)Keil armclang 中,可以通过 __MODULE__ 来替代。

  • 3)arm_gcc 中:

    • (1)可以重新声明一个 __FILENAME__ 宏定义来封装 strrchr() 函数。这种做法是程序运行期处理的,显然不太有利于单片机程序。
    • (2)使用一些 Makefile 支持的命令(如 subst、notdir、abspath)来定义 __FILENAME__。这样一来,这些命令在程序编译期就可以把需要的文件名裁剪好,效率更高一些。
  • 4)然而,可能因为 DAPLINK 采用的 CMake 版本较老,其采用的 target_compile_definitions() 方法添加宏定义。我测试过无数种写法均无法成功,无奈只能选择 strrchr() 函数。

  • 5)最终结果:

参考

  • https://sourcelizi.github.io/202203/trice-and-rtt/
  • https://blog.csdn.net/qq_36973838/article/details/131564806
  • https://blog.csdn.net/m0_37636212/article/details/124980698
  • https://wanghenshui.github.io/2019/09/23/\_\_FILE\_\_.html

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql查看和修改默认配置

1.查看最大连接数 SELECT max_connections; 或者 SHOW VARIABLES LIKE max_connections;2.查看当前连接的客户端 SHOW PROCESSLIST;2.临时设置最大连接数 SET GLOBAL max_connections 500;3.临时设置连接客户端交互超时时间 SET GLOBAL interactive_timeout 1800;4.永久生…

3.3 Thymeleaf语法

文章目录 引言Thymeleaf标签显示标签链接地址标签条件判断标签元素遍历标签 Thymeleaf表达式变量表达式选择变量表达式消息表达式链接表达式 Thymeleaf内置对象上下文对象上下文变量上下文区域请求对象响应对象会话对象日期对象 实战演练创建控制器创建模板页面 结语 引言 Thy…

【Python爬虫】看电影还在用VIP?一个python代码让你实现电影自由!附源码

今日主题 如何用Python解析vip电影。 什么是vip电影&#xff1f; 这些vip电影啊&#xff0c;想要观看的话&#xff0c;必须充值会员&#xff0c;否则没法看。 比如这个&#xff1a; 这些vip电影解析后呢&#xff1f; 不需要会员&#xff0c;不需要登录&#xff0c;可以直接…

4、.Net 快速开发框架:DncZeus - 开源项目研究文章

DncZeus 是一个基于 ASP.NET Core 和 Vue.js 的前后端分离的通用后台管理系统框架&#xff0c;其愿景是成为一个易于使用且功能丰富的 .NET Core 通用后台权限管理模板系统基础框架。项目名称 "DncZeus" 由 "Dnc"(.NET Core 的缩写)和 "Zeus"(古…

STMicroelectronics 意法半导体芯片选型表

意法半导体作为全球知名的半导体厂商&#xff0c;其产品广泛应用于各个领域&#xff0c;从消费电子到工业控制&#xff0c;从汽车电子到通信设备&#xff0c;都能看到意法半导体芯片的身影。在电子硬件设计领域&#xff0c;芯片的选型至关重要。亿配芯城&#xff08;ICgoodFind…

SpringBoot+MyBatis+MySQL项目基础搭建

一、新建项目 1.1 新建springboot项目 新建项目 选择SpringBoot&#xff0c;填写基本信息&#xff0c;主要是JDK版本和项目构建方式&#xff0c;此处以JDK17和Maven举例。 1.2 引入依赖 选择SpringBoot版本&#xff0c;勾选Lombok&#xff0c;Spring Web&#xff0c;MyBa…

线性代数知识学习

1.标量 简单操作 长度 2.向量 parallel for all do 点乘、正交 3.矩阵 乘法&#xff08;矩阵乘以向量&#xff09; 4.范数 &#xfeff;&#xfeff;取決于如何衡量b和c的长度 &#xfeff;&#xfeff;常见范数 &#xfeff;&#xfeff;矩阵范数&#xff1a;最小的满足的…

小猿口算炸鱼脚本

目录 写在前面&#xff1a; 一、关于小猿口算&#xff1a; 二、代码逻辑 1.数字识别 2.答题部分 三、代码分享&#xff1a; 补充&#xff1a;软件包下载 写在前面&#xff1a; 最近小猿口算已经被不少大学生攻占&#xff0c;小学生直呼有挂。原本是以为大学生都打着本…

【C语言】循环结构-for循环

循环结构&#xff1a;计算机最擅长的事情就是做简单重复的工作 通过控制循环变量&#xff0c;是否满足循环条件来调整循环次数。 for(初始化;循环条件;循环控制) {循环体; }#include <stdio.h> #include <math.h> /* 功能&#xff1a;循环结构&#xff08;for&…

[LeetCode] 695. 岛屿的最大面积

题目描述&#xff1a; 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0&#xff08;代表水&#xff09;包围着。 岛…

Java 小游戏《超级马里奥》

文章目录 一、效果展示二、代码编写1. 素材准备2. 创建窗口类3. 创建常量类4. 创建动作类5. 创建关卡类6. 创建障碍物类7. 创建马里奥类8. 编写程序入口 一、效果展示 二、代码编写 1. 素材准备 首先创建一个基本的 java 项目&#xff0c;并将本游戏需要用到的图片素材 image…

大数据-174 Elasticsearch Query DSL - 全文检索 full-text query 匹配、短语、多字段 详细操作

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

推荐一个可以免费上传PDF产品图册的网站

​在数字化时代&#xff0c;企业将产品图册以PDF格式上传至网络&#xff0c;不仅便于客户浏览和下载&#xff0c;还能提升企业的专业形象。今天&#xff0c;就为您推荐一个可以免费上传PDF产品图册的网站——FLBOOK&#xff0c;轻松实现产品图册的在线展示。 1.注册登录&#x…

交通目标识别数据集YOLO 模型 ui界面✓图片数量15000,xml和txt标签都有 11类 交通道路车辆行人红黄绿数据集 红绿灯数据集 交通信号数据集

YOLO交通目标识别 数据集 模型 ui界面 ✓图片数量15000&#xff0c;xml和txt标签都有&#xff1b; ✓class&#xff1a;biker&#xff0c;car&#xff0c;pedestrian&#xff0c;trafficLight&#xff0c;trafficLight-Green&#xff0c;trafficLight-GreenLeft&#xff0c; tr…

调用第三方接口

目录 一、分析给出的接口文档 二、请求体格式之间的区别 三、示例代码 一、分析给出的接口文档 一般的接口文档包括以下几大部分&#xff1a; 1、请求URL&#xff1a;http://{ip}:{port}/api/ec/dev/message/sendCustomMessageSingle 2、请求方式&#xff1a;POST、GET等 3、…

3.C++经典实例-奇数还是偶数

要判断一个数是奇数还是偶数&#xff0c;只需要判断这个数是否能被2整除即可&#xff0c;如果要判断是否能整除&#xff0c;则要判断当前数除以2的余数是否为0&#xff0c;在C中&#xff0c;余数&#xff0c;使用%号&#xff0c;因此&#xff0c;程序为&#xff1a; #include …

缓存常见问题:缓存穿透、雪崩、击穿及解决方案分析

1. 什么是缓存穿透&#xff0c;怎么解决&#xff1f; 缓存穿透是指用户请求的数据在缓存中不存在即没有命中&#xff0c;同时在数据库中也不存在&#xff0c;导致用户每次请求该数据都要去数据库中查询一遍。如果有恶意攻击者不断请求系统中不存在的数据&#xff0c;会导致短时…

C++初阶学习第七弹——string的模拟实现

C初阶学习第六弹------标准库中的string类_c语言返回string-CSDN博客 通过上篇我们已经学习到了string类的基本使用&#xff0c;这里我们就试着模拟实现一些&#xff0c;我们主要实现一些常用到的函数。 目录 一、string类的构造 二、string类的拷贝构造 三、string类的析构函…

第十四届单片机嵌入式蓝桥杯

一、CubeMx配置 &#xff08;1&#xff09;LED配置 &#xff08;1&#xff09;LED灯里面用到了SN74HC573ADWR锁存器&#xff0c;这个锁存器有一个LE引脚,这个是我们芯片的锁存引脚&#xff08;使能引脚&#xff09;&#xff0c;由PD2这个端口来控制的 &#xff08;2&#xff…

13图书归还-云图书管理系统(Vue3+Spring Boot+element plus)

目录 1 接口地址2 后台代码RecordControllerBookController 3 view/books/BookRecordsVue中前端框架搭建4 api/record.js文件写查询用户借阅记录的接口代码5 api/book.js中写归还图书、查询当前借阅图书接口代码6 BookRecordsVue中导入接口函数&#xff0c;并调用7 运行效果 1 …