linux驱动32:延迟执行

本文介绍了Linux内核中实现延时的各种方法,包括忙等待和非忙等待的长延迟与短延迟技术。长延迟可通过while循环结合cpu_relax()或schedule()实现,短延迟则利用ndelay(), udelay(), mdelay()等函数完成。此外,还介绍了如何使用等待队列和schedule_timeout()函数来实现超时处理。

设备驱动程序经常需要某些特定代码延迟一段时间后执行,为了让硬件能完成某些任务。

长延迟

忙等待

把执行延迟若干个时钟滴答,或对延迟的精度要求不高。

while(time_before(jiffies, j1))

{

        cpu_relax();

}

会降低系统性能。

让出处理器

在不需要CPU时主动释放CPU,通过调用schedule函数实现,<linux/sched.h>。

while(time_before(jiffies, j1))

{

        schedule();

}

超时

实现延迟的最好方法应该是让内核为我们完成相应的工作。有两种构造基于jiffies超时的路径,使用哪个则依赖于驱动程序是否在等待其它事件。

一、等待队列

驱动程序使用等待队列来等待其它一些事件,希望在特定时间段中运行,则可以使用wait_event_timeout或者wait_event_interruptible_timeout函数,这两个函数会在给定的等待队列上休眠,会在超时到期时返回。

二、不等待特定事件而延迟

schedule_timeout函数,<linux/sched.h>可以避免声明和和使用多于的等待队列头。

signed long schedule_timeout(signed long timeout);

schedule_timeout调用前要设置当前进程状态

set_current_state(TASK_INTERRUPTIBLE);

schedule_timeout(delay);

调度器会在超时且其状态变成TASK_RUNNING时才会运行这个进程。

短延迟

当设备驱动程序需要处理硬件的延迟时,这种延迟通常最多涉及到几十毫秒,这时时钟滴答不是正确的方法。

ndelay、udelay和mdelay几个内核函数可以很好地完成短延迟任务,分别延迟指定的纳秒、微秒和毫秒。

<linux/delay.h>

void ndelay(unsigned long nsecs);

void udelay(unsigned long usecs);

void mdelay(unsigned long msecs);

一般性规则,延迟上千个纳秒应使用udelay(微秒)而不是ndelay(纳秒),毫秒级延迟应使用mdelay而不是更细粒度的短延迟函数。

以上三个延迟函数都是忙等待函数,延迟过程中无法运行其它任务。

实现毫秒级或更长延迟还有其它一些函数,不涉及忙等待,<linux/delay.h>

void msleep(unsigned int millisecs); //不可中断

unsigned long msleep_interruptible(unsignd int millisecs); //可中断,进程提前唤醒时返回剩余毫秒数

void ssleep(unsigned int secs); //秒级延迟,不可中断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值