用SWD调试接口测量代码运行时间 ( SWO )

用SWD调试接口测量代码运行时间

关于时间测量的种种问题

在嵌入式中,我们经常需要测量某段代码的执行时间或测量事件触发的时间,常规的思路是:

1:在测量起始点,反转电平
2:在测量结束点,再次反转电平

然后通过示波器或者逻辑分析仪来测量反转间隔,也就是代码时间

这种方法,在测量两个或多个时间信号同步的时候,非常有用,实际上,这也是唯一的方法。

但是如果在测量中,其它代码也会控制这个管脚电平或者周期性动作,这时便需要在<动作1>之前
增加前导码,从而便于在繁杂的波形中,一眼识别出需要特定的波形

同时,如果测量的时间值非常小,那么用示波器即便可以识别,但不容易捕获

SWD解决方案

在ARM Cortex-M 芯片中,用SWD调试接口取代了传统的JTAG调试接口,从而占用MCU更少的管脚,同时提高了调试性能。

SWD由四根线组成,SWO,SWDIO,SWCLK,GND;SWDIO和SWCLK组成了基本的串行调试接口,SWO则提供一个信息输出通道,
可以输出很多信息,比如指令的执行时间或者ISR触发事件,所以我们可以通过SWD接口配合IDE来获取代码执行时间,从而在某种程度上取代示波器

IAR中使用SWD测量时间

注:下文假设读者已经熟悉IAR的使用方法,如果您不熟悉,请参考网上对应的入门教程

1:配置SWD时钟

这里,我们需要在调试器选项中

1:选择SWD调试接口

2:将时钟频率设置成MCU的时钟频率,同时将SWO时钟选择成自动识别模式

配置完成后,进入debug模式,选择J-Link—>SWD Configuration配置页,重点关注SWO时钟的实际值,如下所示

如果显示不对,则说明SWO配置不对

2:设置时标变量

在示波器方案中,我们需要用某个管脚来测量实际,SWD也类似,只不过将物理管脚替换成某个变量而已。

这里,我们设置TimeLine变量作为时标变量

volatile uint32_t TimeLine = 0;

volatile是为了防止TimeLine被编译器优化,从而造成测量值不准确。

3:设置Data Log

Data Log是IAR的一种调试断点,类似数据断点,IAR会实时记录对应的变化,因此被称为Log。

在调试模式下,在TimeLine变量上右击,选择”Set Data Log Breakpoint for ‘TimeLine’”选项

设置后,不会像常规的断点那样用红色来标注,在IAR底下,我们需要进入Jlink的BreakPoint Usage来查看,如下图所示

这里,我们可以清楚的看到TimeLine已经被设置成读写断点

4:使能Data Log和Data Log Summary

在Jlink菜单下,进入Data LogData Log Summary窗口,然后右键选择Enable

至此,我们设置完毕,可以将TimeLine放置在测量的起始,结束位置

5:开始时间测量

我们的测试代码如下

while(1)
{
    TimeLine = 0;
    index++;
    TimeLine = 1;
    index++;
}

按上述完成配置后,点击Run全速运行几秒钟,然后暂停,可以在Data LogData Log Summary窗口看到对应的信息

咦,为什么全是Overflow???哪里错了

还记得我们刚开始设置SWO的时钟速度吗?当时间测量点的间隔过小,且发送速率过快时,会超出SWO的传输能力,从而造成overflow问题

为了验证确实是这个原因,我们将在代码中插入一些软件延时,如下所示

void delay(volatile uint32_t tick)
{
    while(tick--);
}

....

while(1)
{
    TimeLine = 0;
    index++;
    delay(0xFFFF);
    TimeLine = 1;
    index++;
    delay(0xFFFF);
}

重编译,进入调试模式,全是运行,暂停,ok,这次可以看到一切正常了

/******************** Data log 窗口 ************************/

Time    Approx  PC  Description Type    Value   Address
17040.43 us X   0x8000a6c   TimeLine    W   0   @ 0x20000390+?
25232.68 us X   0x8000a7c   TimeLine    W   1   @ 0x20000390+?
33424.99 us X   0x8000a6c   TimeLine    W   0   @ 0x20000390+?
41617.24 us X   0x8000a7c   TimeLine    W   1   @ 0x20000390+?
49809.54 us X   0x8000a6c   TimeLine    W   0   @ 0x20000390+?
58001.79 us X   0x8000a7c   TimeLine    W   1   @ 0x20000390+?
66194.10 us X   0x8000a6c   TimeLine    W   0   @ 0x20000390+?
74386.35 us X   0x8000a7c   TimeLine    W   1   @ 0x20000390+?
82578.65 us X   0x8000a6c   TimeLine    W   0   @ 0x20000390+?
90770.90 us X   0x8000a7c   TimeLine    W   1   @ 0x20000390+?
98963.21 us X   0x8000a6c   TimeLine    W   0   @ 0x20000390+?

/********************* Data Log Summary 窗口 *****************/
TimeLine
  Total Accesses:   335
  Read Accesses:    0
  Write Accesses:   335

Approximative time count: 335

Overflow count: 0

另外,我们也可以打开J-link菜单下的TimeLine选项(不要和我们的TimeLine变量搞混了)

效果图如下所示

6:注意事项

当SWO数据量过大的时候,容易出现过冲的情况,解决方案是在调试模式下,单步进行,从而避免发送大数据

全文完,希望本文对您有帮助^_^

时间: 2024-08-24 13:09:52

用SWD调试接口测量代码运行时间 ( SWO )的相关文章

python测量代码运行时间方法

Python 社区有句俗语: “python自己带着电池” ,别自己写计时框架. Python3.2具备一个叫做 timeit 的完美计时工具可以测量python代码的运行时间. timeit 模块: timeit 模块定义了接受两个参数的 Timer 类.两个参数都是字符串. 第一个参数是你要计时的语句或者函数. 传递给 Timer 的第二个参数是为第一个参数语句构建环境的导入语句. 从内部讲, timeit 构建起一个独立的虚拟环境, 手工地执行建立语句,然后手工地编译和执行被计时语句.如果

Charles辅助调试接口(转)

原文地址Charles辅助调试接口 前面有一篇讲了关于抓包工具fiddler和charles,这里再写写我是怎样用charles辅助调试接口.Charles下载传送门. 这篇文章写了个头,没时间就一直放着没写,今天刚好周六,也早点下班了(苦逼的周六加班党),就把这个写完吧,其实这两天有点感冒头晕晕的,尽量不写错吧. 经常会有这样的场景: 场景一: 想看看其他的App是怎样设计请求,怎样设计返回数据格式,某一个功能点请求分几个实现的.最近我在用某听书软件听鬼故事(^0^),它们限制非VIP每天只能

Stopwatch检测代码运行时间

System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 开始监视代码运行时间 // you code .... stopwatch.Stop(); // 停止监视 TimeSpan timespan = stopwatch.Elapsed; // 获取当前实例测量得出的总时间 double hours = timespan.TotalHours; // 总小时 double minutes =

C#如何测试代码运行时间

第一种方式: System.Diagnostics.Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 开始监视代码运行时间 // 需要测试的代码 .... stopwatch.Stop(); // 停止监视 TimeSpan timespan = stopwatch.Elapsed; // 获取当前实例测量得出的总时间 double hours = timespan.TotalHours; // 总小时 double min

linux上使用J-Link调试S3C2440裸机代码

工具: segger的jlink仿真器 segger的jlink for linux 交叉编译工具链里面的arm-xx-linux-xx-gdb 初始化脚本 工具安装 segger的jlink for linux 进入Segger官网--->Download--->J-Link/J-Trace--->J-Link Software and Documentation Pack.有deb.rpm.tgz三种包可供选择,随便选一个,我选的是tgz.由于我的仿真器是和谐版,所以我不敢选择高版本

调试接口你还在用postman吗

作者 | 陈凯玲 来源 | my.oschina.net/keking/blog/3104972 接口调试是每个软件开发从业者必不可少的一项技能,一个项目的的完成,可能接口测试调试的时间比真正开发写代码的时间还要多,几乎是每个开发的日常工作项. 所谓工欲善其事必先利其器,在没有尝到IDEA REST真香之前,postman(chrome的一款插件)确实是一个非常不错的选择,具有完备的REST Client功能和请求历史记录功能.但是当使用了IDEA REST之后,postman就可以丢了,因为,

Mac上使用Visual Studio Code开发/调试.NET Core代码

Mac上使用Visual Studio Code开发/调试.NET Core代码 .Net Core 1.0终于发布了,Core的一大卖点就是跨平台.这个跨平台不只是跨平台运行,而且可以跨平台开发.今天抽空研究了下在Mac下如何使用VS Code来开发.NET Core程序,并且调试代码. 1.安装.NET Core 在mac上打开终端: ~$ brew update ~$ brew install openssl ~$ brew link --force openssl 如果不能使用brew命

wp8 入门到精通 测量代码执行时间

Stopwatch time = new Stopwatch(); byte[] target = new byte[size]; for (int j = 0; j < size; j++) target[j] = unchecked((byte)j); //Otherwise parts of the array are optimised out. CCMD5Core.GetHash(target); time.Start(); for (int i = 1; i <= iteratio

Objective-C 计算代码运行时间

转自:http://www.isaced.com/post-213.html Objective-C 计算代码运行时间 JUN 25 今天看到一篇关于iOS应用性能优化的文章,其中提到计算代码的运行时间,觉得非常有用,值得收藏.不过在模拟器和真机上是有差异的,以此方法观察程序运行状态,提高效率. 第一种:(最简单的NSDate) NSDate* tmpStartData = [NSDate date]; //You code here... double deltaTime = [[NSDate