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));
}
我在 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));
}