最近在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从目标板到调试器的输出的更多相关文章

  1. iOS LLDB调试器和断点调试

    技巧一:运行时修改变量的值 你以前怎么验证是不是某个变量的值导致整段程序不能正常工作?修改代码中的变量的值,然后cmd+r重新启动app?现在你不需要这么做了,只需要设置一个断点,当程序在这进入调试模 ...

  2. 第二章排错的工具:调试器Windbg(下)

    感谢博主 http://book.51cto.com/art/200711/59874.htm 2.2  读懂机器的语言:汇编,CPU执行指令的最小单元2.2.1  需要用汇编来排错的常见情况 汇编是 ...

  3. xcode 调试器 LLDB

    本文完全转载,转载地址:点击这里 你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函 ...

  4. 与调试器共舞 - LLDB 的华尔兹

    你是否曾经苦恼于理解你的代码,而去尝试打印一个变量的值? 1 NSLog(@"%@", whatIsInsideThisThing); 或者跳过一个函数调用来简化程序的行为? 1 ...

  5. 嵌入式调试器原理和各类调试器集锦(JLINK、STLINK、CCDEBUG)

    工欲善其事,必先善其器.调试器在嵌入式开发调试中的重要性不言而喻,单步.断点和监察的效率远高于串口打印.但是,调试器对于一般开发人员往往是一个黑匣子.今天我们就来谈谈调试器的原理,顺便把自己的几类调试 ...

  6. 调试器GDB的基本使用方法

    GDB调试的三种方式: 1. 目标板直接使用GDB进行调试. 2. 目标板使用gdbserver,主机使用xxx-linux-gdb作为客户端. 3. 目标板使用ulimit -c unlimited ...

  7. GDB 调试器使用手冊

    使用GDB: 本文描写叙述GDB,GNU的原代码调试器. (这是4.12版1994年一月.GDB版本号4.16) * 文件夹: * 摘要: GDB的摘要 * 实例: 一个使用实例 * 入门: 进入和退 ...

  8. ARM调试器只能偶尔连接成功问题

    这里分析一个ARM板子JTAG调试器经常连接失败,只能偶尔连上目标板问题. 背景 这是原先另一个部门的板子,在部门合并之后,最近要对这个板子的代码体系进行转移,在过问开发进度时,工程师反映这个板子调试 ...

  9. 把 STM32 bluepill 变成调试器(daplink)

    在调一块 ARM M0 内核的板子,使用官方的 DEMO 板子来调,板子上集成了 daplink 调试器. 为了方便使用,我把目标板跟 daplink 剪开了,然后用杜邦线把 daplink 跟目标板 ...

随机推荐

  1. 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 ...

  2. core.net 创建coreclass 项目出现一些问题

    错误如下: Project CoreTest does not have a lock file. Please run "dotnet restore" to generate ...

  3. matplotlib-形状

    需要   import matplotlib.patches as mp import numpy as np import matplotlib.pyplot as plt import matpl ...

  4. [C++]2-3 倒三角形

    /* 倒三角形(Triangle) 输入正整数n<=20,输出一个n层的倒等腰三角形. 0 ######### 9 = 2* n-1 1 ####### 7 = 2*(n-1)-1 2 #### ...

  5. [C++]PAT乙级1012.数字分类 (20/20)

    /* 1012. 数字分类 (20) 给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字: A1 = 能被5整除的数字中所有偶数的和: A2 = 将被5除后余1的数字按给出顺序进行交错求和, ...

  6. 目前比较火的前端框架及UI组件

    看到的一篇总结性的文章,收藏一下,感兴趣的可以自己看看,哪些是已经会的,哪些是没听说过的,哪些是一知半解的,都可以稍微看看. 一.前端框架库: 1.Zepto.js 地址:点击打开链接 描述:Zept ...

  7. luogu P4173 残缺的字符串

    传送门 两种做法,一种是依次考虑每种字符,然后如果某个位置是该字符或者是\(*\)对应的值就是1,否则是0,然后把第一个串倒过来,fft卷积起来,最后看对应位置的值是否为m 然而上面那个做法在字符集大 ...

  8. MySql数据库学习笔记(2)

    DELETE 语法:delete from 表名 [where condition] delete from grade; TRUNCATE 用于完全清空表数据,但表结构.索引.约束不变: 语法: t ...

  9. 页面跳转、底部tabs切换页面

    1.页面跳转 import { NavController } from 'ionic-angular'; constructor(public navCtrl: NavController) { } ...

  10. DIY一些基于netty的开源框架

    几款基于netty的开源框架,有益于对netty的理解和学习! 基于netty的http server框架 https://github.com/TogetherOS/cicada 基于netty的即 ...