当一个设备驱动需要处理它的硬件的反应时间,涉及到的延时常常是最多几个毫秒. 在这 个情况下,依靠时钟嘀哒显然不对路.
The kernel functions ndelay,udelay,and mdelay serve well for short delays,delaying execution for the specifIEd number of nanoseconds,microseconds,or milliseconds respectively.* Their prototypes are: * The u in udelay represents the Greek letter mu and stands for micro.
内核函数 ndelay,以及 mdelay 对于短延时好用,分别延后执行指定的纳秒数,微秒数或者毫秒数. [27]27它们的原型是:
#include <linux/delay.h>
voID ndelay(unsigned long nsecs); voID udelay(unsigned long usecs); voID mdelay(unsigned long msecs);
这些函数的实际实现在 <asm/delay.h>,是体系特定的,并且有时建立在一个外部函数上. 每个体系都实现 udelay,但是其他的函数可能或者不可能定义; 如果它们没有定义,
<linux/delay.h> 提供一个缺省的基于 udelay 的版本. 在所有的情况中,获得的延时至
udelay 中的 u 表示希腊字母 mu 并且代表 micro.
少是要求的值,但可能更多; 实际上,当前没有平台获得了纳秒的精度,尽管有几个提供 了次微秒的精度. 延时多于要求的值通常不是问题,因为驱动中的短延时常常需要等待硬 件,并且这个要求是等待至少一个给定的时间流失.
udelay 的实现( 可能 ndelay 也是) 使用一个软件循环基于在启动时计算的处理器速度,使用整数变量 loos_per_jiffy. 如果你想看看实际的代码,但是,小心 x86 实现是相当 复杂的一个因为它使用的不同的时间源,基于什么 cpu 类型在运行代码.
为避免在循环计算中整数溢出,udelay 和 ndelay 强加一个上限给传递给它们的值. 如 果你的模块无法加载和显示一个未解决的符号,bad_udelay,这意味着你使用太大的参 数调用 udleay. 注意,编译时检查只对常量进行并且不是所有的平台实现它. 作 为一个通用的规则,如果你试图延时几千纳秒,你应当使用 udelay 而不是 ndelay; 类 似地,毫秒规模的延时应当使用 mdelay 完成而不是一个更细粒度的函数.
重要的是记住这 3 个延时函数是忙等待; 其他任务在时间流失时不能运行. 因此,它们 重复,尽管在一个不同的规模上,jitbusy 的做法. 因此,这些函数应当只用在没有实用 的替代时.
有另一个方法获得毫秒(和更长)延时而不用涉及到忙等待. 文件 <linux/delay.h> 声明 这些函数:
voID msleep(unsigned int millisecs);
unsigned long msleep_interruptible(unsigned int millisecs); voID ssleep(unsigned int seconds)
前 2 个函数使调用进程进入睡眠给定的毫秒数. 一个对 msleep 的调用是不可中断的; 你能确保进程睡眠至少给定的毫秒数. 如果你的驱动位于一个等待队列并且你想唤醒来打 断睡眠,使用 msleep_interruptible. 从 msleep_interruptible 的返回值正常地是 0; 如果,这个进程被提早唤醒,返回值是在初始请求睡眠周期中剩余的毫秒数. 对 ssleep 的调用使进程进入一个不可中断的睡眠给定的秒数.
通常,如果你能够容忍比请求的更长的延时,你应当使用 schedule_timeout,msleep,或者 ssleep.
总结以上是内存溢出为你收集整理的linux 短延时全部内容,希望文章能够帮你解决linux 短延时所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)