在众多实时应用领域,例如电机控制、发动机控制以及无线通信等时间敏感的应用中,CPU对代码的执行时间可能只占据不到5%的时间。一般来说,这些嵌入式系统会使用C语言进行编写,开发人员可能会使用汇编语言来优化代码,以满足时间期限的要求。测量部分代码的实际执行时间可以帮助我们找到代码中的时间关键点。
本文将介绍如何轻松地测量和显示基于Cortex-M MCU的代码片段的执行时间。
测量执行时间的方法
有许多方法可以测量代码的执行时间。嵌入式工程师经常使用数字输出和示波器。我们可以在要监测的代码执行之前,将输出设置为高电平,代码执行结束后将输出设置为低电平。当然,在进行这些操作之前需要进行大量的设置工作,例如找到易于探测的输出引脚、将端口配置为输出模式、编写代码、编译等等。获取到信号后,你可能还需要一段时间来监测信号,以获取最小和最大的运行时间。
另一种测量执行时间的方法是使用带有跟踪功能的调试工具。你只需要运行代码、查看跟踪信息、手动计算增量时间并将CPU周期转换为微秒。不过,不幸的是,跟踪功能只提供单次执行的情况,你可能需要进一步查看跟踪信息才能找到最坏情况的执行时间,这可能是一个繁琐的过程。
Cortex-M周期计数器
Cortex-M的处理器上的 CoreSight调试端口包含一个32位自由运行计数器,用于CPU时钟周期计数。计数器是调试监视和跟踪 (DWT) 模块的一部分,可轻松用于测量代码的执行时间。启用和初始化该功能所需的代码如下:
使用DWT周期计数器测量代码执行时间
我们可以通过读取代码段前后的循环计数器的值来测量并计算代码片段的执行时间,如下所示。
无符号数delta表示被测代码的实际执行时间(以CPU时钟周期为单位)。
在代码执行期间可能会发生中断,因此每次执行此序列获得时间值可能并不相同,我们也可以在测量期间禁用中断以移除中断的影响。但建议在测量中允许中断,因为它们会影响代码的时间期限。
如果被测量的代码包含条件语句、循环或任何可能导致变化的东西,那么获得的值可能不代表最坏情况下的执行时间。要解决此问题,可以简单地添加一个峰值检测,如下所示。在进行任何测量之前,需要声明 max 并将其初始化为最小值(即 0)。
同样,如果需要了解最短执行时间,min只需在测量之前声明并初始化为最大计数值(即 0xFFFFFFFF)。代码如下:
执行时间还取决于 CPU是否配备cache,某些Cortex-M4和Cortex-M7处理器集成了Cache。如果 系统使用了指令或数据cache,则同一代码段的多次测量结果可能会不一致。你可以考虑禁用cache来衡量最坏的情况。
大多数调试器能够实时显示这些变量值。我们可以使用Global声明显示的变量以保留其值并允许实时监控。这些值代表CPU时钟周期,但大多数调试器无法为显示目的缩放变量。假设CPU时钟速度为16 MHz,显示70.19微秒比显示1123个周期要方便得多。实际上有一种更好的方式来显示实时变量,使用μC/Probe实时监控工具,它还提供了缩放能力,以易读的形式查看变量值。
使用μC/Probe显示测量值
在应用中添加测量,监控四个代码片段的执行时间,并通过μC/Probe显示测量结果。
下图显示了使用 IAR的LiveWatch(左)和 μC/Probe 的Tree View控件(右)的原始测量值。elapsed_time_tbl[] 是一个数组,用于存储不同代码片段的测量值。
你还可以将min/max/current值分配给gauge和numeric indicator控件,如下图所示。这里的值以微秒为单位显示,示例中CPU以80 MHz 运行,使用了0.0125的缩放因子。仅显示最长执行时间。
uC/Probe还可以与Microsoft的Excel连接,从而在电子表格中显示实时值,如下图所示。
总结
作为嵌入式开发人员,我们有许多工具可以用来测试和验证我们的设计。μC/Probe提供了许多功能,允许用户使用gauge、meter、numeric indictor、Excel或graph/plots来监控应用程序中的变量。基于Cortex-M处理器的DWT 周期计数器功能和μC/Probe,我们可以轻松实现Cortex-M MCU应用的设计验证工作。
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !