补偿ARM中断的延迟?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了补偿ARM中断的延迟?相关的知识,希望对你有一定的参考价值。

我正在研究STM32F4 CPU上的一个项目,产生信号。

我在STM32上有CPU时钟(没有预分频器)的通用定时器,在溢出时触发中断,然后用GPIO产生周期信号。

我需要在非常精确的时间触发GPIO(基本上低至一个CPU周期精度)。通过设置优先级等,我已设法将此抖动减少到+ -5个周期,但这种抖动存在,具体取决于CPU的工作情况。

我需要补偿这几个周期的抖动。只要我在精确的时间切换GPIO,添加几个周期的延迟就不是问题。

我的想法是读取计数器的当前值,并有一个FIXED_NUMBER-CURRENT_VALUE时间的活动循环,确保我将在精确的时间退出循环。

然而,在C中做一个简单的循环 - 一个FOR循环,或一个while(counter-> value <TARGET)不起作用,因为它ADDS抖动而不是减少它。

我做错了什么/天真吗?我应该在集会中这样做吗?怎么会与C不同(我检查了用GCC反汇编来检查循环没有被优化掉,也不是我打了内存?)

(我确保空的,非优化的但不打击内存循环体)

编辑:在AVR上看到这个例子(我知道的更稳定)通过示例查看http://lucidscience.com/pro-vga%20video%20generator-7.aspx(搜索“jitter”)

edit2:我在汇编中尝试了一个简单的循环,例如(r0是我的计数器,等待的循环次数,在寄存器中)

loop : SUBS r0,#1 ; tried with 2 also
       BGE loop

而且,如果没有它,抖动会更好。

总结起来,我已经知道我应该拖延多少。我只需要一种方法让代码分支在一个案例中可靠地消耗N个循环而在另一个案例中可以消耗M.不幸的是,单独的分支似乎不起作用,因为管道填充似乎不需要可靠的循环次数,并且条件表达式也不会因为它们总是采用相同数量的循环(有时无效)。

从RAM而不是闪存运行会提高一致性吗? (NB stm32f4有一个flash预取..)

答案

(具有讽刺意味的是,关于减少响应延迟的问题需要三年才能得到答案。)

+/- 5个周期听起来非常熟悉。在中断调度期间,您可能会遇到等待状态访问Flash控制器。

在中断调度期间,CPU需要做三件事:

  1. 加载矢量表条目。
  2. 加载中断例程的初始代码。
  3. 将一些寄存器写入堆栈。

如果向量表和/或中断例程代码在Flash中,则项目1和2中的提取将转到Flash。当以最高额定速度(高达168MHz)运行CPU时,访问Flash需要五种等待状态。这意味着对Flash的访问可能需要1或6个周期,具体取决于所请求的数据是否在Flash缓存中。如果你看到正好有0或5个周期的延迟,这可能是罪魁祸首。通过将ISR代码和向量表移动到RAM中,可以轻松解决此问题。您还可以通过禁用Flash缓存来“修复”它,这将导致Flash访问速度可预测地很慢。

有一个潜行因素可能也在咬你:如果被中断的代码也使用Flash,中断调度可能必须等待其Flash访问完成,假设它错过了缓存。您可以通过将中断的代码移动到RAM中来解决这个问题,但此时它开始听起来像Flash中没有任何东西。有一种方法可以将代码保存在我下面提到的Flash中。

最后,还有一个比较狡猾的事情:如果你在延迟敏感的中断之前有其他可能发生的中断,那么由于tail chaining,该中断有可能达到-5个周期的延迟。

我对上面列出的第二个问题的解决方案有点奇怪:当发生中断时,确保处理器处于空闲状态,即不接受另一个中断或从Flash获取。我这样做的方法是配置一个较低优先级的中断,在我的延迟敏感中断之前到达(使用定时器); ISR只执行等待中断指令wfi

这些都是可克服的问题。我不同意你需要放弃C并用汇编语言写的评论者;我的m4vgalib系统几乎不包含汇编语言,抖动非常低。

我在one section of an article on my blog中更详细地讨论了这些相同的问题和我的解决方案。

另一答案

Cliff是正确的,没有办法在具有中断,闪存等待状态和流水线的CPU核心上获得单个CPU周期精度。 AFAIK,有点奇怪的Parallax“Propeller”是少数几个能够保证周期时间一致性的“高性能”MCU核心之一,因为它不支持中断(而是支持“旋转”接入集线器中的8个核心)。

以上是关于补偿ARM中断的延迟?的主要内容,如果未能解决你的问题,请参考以下文章

Linux kernel的中断子系统之:ARM中断处理过程

使用 ARM GIC(全局中断控制器)禁用中断

pvz2网络延迟补偿

STM32的中断处理流程是怎样的?与ARM7 ARM9相同吗?

TQ2440开发板学习纪实--- 基于中断的UART串口接收

ARM7LPC2138做串口中断实验的时候,发送中断一直进不去。接收中断一切正常,代码改了n遍了,求解释啊