ARM嵌入式延迟硬件定时器vs CPU周期计数器

时间:2016-11-14 23:37:54

标签: arm embedded

我正在研究一个在基于ARM Cortex M3的微控制器上运行的嵌入式项目。我们的供应商提供的一些代码使用延迟功能来设置内置硬件定时器,然后旋转直到定时器到期。通常,这用于等待1到几百微秒。这些延迟几乎是因为它们正在等待一些寄存器,芯片或总线完成一个动作,需要等待至少给定的微秒数。硬件计时器的设置开销似乎也至少需要6微秒。

在多线程环境中,这是一个问题,因为有N个线程但只有1个硬件计时器。我可以在使用定时器时禁用中断,以防止上下文切换,从而防止竞争条件但看起来有点难看。我正在考虑将使用硬件定时器的功能替换为使用ARM CPU循环计数器(CCNT)的功能。是否存在我缺少的陷阱或其他替代方案?显然,循环计数器功能需要调整到适当的CPU频率,这对于我们的系统永远不会改变,但我想可以使用硬件定时器以编程方式检测到。

2 个答案:

答案 0 :(得分:6)

启动时设置计时器一次,让计数器连续运行。如果要开始延迟,请读取计数器值并记住此起始值。然后在延迟循环中再次读取计数器值并循环,直到计数器值减去起始值大于或等于所请求的延迟滴答。 (如果你正确地进行减法,那么翻转将会被淘汰,你不需要特殊的处理来检查它们。)

答案 1 :(得分:2)

你可以多路复用你的计时器,这样你就可以得到每个线程想要触发的表和一个用于执行的函数指针/向量。发生定时器中断时,触发该线程的中断,然后将定时器设置为列表中的下一个,减去经过的时间。这就是我看到许多* nix操作系统在其内核代码中所做的事情,因此应该有代码来作为示例。

更大的问题是你正在旋转锁定等待计时器的线程。除了CPU使用率,并且取决于您拥有的操作系​​统(或者如果您有操作系统),您可以轻松地引入线程反转问题,甚至完全锁定。最好使用线程原语,这样任何操作系统都可以实际睡眠你的线程并在需要时唤醒它们。