• 内核延时


    查阅内核代码时经常看到和应用到延时,本文用于归纳延时相关内容。

    一. 短延时

    void ndelay(unsigned long nsecs);
    void udelay(unsigned long usecs);
    void mdelay(unsigned long msecs);

    短延时的本质是忙等。

    毫秒时延已经很大了,在内核中,最好不要直接使用mdelay(),无谓消耗cpu资源,对于毫秒级以上时延,内核提供如下函数:

    void msleep(unsigned int msecs);
    unsigned long msleep_interruptible(unsigned int msecs);
    void ssleep(unsigned long secs);

    msleep(),ssleep()不能被打断,msleep_interruptible()则可以被打断。

    二. 长延时

    内核中进行延时的一个很直观的方法是比较当前的jiffies和目标jiffies,直到未来的jiffies达到目标jiffies。

    unsigned long delay = jiffies + 100;
    while(time_before(jiffies, delay));
    
    unsigned long delay = jiffies + 2*Hz;
    while(time_before(jiffies, delay));

    延时100jiffies,然后再延时2s。

    #define time_after(a,b)     
        (typecheck(unsigned long, a) && 
         typecheck(unsigned long, b) && 
         ((long)((b) - (a)) < 0))
    #define time_before(a,b)    time_after(b,a)

    不推荐(禁止)直接jiffies值比较,因为jiffies有溢出,必须考虑wrap,推荐使用time_after()和time_before()。

    三. 睡眠延时

    linux/sched.h
    extern signed long schedule_timeout(signed long timeout);
    extern signed long schedule_timeout_interruptible(signed long timeout);
    extern signed long schedule_timeout_killable(signed long timeout);
    extern signed long schedule_timeout_uninterruptible(signed long timeout);

    schedule_timeout()可以使当前任务睡眠指定的jiffies之后重新调度执行,msleep()和msleep_interruptible()本质就是依靠schedule_timeout_uninterruptible()和schedule_timeout_interruptible()实现的。

    extern void sleep_on(wait_queue_head_t *q);
    extern long sleep_on_timeout(wait_queue_head_t *q, signed long timeout);
    extern void interruptible_sleep_on(wait_queue_head_t *q);
    extern long interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long timeout);

    将当前进程添加到等待队列中,从而在等待队列上睡眠。当超时发生时,进程被唤醒。

    参考:

    1. 设备驱动开发详解  宋宝华

  • 相关阅读:
    WCF双工通讯以及客户端间的间接通讯
    认识IoC
    学习“迷你ASP.NET MVC框架”后的小结
    MVP的PV模式与SC模式
    Android学习笔记(九) 视图的应用布局效果
    C# 动态编译
    C#中协变与抗变(逆变)
    线程池ThreadPool的初探
    关于异步的初步认识
    仿Office的程序载入窗体
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/8596118.html
Copyright © 2020-2023  润新知