我正在从事一个嵌入式项目,该项目运行在基于ARM Cortex M3的微控制器上。我们的供应商提供的一些代码使用一个延迟函数来设置内置的硬件定时器,然后旋转直到计时器过期。通常,这是用来等待1到几百微秒之间。这些延迟几乎是因为它们在等待某个寄存器、芯片或总线来完成操作,并且需要等待(至少)给定的微秒数。硬件定时器似乎也花费了至少6微秒的开销来设置。
在多线程环境中,这是一个问题,因为有N个线程,但只有一个硬件定时器。我可以禁用中断,而计时器是用来防止上下文切换,因此,竞争条件,但这似乎有点丑陋。我正在考虑用使用ARM CPU周期计数器(CCNT)的功能取代使用硬件定时器的功能。是否有我错过的陷阱或其他选择?显然,循环计数器功能要求将其调到适当的CPU频率,这对于我们的系统来说是永远不会改变的,但我认为可以使用硬件定时器在引导时以编程方式检测到。
发布于 2016-11-15 00:22:29
在启动时设置计时器一次,并让计数器连续运行。当您想要启动延迟时,读取计数器值并记住这个开始值。然后在延迟循环中再次读取计数器值并循环,直到计数器值减去开始值大于或等于所请求的延迟滴答。(如果你做了正确的减法,那么滚转就会洗掉,你不需要特殊的处理来检查它们。)
发布于 2016-11-15 00:03:55
您可以对计时器进行多路复用,这样您就可以得到每个线程需要何时触发的表,以及一个函数指针/向量以供执行。当计时器中断发生时,启动该线程的中断,然后将计时器设置为列表中的下一个,减去经过的时间。这就是我所看到的许多*nix操作系统在内核代码中所做的事情,因此应该有一些代码可以从中提取出来。
一个更大的问题是,您正在旋转锁定线程等待计时器。除了CPU的使用之外,根据您拥有的操作系统(或者如果您有操作系统),您可以很容易地引入线程反转问题,甚至可以完全锁定。最好使用线程原语,这样任何操作系统都可以真正睡眠线程,并在需要时唤醒它们。
https://stackoverflow.com/questions/40599676
复制相似问题