我试图找出ARM处理器中给定代码块所消耗的时间。为此,我使用Systick计时器,这基本上是一个递减计数器。
对于正常的代码块,我可以测量函数开始和结束之间的时间差,以了解测量的时间。但是,如果代码段太长,我应该如何处理它?
根据我的逻辑,我将使用我自己设计的公式,如下所示:
time consumed=(no. of times overflow occured X start value)
+(start value - end value)附言:起始值是最大值,不是零,因为计时器是递减计数器。
我的推理是正确的,还是应该使用其他公式?
发布于 2017-11-19 14:52:30
这个公式应该是正确的,只要你考虑到在一个周期中完成的最大刻度数。
假设一个完整周期中的刻度数是MAX_TICKS,那么时间(刻度)是
nUnderflows * MAX_TICKS + start - end在C中,这可以看作是,例如
#define MAX_TICKS 32768
int nUnderflows;
// schematic function called by the system every tick
// (in a critical section)
void systick_callback() {
if ( ! internal_counter--) {
internal_counter = MAX_TICKS;
nUnderflows++;
}
}
int main() {
int start,end;
// small critical section to avoid a race condition
block_interruptions(); // CLI
nUnderflows = 0;
start = systick();
release_interruptions(); // STI
my_timed_function();
end = systick();
int time = (nUnderflows * MAX_TICKS) + start - end;
// * precedence is usually higher than of + / -, though
}假设int在您的情况下是可用的,并且不会溢出。
发布于 2017-11-20 01:04:51
如果它是一个自由运行的计数器,首先你需要确保开始-结束(或结束-开始取决于递减或递增计数)。因此,如果它是一个16位计数器(start-end)&0xFFFF将是等式的一部分。那么溢出次数0x10000将是它的一部分,如果开始
如果计时器是一个完整的32位,那么你不需要一个掩码,尽管优化器应该注意它,但作为一个习惯,你应该记住如果你不掩码,那么开始-结束将产生错误的数字,抛出所有的东西,许多翻转或没有。
发布于 2017-11-20 02:25:06
Cortex documentation表示,这是一个24位计时器,从存储在名为SYST_RVR的端口中的值开始倒计时。(我想这就是你所说的“起始值”的意思。在提出这样的问题时,最好使用记录在案的术语。)当该值从1转换为0时,会产生SYST_RVR中断,SYST_RVR复位,并重复该周期。
SYST_RVR值、中断处理程序等取决于您的处理器所在的系统的操作系统,您没有提到这一点,所以通常没有办法回答您的问题。
这种定时器体系结构通常由OS用来实现诸如线程抢占等与时间相关的功能的系统心跳。但是没有标准的模式。
显然,您知道SYST_RVR的操作系统价值。这将确定定时器超时的速率。在已校准计时器的系统中,有另一个寄存器SYST_CALIB,用于存储两次超时之间10ms所需的值。也许你的系统就是这么用的?这意味着你在0之间只有10毫秒。
你的公式很好。
“溢出的数量(实际上是下溢)”可能是最难的部分。您将如何确定这一点?似乎只有两种方法: 1)截取systick中断,并使用它来递增您自己的计数器。或者可能现有的中断处理程序已经保留了一个计数器。然后,您可以只测量该值的变化。选项2):您可以在要测量的记录计时器值profile_buffer[++bufp] = <systick value>的代码中插入分析点。你需要插入足够的时间来确保它们之间的间隔不超过10毫秒(或者不管实际的倒计时时间是多少)。然后,您可以在代码运行完成后分析缓冲区内容,以确定总运行时间。当然,添加测试代码会增加运行时间。但是systick中断处理程序可能会有相同的问题,这取决于它是如何实现的。
https://stackoverflow.com/questions/47373007
复制相似问题