Jef*_*eff 9 linux embedded linux-kernel
我们有一个使用3.2内核的ARM9 - 一切似乎都运行正常.最近我被要求添加一些代码,以便在启动时在某些GPIO线上添加50ms脉冲.脉冲代码很好; 正如预期的那样,我可以看到线条向下和向上.什么不能按我预期的方式工作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
}
Run Code Online (Sandbox Code Playgroud)
我不喜欢它,但它工作正常.代码中有一些奇怪的常量和指令udelay.有人可以告诉我这应该如何工作?在所有时钟初始化之后调用此代码,因此其他所有内容似乎都可以.
根据 Linus 在这个帖子中的说法:
如果有1%左右的折扣,那就没问题了。如果有人选择的延迟值对延迟中的小错误非常敏感,以至于他们注意到 - 或者甚至注意到 5% 之类的东西 - 那么他们选择的延迟太短了。
udelay() 从来就不是某种精密仪器。特别是当 CPU 以不同的频率运行时,我们历史上曾经历过一些相当剧烈的波动。传尽管)。
所以从历史上看,我们已经看到 udelay()确实有折扣(即 50% 折扣等),我不会担心 1% 范围内的事情。
莱纳斯
所以它不会是完美的。它将会关闭。多少取决于很多因素。不要使用for循环,而是考虑使用mdelay。可能会更准确一些。来自O'Reilly Linux 设备驱动程序一书:
udelay调用应该仅在短时间间隔时调用,因为 udelay 的精度仅为
loops_per_second8 位,并且在计算长延迟时会累积明显的错误。尽管最大允许延迟接近一秒(因为较长延迟的计算会溢出),但建议的udelay最大值为 1000 微秒(一毫秒)。函数mdelay在延迟必须长于一毫秒的情况下有所帮助。同样重要的是要记住udelay是一个忙等待函数(因此mdelay也是);在此时间内无法运行其他任务。因此,您必须非常小心,尤其是使用mdelay时,并避免使用它,除非没有其他方法可以实现您的目标。
目前,对长于几微秒和短于计时器滴答的延迟的支持效率非常低。这通常不是问题,因为延迟需要足够长才能被人类或硬件注意到。对于与人类相关的时间间隔来说,百分之一秒是合适的精度,而对于硬件活动来说,一毫秒是足够长的延迟。
具体来说,“ udelay的建议最大值为 1000 微秒(一毫秒) ”这一行对我来说很突出,因为您声明 2000 是最大值。从本文档中关于插入延迟的内容:
mdelay 是 udelay 的宏包装器,用于在将大参数传递给 udelay 时考虑可能的溢出
因此,您可能会遇到溢出错误。尽管我通常不会认为 2000 年是一个“大争论”。
但是,如果您需要真正的计时准确性,则需要像您一样处理偏移量,自行推出或使用不同的内核。有关如何使用汇编程序或使用硬实时内核来滚动自己的延迟函数的信息,请参阅这篇有关高分辨率计时的文章。
| 归档时间: |
|
| 查看次数: |
1468 次 |
| 最近记录: |