通过printf从目标板到调试器的输出
最近在SEGGER的博客上看到Johannes Lask写的一篇关于在调试时使用printf函数从目标MCU输出信息到调试器的文章,自我感觉很有启发,特此翻译此文并推荐给各位同仁。当然限于个人水平,有不当之处恳请指正。原文网址:https://blog.segger.com/getting-printf-output-from-target-to-debugger/

Erich Styger最近发布了一篇《关于如何使用ARM Cortex-M目标上的单线输出(SWO)添加控制台功能》的伟大教程。
这激发了我写一篇在嵌入式目标(包括SWO和RTT)上的调试输出(“printf”)实现的更普遍的文章。
从目标调试输出
有不同的方法来从目标应用程序获取调试输出。
自从早期嵌入式系统以来,已经有了硬件依赖的解决方案,如使用UART或USB CDC。但是应用程序可能已经使用了UART,CDC需要目标硬件上的USB堆栈和USB连接器。
第一个软件解决方案是semihosting。使用semihosting,CPU停止打印输出,并由调试器重新启动“幕后”操作。打印一个消息可能需要几毫秒到几百毫秒的时间,因为这是一个昂贵的操作。调试器需要意识到目标已经停止执行,读取寄存器和内存,写入内存,然后重新启动CPU。这意味着目标CPU在这段时间内不运行。因此,semihosting可以简单地不用于需要实时行为的应用,例如通信栈。另外,semihosting实现是依赖于调试器的,而使用semihosting的应用程序可能在没有连接调试器的情况下运行。
然后还有ARM的SWO跟踪端口和SEGGER的实时传输(RTT)。
单线输出
SWO是由ARM为Cortex-M3,M4和M7设备设计的单引脚接口。引脚可以使用标准调试连接器连接到调试探头,并与SWD接口(而不是JTAG)一起使用。目标MCU可以在CPU引脚上传输数据包,类似于UART TX引脚,时钟速率来自CPU时钟。在调试器上设置SWO需要知道CPU时钟速度。如果应用程序的某些部分在启动前必须在初始化之前进行输出,或者在应用程序运行时时钟速度发生变化,那么这一点尤为重要。SWO不会如semihosting发送输出那样停止CPU。通过SWO的输出速度取决于组态的SWO速度。数据分组,即调试输出分组,以特殊格式编码。这允许发送多达32个数据包类型(刺激),但也会导致一些协议开销,这将以10 MHz SWO速度将事情减慢到〜1.5 us / char。这意味着输出80个字符大约需要120个微秒。要在RTOS或中断程序中使用来自多个任务的SWO,在SWO输出期间应禁用中断,这可能会影响系统的实时行为。
尽管SWO最常用于打印调试消息。它也可用于记录中断进入/退出和功能进入/退出,定期对PC值或内存中的变量进行采样,或者用于事件通知。
Erich全面介绍了如何在调试消息中使用SWO,如何在目标上进行设置,以及如何在主机上获取输出。
实时传输
RTT是SEGGER的调试终端解决方案。它将SWO的优点与其他方法的特点相结合。RTT是一种仅用于软件的解决方案,而不是标准调试连接以外的目标设备上不需要额外的硬件。它可以与任何J-Link一起使用,即使使用诸如J-Link OB,OpenSDA或转换的ST-LINK等小型板载机型。
RTT允许非常高的传输速度,而不会影响目标的实时行为。没有协议开销,打印消息可以在一微秒或更短的时间内完成,基本上只需要做一个单个memcpy()的时间。由于RTT的速度非常快,所以输出可以通过锁定中断来保证线程安全,而这种中断对系统的实时行为影响最小。当目标应用程序正在运行时,输出消息由J-Link读取并传输到主机。
与UART类似,RTT是双向的。您可以从主机向目标应用程序发送输入。双向通信允许您控制目标系统,而无需任何其他输入设备。使用RTT可以实现全功能终端。
RTT实现源代码可以自由地在任何系统中使用,提供功能和自由。
在主机上使用RTT是灵活并且容易的。J-Link软件包括可以与任何调试工具并行使用的RTT Viewer,一个GUI。您还可以使用Telnet客户端连接到调试会话(端口19031)并与目标进行通信。一些调试器甚至直接集成RTT。Embedded Studio和独立调试器Ozone可以在其终端窗口中通过RTT显示目标输出,并且不需要任何其他工具。
概要

printf调用与不同实现的速度比较
在从嵌入式目标执行SWO调试输出之前,只能使用低效或依赖硬件的方法。
使用SWO ARM设计了一个快速的解决方案。它重量轻且快速,但具有一些缩写,因为它仅在某些Cortex-M器件上可用,需要额外的引脚连接到MCU,并且是单向的。
RTT结合了SWO的所有优点,并增加了更多功能。它比SWO更快,不仅限于Cortex-M,允许通过标准调试连接进行双向通信,并且在任何需要系统的实时情况下都是最不具有干扰性的。
当您可以使用RTT时,没有任何理由使用SWO。
通过printf从目标板到调试器的输出的更多相关文章
- iOS LLDB调试器和断点调试
技巧一:运行时修改变量的值 你以前怎么验证是不是某个变量的值导致整段程序不能正常工作?修改代码中的变量的值,然后cmd+r重新启动app?现在你不需要这么做了,只需要设置一个断点,当程序在这进入调试模 ...
- 第二章排错的工具:调试器Windbg(下)
感谢博主 http://book.51cto.com/art/200711/59874.htm 2.2 读懂机器的语言:汇编,CPU执行指令的最小单元2.2.1 需要用汇编来排错的常见情况 汇编是 ...
- xcode 调试器 LLDB
本文完全转载,转载地址:点击这里 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函 ...
- 与调试器共舞 - LLDB 的华尔兹
你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? 1 NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函数调用来简化程序的行为? 1 ...
- 嵌入式调试器原理和各类调试器集锦(JLINK、STLINK、CCDEBUG)
工欲善其事,必先善其器.调试器在嵌入式开发调试中的重要性不言而喻,单步.断点和监察的效率远高于串口打印.但是,调试器对于一般开发人员往往是一个黑匣子.今天我们就来谈谈调试器的原理,顺便把自己的几类调试 ...
- 调试器GDB的基本使用方法
GDB调试的三种方式: 1. 目标板直接使用GDB进行调试. 2. 目标板使用gdbserver,主机使用xxx-linux-gdb作为客户端. 3. 目标板使用ulimit -c unlimited ...
- GDB 调试器使用手冊
使用GDB: 本文描写叙述GDB,GNU的原代码调试器. (这是4.12版1994年一月.GDB版本号4.16) * 文件夹: * 摘要: GDB的摘要 * 实例: 一个使用实例 * 入门: 进入和退 ...
- ARM调试器只能偶尔连接成功问题
这里分析一个ARM板子JTAG调试器经常连接失败,只能偶尔连上目标板问题. 背景 这是原先另一个部门的板子,在部门合并之后,最近要对这个板子的代码体系进行转移,在过问开发进度时,工程师反映这个板子调试 ...
- 把 STM32 bluepill 变成调试器(daplink)
在调一块 ARM M0 内核的板子,使用官方的 DEMO 板子来调,板子上集成了 daplink 调试器. 为了方便使用,我把目标板跟 daplink 剪开了,然后用杜邦线把 daplink 跟目标板 ...
随机推荐
- bzoj 2726 任务安排(3)/loj 10184-10186 斜率优化
任务安排1 #include<bits/stdc++.h> #define int long long using namespace std; ; int n,s,t[N],c[N],f ...
- core.net 创建coreclass 项目出现一些问题
错误如下: Project CoreTest does not have a lock file. Please run "dotnet restore" to generate ...
- matplotlib-形状
需要 import matplotlib.patches as mp import numpy as np import matplotlib.pyplot as plt import matpl ...
- [C++]2-3 倒三角形
/* 倒三角形(Triangle) 输入正整数n<=20,输出一个n层的倒等腰三角形. 0 ######### 9 = 2* n-1 1 ####### 7 = 2*(n-1)-1 2 #### ...
- [C++]PAT乙级1012.数字分类 (20/20)
/* 1012. 数字分类 (20) 给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字: A1 = 能被5整除的数字中所有偶数的和: A2 = 将被5除后余1的数字按给出顺序进行交错求和, ...
- 目前比较火的前端框架及UI组件
看到的一篇总结性的文章,收藏一下,感兴趣的可以自己看看,哪些是已经会的,哪些是没听说过的,哪些是一知半解的,都可以稍微看看. 一.前端框架库: 1.Zepto.js 地址:点击打开链接 描述:Zept ...
- luogu P4173 残缺的字符串
传送门 两种做法,一种是依次考虑每种字符,然后如果某个位置是该字符或者是\(*\)对应的值就是1,否则是0,然后把第一个串倒过来,fft卷积起来,最后看对应位置的值是否为m 然而上面那个做法在字符集大 ...
- MySql数据库学习笔记(2)
DELETE 语法:delete from 表名 [where condition] delete from grade; TRUNCATE 用于完全清空表数据,但表结构.索引.约束不变: 语法: t ...
- 页面跳转、底部tabs切换页面
1.页面跳转 import { NavController } from 'ionic-angular'; constructor(public navCtrl: NavController) { } ...
- DIY一些基于netty的开源框架
几款基于netty的开源框架,有益于对netty的理解和学习! 基于netty的http server框架 https://github.com/TogetherOS/cicada 基于netty的即 ...