cortex-m1 上的计时函数给出了奇怪的结果

Timing functions on cortex-m1 gives weird results

我在 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

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

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

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

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

在那之后,systick 倒计时并在 24 位或您设置的限制处回绕,因此您需要使用模数或仅如果-然后-减法来撤消此操作。 Modulo 更简洁,但在 ARMv6M 上的库中存在差异。

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