Linux 如何证明uuudelay()在我的ARM嵌入式系统上正常工作?
我们有一个使用3.2内核的ARM9,看起来一切正常。最近,我被要求添加一些代码,以便在启动时在一些GPIO线路上添加50ms脉冲。脉冲编码良好;我可以看到队伍像预期的那样上下起伏。没有按我预期的方式工作的是Linux 如何证明uuudelay()在我的ARM嵌入式系统上正常工作?,linux,linux-kernel,embedded,Linux,Linux Kernel,Embedded,我们有一个使用3.2内核的ARM9,看起来一切正常。最近,我被要求添加一些代码,以便在启动时在一些GPIO线路上添加50ms脉冲。脉冲编码良好;我可以看到队伍像预期的那样上下起伏。没有按我预期的方式工作的是udelay()函数。阅读文档让我觉得单位是微秒,但在逻辑分析仪中测量的时间太短了。所以我最后添加了这段代码以获得50ms // wait 50ms to be sure PCIE reset takes for (i=0;i<6100;i++) // measured on logic
udelay()
函数。阅读文档让我觉得单位是微秒,但在逻辑分析仪中测量的时间太短了。所以我最后添加了这段代码以获得50ms
// wait 50ms to be sure PCIE reset takes
for (i=0;i<6100;i++) // measured on logic analyzer - seems wrong to me!!
{
__udelay(2000); // 2000 is max
}
//等待50毫秒以确保PCIE重置需要
对于(i=0;i根据Linus在:
如果是1%左右的折扣,就可以了。如果有人选择了延迟值
这对延迟中的小错误非常敏感,以至于他们注意到
那——或者甚至注意到5%之类的东西——那么他们也选择了
没有耽搁
udelay()从来没有真正意义上的精确性
仪器,尤其是CPU以不同频率运行,
历史上,我们曾经历过一些相当剧烈的波动。传统的
繁忙循环最终不仅受到中断的影响,还受到
比如缓存对齐(我们曾经将其内联),然后
基于TSC的方案显然取决于TSC的稳定性(他们认为
有一段时间没有
所以从历史上看,我们看到udelay()真的很差(即50%的折扣)
等),我不会担心1%范围内的事情
莱纳斯
<> p>所以它不会是完美的。它将被关闭。取决于很多因素,而不是使用<代码> 循环,而是考虑使用<代码> Mdiels。它可能更准确一些。
udelay调用只应在短时间内调用,因为
每秒循环次数的精度仅为8位,非常明显
计算长延迟时会累积错误。即使
最大允许延迟接近1秒(自计算
对于较长的延迟,建议的udelay最大值为
1000微秒(一毫秒)。函数mdelay有助于
延迟必须超过一毫秒的情况
记住udelay是一个繁忙的等待函数,这一点也很重要
(因此,mdelay也是如此);在此期间无法运行其他任务
因此,你必须非常小心,尤其是对mdelay,以及
避免使用它,除非没有其他方法来实现你的目标
目前,支持超过几微秒的延迟和
短于计时器的滴答声是非常低效的。这通常不是一个问题
问题,因为延迟需要足够长的时间才能引起客户的注意
人或硬件。百分之一秒是合适的
人类相关时间间隔的精度,而一毫秒是
足够长的硬件活动延迟
具体来说,行“udelay的建议最大值为1000微秒(一毫秒)”向我突出,因为您声明2000是插入延迟的最大值:
mdelay是udelay的宏包装器,用于解释可能的
将大参数传递给udelay时溢出
<> p>所以你可能遇到溢出错误。虽然我通常不认为2000是一个“大参数”。
但是,如果您需要真正精确的计时,您需要像处理偏移一样处理偏移,滚动您自己的或使用不同的内核。有关如何使用汇编程序或硬实时内核滚动您自己的延迟函数的信息,请参阅上的这篇文章
另请参阅:在现代内核上hrtimer\u nanosleep应该足够便携。@cdleonardnanosleep
可能会根据调度程序模式和延迟长度在繁忙循环中使用udelay
。请参阅我在.@embedded.kyle上提供的链接-非常感谢您的回答,但我不满意。mdelay只是在for循环中调用udelay,所以这没有帮助。udelay的关闭量远没有接近1%或50%——我本来以为如果一切正常(每个循环2毫秒)循环计数器为25。如果关闭50%——我的循环将为50。但是6100?那太远了,我很烦恼。再次感谢,但我仍然在探索:)@Jeff可能是or每秒循环次数
内核变量已关闭。看看它们是否合理。答案不错,这就解释了我目前遇到的问题。非常感谢。