ramlife

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

转自: http://www.armbbs.cn/forum.php?mod=viewthread&tid=95867&highlight=Ozone

承接上一个帖子:
Ozone使用介绍-基础功能
http://armbbs.cn/forum.php?mod=viewthread&tid=95855&extra=page%3D1
因为废话和贴图太多,一个帖子不方便看,所以分为了三个帖子,本帖介绍Trace功能。

其实几个月前还是没有太关注Trace这个功能,最近趁购买J-Trace的时候,也顺道看了看Trace的一些相关介绍。
Trace其实分为很多种(自己瞎划分的哈,大家随便看看):
1、自己写printf,根据自己的printf来进行跟踪
2、利用基于MCU支持的Jlink_RTT、 USB CDC、TCP/IP、串口等种方式的流模式
,和一些内嵌入工程的接口调试代码,来提供Trace记录,如SystemView(基于Segger的RTT,号称可以跟踪裸机不知道怎么做到的)、Tracealyzer(基于多种流模式)
System介绍:https://www.segger.com/products/development-tools/systemview/

Tracealyzer介绍:https://percepio.com/tracealyzer/

3、利用基于MCU硬件的Trace接口(比如Trace Pins、TraceBuffer、SWO)而实现的追踪功能。其中SWO(Serial Wire Viewer(SWV))速度很低,但是占用接口很少;TraceBuffer(ETB算是)的上限会基于MCU本身的buffer大小;Trace Pins(ETM)只是负责实时上报出去,由跟踪调试器(J-Trace等)进行对应的协议转发或处理。
以下是Ozone手册的介绍:

ARM官网也会对自家硬件的ETM功能做对应介绍:(ST的手册这方面没有啥介绍)http://www2.keil.com/coresight/

感觉其中2主要针对带有OS的目标程序进行追踪,主要说说3:
下图摘自http://www.myir-tech.com/resource/510.asp(米尔科技)

ETB,嵌入式跟踪缓存
CoreSightETB 是一个跟踪接收器,它可使用可配置大小的 RAM 为跟踪数据提供芯片上存储。
ETM,嵌入式跟踪宏单元
ETM宏单元为 ARM 微处理器提供实时指令跟踪和数据跟踪。跟踪软件工具使用 ETM 生成的信息重建全部或部分程序的执行情况。

CTI:Cross Trigger Interface ATB:Advanced Trace Bus

这么看的话,如果想要在STM32上实现硬件的Trace功能,需要的调试器本身就必须对接Trace接口。“大家都有便宜的”的Jlink是无法满足的,我之前购买的Stlink V3、DAPlink应该是都不行的。这个时候必须购买具备Trace功能(接口)的调试器了。在我决定购买Jlink Trace的时候,并没有比对过其他家具备Trace功能的调试器(好吧,就是不知道有……,当时还以为IAR只做IDE工具,没有调试器的)。
我购买的:
德国的Segger:J-TracePro https://www.segger.com/products/debug-trace-probes/

后面搜了下,发现以下几家其实是都支持的。
瑞典的IAR:I-Jet Trace https://www.iar.com/iar-embedded-workbench/add-ons-and-integrations/in-circuit-debugging-probes/

(算英国?)ARM(自家的宝宝):ULINKpro https://store.developer.arm.com/store/debug-probes/ulinkpro-debug-adapter#purchase>

德国LAUTERBACH(调试界的劳斯莱斯):Cortex-M (ARMv6/7/832-bit) Debugger
https://www.lauterbach.com/frames.html?home.html

其他的欢迎大家补充,支持Cortex M系列的我目前知道的就是这几个了。具体性能不敢对比,都是调试界的泰山北斗,算是神仙打架吧……;每家支持跟踪的调试器,都有配套自己的跟踪工具(I-Jet和ULINKpro好像是集成进入IAR和Keil中了)

毕竟买的是J-Trace,上一张和Jlink的对比图,发现还是会大一圈的,如下图

其中Jlink&Trace的手册也给出了连接方法,和PCB的接口是对应的

后面的Trace都是基于Ozone进行演示的,如果有其他“小伙伴”有其它Trace工具的,欢迎借给我测试功能_

跟跟踪相关的三个窗口分别是Code Profile、InstructionTrace还有Timeline,这时候可以选择把这些窗口打开。

Trace需要进行配置才可以,因为上一偏帖子是关闭了Trace的,所以这时候在具备Trace的界面会提示Trace已经被禁止了,需要手动打开

配置有三种:
1、Trace Pins配置

其中时间标签(TimeStamps)可以选择勾选,官方手册上面写道,如果不勾选时间标签的话,还可以进一步提升跟踪性能。这个也好理解,毕竟都需要通过Trace的硬件接口(ARM的ETM协议)上报出来,减少了TimeStamps的参数(不再占传输带宽了),理应提高跟踪性能。

CPU时钟频率设置,我的理解是为了根据指令条目综合得到Timeline的时间轴信息的,毕竟Trace回来的指令只能编号,目标板也不可能提供时间信息,即使提供也太占传输带宽了。

TracePort 带宽的话,我觉得如果是目标板设计时,要么就会留出所有的端口(4个),要么一个也不会留,没道理项目上设计预留Trace接口,还只给出了1或2个吧……Segger提供的测试板是4个,所以选择4bit。
最大指令计数上限,这个地方目前Ozone的上限是64M,设置大于64M没有意义。这个后面再Timeline窗口会提到。

Trace-Time是个时间修正设置。根据Ozone的跟踪精度介绍,我的理解是在这里可以对跟踪的数据进行延迟的修正。对我意义不大,没有那么高的精度要求。

2、Trace Buffer:STM32F4不支持,不知道怎么测试

3、SWO:本次没有测试,毕竟已经有Trace Pin了

当正确设置完毕后,就可以进行追踪了,因为还没有开始RUN起来,所以追踪的窗口还是显示No Data

点开RUN的时候,程序和用其他IDE一样,已经
有个细节需要注意,Segger是有一套自己的(STM32F4xx_Startup.s)启动文件的,虽然套路和我们常用的ST的一样,都是从Reset_Handler启动,进行初始化的,两者的写法略有不同,不过后面都是调用system_stm32f4xx.c(这个都是ST提供的了)文件。移植不同IDE工程的时候,这个地方也是需要进行一些改动的(比如从Keil移植到ES)。

因为启动文件的不同,所以会导致在Run之后,Ozone在使用自家启动文件(例程里面就是使用自家的启动文件)的时候,就可以追踪从Reset_Handler启动后的执行情况。

但是如果直接使用Keil工程包导入的使用ST自带的启动文件的话,Ozone并不能正确识别启动文件的操作。

Ozone的起始点是可以设置的

先上个全局的动态图看一下吧(这个图我指令跟踪上限是10M)

1、Timeline时间线窗口:
当打开Trace功能,同时开始运行程序,Ozone会根据J-Trace不断通过接口协议(USB3.0 或者 千兆网线)上报的ETM数据进行记录。根据上报的ETM记录,可以重建整个时间线的指令执行情况。横轴指令数目或时间(根据指令计数和设置的MCU主频得导的时间),纵轴是函数之间的调用关系,不需要使用RTOS,裸跑也能实现。

以下是裸跑的情况

猜测STM32的指令都是一个指令周期相同,所以不存在不等分的情况
在时间线中选中任何一个函数的图框,都会跳转到该函数在文件窗口中的语句位置、反汇编窗口的指令位置、指令追踪窗口的计数位置,动图如下:

可以看到指令追踪窗口下点击和时间线点击是一样的(本来就是一个东西,时间线是为了更直观的看到指令的执行的一种表现形式)
遗憾的是,指令执行的上限,虽然在上图的最大指令计数上限,可以更改到比64M更多的数据,比如2.2G。但是就我实验发现,不论怎么设置,都无法突破64M左右的上限。因为购买这个J-Trace,看广告(产品介绍写的是无限跟踪),所以觉得不应该有这个问题。
当时一度以为64M这个坎是J-Trace的硬件性能决定的,因为当时拆解J-Trace时候发现J-Trace内部的SDRAM是1Gb(型号IS43LD32320),这样如果J-Trace实现的跟踪机制是先将ETM的情况记录在SDRAM中,当手动Ozone点击停止(或断点)后再将执行情况上报给Ozone的话,刨除掉ETM编码指令所浪费的字节,硬件上必然是有瓶颈的。这肯定是谈不上无限追踪的。

当时内心深处有一种被深深欺骗的感觉,但是又觉得Segger不至于这样吧。所以又做了个实验,USB不太会抓包。但是J-Trace是有网口的,可以通过Wireshark来抓包试试。
于是我根据这个想法做了个实验:
1.1、J-Trace和PC连接上之后的抓包结果,此时通讯数据速率不大

1.2、点击绿色运行按钮,程序开始运行,此时通讯数据速率变大

1.3、等带一段时间后,点击暂停,Timeline窗口出现Trace的内容,拖动Timeline的窗口,追踪到的指令总数是67M左右,此时通讯数据速率也不大

所以最后我猜测,J-Trace在程序运行时就已经将跟踪数据不断的发送出来到PC了;
而不是将这些数据滚存在J-Trace的SDRAM中等调试结束后,再通过网线(或USB线)将滚存的追踪数据从SDRAM读取出来再发送。

为了解答我的疑惑,我给Segger发了个邮件,同时也问他们网站上写的关于无限跟踪是指什么。很快,当天就回复了,内容如下:(基本印证了我的猜测)

后来又仔细看了看Segger的官网对Ozone的描述中,又看到点东西。老版的J-Trace应该是内置了存储空间(应该是RAM吧),具备跟踪64M指令的能力。
不知道是不是Ozone当前还没有兼容新款的硬件。我手里面这款J-Trace硬件相对来说是最新版本(固件也已经升级到了最新的DLL了)。

跟踪上限这点I-Jet里面也有介绍:

2、指令跟踪窗口:
当程序停下来的时候(手动暂停或进入断点),当前PC指针在最底部,之前执行过的所有指令都会在该窗口下显现出来(隶属的函数语句在反汇编指令的右侧)。

上限由之前设置过的指令跟踪上限决定。和时间线窗口相同,点击后也是有着相同的交互关系。该窗口也支持指令根据函数折叠,动图如下:

3&4&6、文件窗口&反汇编窗口&跟踪(断点)窗口
因为有了跟踪,所以比起Debug来说,Trace可以展现出来语句(指令)执行的次数。之前使用Jlink的话,只能看到通过打断点,或者在已有程序里面加一个(更改程序,多多少少会改变实际程序的运行)计数器、打印等,才能得到执行次数。举一个(网上抄的)不恰当的例子,Debug本身更像是个照相机,但是Trace相对来说是个录像机了,可以帮忙我们更高的定位、排查问题。

在这两个窗口下,还可以设置Trace Start 和 Trace End。这个功能被Ozone 称作 Selective Tracing。可以只跟踪被选中的代码(可以选多组),这样Excute Count、Timeline和Instruction Trace都会只记录选中的代码。选择设置后,这些起止位置会在跟踪(断点)窗口中显示出来,同时支持勾选是否部分跟踪。

这个操作完成后,Ozone会只显示和记录选中的跟踪内容,毕竟不是无限记录(可以省着点用)。

5、代码执行状态窗口:
可以看到函数语句的执行覆盖率、反汇编后指令的执行覆盖率、以及Run Count和Fetch Count,还有就是负载率了。动图如下:

其中,如果不想看某些空闲函数的CPU负载率的话,可以去掉这个函数的负载率计算。这个在使用OS的时候可以去掉Idle任务。点开函数的折叠,也可以看到具体的指令执行情况。根据Segger回复我的邮件,这个过程应该是可以无限追踪的

感觉Fetch Count是函数中的C语句每条汇编后的指令执行次数之和,所以次数会远远大于函数本身的Run Count。不知道这个理解对不对。

通过鼠标选中Exclude All NOP可以实现排除掉空指令(NOP)的执行、统计状况

也可以选择性的Export需要的跟踪记录

生成的记录如下所示:

这篇帖子又写的很长……看来只能下篇帖子写特殊功能了

本主题由 eric2013 于 2019-12-7 10:08 添加图章 版主推荐

posted on 2020-01-21 17:24  ramlife  阅读(2714)  评论(0编辑  收藏  举报