出现“丢失事件”?看Tracealyzer流模式如何调优

Tracealyzer基础概念和使用请点击阅读

Tracealyzer 针对FreeRTOS和 Micrium µC/OS的记录器库可以配置成通过可用的通信接口(例如串口)来传输跟踪数据。用户通过提供一个自定义的“流端口”(stream port)来实现,需要在trcStreamingPort.h中实现这些I/O功能,供记录器库使用。流端口的示例在记录器库的“streamport”目录中提供。

流端口需要有足够的数据吞吐量,以保证传输的可靠。你在使用自己定义的流端口实现流跟踪时,如果Tracealyzer提示了“丢失事件”,那么你可以参照以下几种方法,来提升流端口的性能。

潜在的问题可以分成3类:

1、跟踪记录时没有足够的临时缓存空间;

2、系统产生的事件数据超过了流端口的处理能力;

3、传输时存在随机错误,比如波特率设置的太高。

缓存写满

我们先从第一类问题开始。多数情况下,流端口在记录器中使用了位于内部RAM的缓存,事件先存储在缓存,再由TzCtrl任务(Tracealyzer创建的专有任务,用于传输流数据)周期性的更新到流端口。这么做有两个目的:平滑数据输出速率和避免在RTOS内核中调用流端口函数。

内部的缓存被分成了几个部分,称之为页。记录器库的TzCtrl任务会定期的传输所有已经写满的页,但记录器正在写的页除外。所以,如果只使用了2个页的最小设置,TzCtrl任务每次运行只能传输一个页的内容。

内部缓存可以在trcStreamingConfig.h中进行配置:

TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT:缓存页的数量

TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE:每页的大小,单位是字节

TRC_CFG_CTRL_TASK_DELAY:TzCtrl任务执行的间隔

TRC_CFG_CTRL_TASK_PRIORITY:TzCtrl任务的优先级

默认的设置可能并不适合你的系统,因此调整这些设置可以明显提升吞吐量。

如果所有的页都已写满,新产生的事件将被会丢弃,直到有一个页传输完成再次可用。为了避免这种情况,必须确保任何两次TzCtrl运行之间产生的跟踪数据量不超过 (PAGE_COUNT-1)*PAGE_SIZE。注意,这里-1是因为当前活动的页不能传输。

举个例子:假设分配了两个缓存页面,每个页大小是2500字节,并计划TzCtrl任务每10毫秒运行一次。在这种情况下,记录器每10毫秒最多可以处理2500字节的跟踪数据,也就是每秒钟250kbytes。250kbytes /s通常是足够的吞吐量,但在这种配置中,系统将无法处理任何10毫秒间隔内超过2500字节的突发。这是因为这时只有1/2跟踪缓冲区页可以用于传输。因此,建议使用5或10个页面,哪怕使用更小的页,以便能够以更有效的方式处理密集的数据突发。例如,对于每个页面500字节的10个页面,记录器可以每10毫秒处理4500字节,因为9/10的缓冲区页面可以用于传输。

可以通过更频繁地运行TzCtrl任务来更有效地使用流接口。通过这种方式,可以减少从缓冲区页满到TzCtrl开始传输的平均延迟。频率由TRC_CFG_CTRL_TASK_DELAY设置控制,降低该设置意味着TzCtrl将更频繁地检查缓冲区以发送数据。如果没有缓冲区页被填满并准备传输,TzCtrl任务将很快返回睡眠状态,只增加很少的开销。

如果这两种优化都不能充分提高吞吐量,请尝试通过增加PAGE_SIZE和/或PAGE_COUNT来增加总缓冲区大小。即使你不想分配较大的缓冲区空间,也可以先尝试较大的值,看看问题是否会消失。一旦配置有效,就可以通过过滤来减少数据速率,然后相应地减少缓冲区大小。

注意,记录器默认使用内部缓冲,但是如果你有一个非常快的流接口,你可以配置你的流端口来禁用内部缓冲,事件数据直接写入流接口。这在trcStreamingPort.h中包含以下行来实现:

#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0

过滤掉不重要的事件

如果按照第一类问题中进行了配置仍然遇到问题,这可能是超过了流接口的最大容量。要进一步确认,请看“Live Stream”窗口。

在“Statistics”面板中查看以下指标:

Received -接收到的字节总数(R)

Total Events—接收到的事件总数(E)

Missed Events—丢失事件的总数(M)

Duration -记录会话的长度,以秒为单位(T)

要计算流接口每秒所需的字节容量,我们需要计算每个事件的平均字节数(R/E)。我们不知道丢失事件的大小(只知道它们的数量),但我们可以假设它们的平均大小与接收到的事件相似。然后,通过将接收到的事件数量和错过的事件数量相加,计算出跟踪事件的总数。它们与平均事件大小相乘,然后除以秒数。

(E+M) * (R/E) / T

示例:在254 KB (R)中记录了14 342个事件(E),在80秒(T)中丢失了1895个事件(D)。

(14 342 + 1 895) * (254000/14 342) / 80 = 3 594 bytes/s

这个示例系统平均生成小于4kb /s的数据,因此在这种情况下,数据丢失可能与流接口容量无关。但是,如果平均数据速率高于流媒体接口所能处理的数据速率,则需要以某种方式降低数据速率。这可以通过在记录器中较不重要的事件进入内部缓冲区之前过滤来实现。因为可能有一些频繁产生,但不是你很关注的事件。

一种方法是在trcConfig.h中更改静态(编译时)过滤,例如,通过禁用

TRC_CFG_INCLUDE_READY_EVENTS和/或TRC_CFG_INCLUDE_OSTICK_EVENTS。

一种更复杂的方法是使用动态运行时过滤,这允许使用记录器API函数vTraceSetFilterMask和vTraceSetFilterGroup排除特定的任务或对象。在traceanalyzer用户手册的记录器API部分进行了介绍。

可能是电缆的问题

可能会遇到随机的传输错误,例如由使用了有问题的电缆或过高的波特率。试着建立一个简单的示例,只在主函数中循环,让其在流接口上生成稳定的数据流。找一个合适的工具来接收数据,比如终端程序,将数据保存到一个文件中,并检查数据中的任何错误。如果您发送一个重复的字节模式(如固定的32位字),则很容易发现这一问题。

最后,是时候把示波器连接起来看看信号了。观察脉冲是否真的是方波,如果不是,也许接口的速率已经达到了极限。尝试降低波特率,看看是否可以实现更稳定的传输。低吞吐量比随机数据丢失更容易处理,因为前者可以通过降低数据速率的过滤来补偿。如果所有这些方法都失败了,考虑更换到另一个速率更高的接口,或者干脆使用更好的Tracealyzer支持的调试器。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有关如何以操作系统感知的方式调试在Avnet MiniZed板上运行的Embedded FreeRTOS应用程序的指南。 介绍在操作系统之上编写嵌入式软件应用程序时,通常很难检测某些时序问题或解释某些奇怪的行为。到底出了什么问题?另一件事是,在研究嵌入式操作系统时,以可视方式呈现系统的运行行为会很有用。了解任务优先级,调度程序设置,队列管理,... 我发现Percepio Tracealyzer是解决这类问题的理想工具。Tracealyzer可以通过两种方式工作:在快照模式下(这是本教程的内容)或在模式下。 对于本指南,您需要一个Avnet MiniZed开发板(基于Xilinx Zynq),Xilinx vivado工具和Percepio tracealyzer 4(其网站上的评估版)。 让我们开始开发本指南的硬件部分(FPGA设计)。如果您不熟悉FPGA设计,则可以打开我的硬件设计。否则,从下面开始构建基于ZYNQ7的设计: 基于zynq7的设计 在程序框图上放置以下组件: ZYNQ7 P rocessing 小号ystem 具有2个通道的AXI GPIO 连接到pl_led_g 和pl_led_r 1个通道的AXI GPIO 连接到pl_sw_1bit 您可以对ZYNQ7处理系统使用自动配置(使用预设),但是随后必须手动添加M_AXI_GP0_ACLK 端口以连接AXI从设备外围设备。 使用“自动连接”功能将AXI_GPIO模块连接到AXI总线。 不要忘记在“模块设计”的顶部添加HDL包装器。生成比特,并将您的硬件设计导出到Vivado SDK(包括比特)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值