【问题标题】:Timing functions on cortex-m1 gives weird resultscortex-m1 上的定时函数给出了奇怪的结果
【发布时间】:2021-05-13 23:00:12
【问题描述】:

我在 cortex-M1 上的计时功能有问题。我正在使用 Arty A7,并且正在使用 systick 来计算函数的时钟持续时间。问题是我得到的时钟没有意义,在我的 PC 上对函数进行原型设计时,我使用 time.h 中的 clock() 测量了它的时钟持续时间 - 大约需要 5000 个时钟。接下来我尝试在 cortex-M1 上测量它并使用 systick 计算时钟 - 现在结果显示数百万个时钟,我认为这没有意义。

这是我使用 systick 进行测量的方法

#define STCTRL      (*( ( uint32_t *) 0xE000E010 ))
#define STRELOAD    (*( ( uint32_t *) 0xE000E014 ))
#define STCURR      (*( ( uint32_t *) 0xE000E018 ))

int main(void)
{
    SystemInit();
    STRELOAD = 16000000;
    uint32_t start, stop;

    STCTRL = (1<<0) | (1<<2);
    wait(1000);
    start = STCURR;
    function();
    stop = STCURR;
    STCTRL = (0<<0);
    printf("%d", (int)(start-stop));
}

我不确定这些信息的相关性,但是当我使用 gcc-9 编译并使用 -O3 -Otime 进行原型设计时,在为 cortex-M1 编译时,我使用 armcc v5.06 - update 7 with flags:- c99 --gnu -c --cpu Cortex-M1 -D__EVAL --li -g -O3 -Otime

我的问题是这 2 个测量值如何以及为什么如此不同?在测量时钟周期(使用clock() 或systick)时我做错了什么吗?

【问题讨论】:

  • 我对这个处理器一无所知,但时间库实现clock() 的方式没有理由与系统计时器的直接读数相同。 CLOCKS_PER_SEC 的 time.h 值是多少?
  • 滴答计数的差异无关紧要。您已将它们缩放为实时值。对于clock(),它是 CLOCKS_PER_SEC,但对于您的 Cortex-M1 板,这实际上取决于您如何配置它。见developer.arm.com/documentation/ddi0413/d/system-control/…
  • 只需在 0x00FFFFFF 处保留/使用重新加载,然后根据它是向下计数还是向上计数,只需从结束或结束中减去开始。并记住与 0x00FFFFFF 的减法,以便它正确滚动。 delta = (x - y)&0x00FFFFFF.
  • 你如何在你的电脑上制作这个原型并且有任何相关的时间?你是说你在arty board的sim中运行它吗?没有理由期望任何两个不同的处理器远程同时处理相同的代码。同样,如果您添加或删除任何代码行,arty 上的执行时间可能会发生变化(预期)。
  • 我更喜欢在 asm 中测试代码,并将读取时钟的内容作为测试的一部分,因为像这样在 C 中执行它可以将一些时钟从一个构建添加/删除到另一个构建。

标签: c arm timing cortex-m


【解决方案1】:

首先,您的寄存器定义是错误的,因为它们遗漏了volatile

#define SysTick_TCTRL      (*((volatile uint32_t*)0xE000E010))
etc.

接下来,您需要将SysTick_LOAD 设置为(period - 1),而不是period。在您的示例中,周期为 16000001。

之后,systick 倒计时并以 24 位或您设置的限制换行,因此您需要使用模数或 if-then-subtract 来撤消此操作。 Modulo 更整洁,但差异拉入了 ARMv6M 上的库。

if (start > stop)
{
  duration = (start - stop);
}
else
{
  duration = (period - (stop - start));
}

【讨论】:

  • 首先,我同意,我需要使寄存器定义易失。其次,实际的周期数并不真正相关,我放在那里的 16000000 只是一个我知道在我的函数执行完成之前不会用完的大数字。
  • 是相关的,因为定时器的初始值是未定义的。它可以立即包装。
  • 在我的示例中未定义?为什么我要关心我的经期是 16000000 还是 16000001?为什么它会换行,最大值不应该是 2^24 - 1?
  • 假设计数器从值 3 开始(它可以是任何东西,这就是 undefined 的意思)。如果您的函数需要 4 个或更多周期,那么它将换行并且您会得到一个非常大的数字,正如您所发现的那样。
  • 当它从重载寄存器中获取值时,它不会从重载寄存器中的值开始。
猜你喜欢
  • 1970-01-01
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多