• linux驱动32:延迟执行


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

    长延迟

    忙等待

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

    while(time_before(jiffies, j1))

    {

            cpu_relax();

    }

    会降低系统性能。

    让出处理器

    在不需要CPU时主动释放CPU,通过调用schedule函数实现,

    while(time_before(jiffies, j1))

    {

            schedule();

    }

    超时

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

    一、等待队列

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

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

    schedule_timeout函数,可以避免声明和和使用多于的等待队列头。

    signed long schedule_timeout(signed long timeout);

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

    set_current_state(TASK_INTERRUPTIBLE);

    schedule_timeout(delay);

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

    短延迟

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

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

    void ndelay(unsigned long nsecs);

    void udelay(unsigned long usecs);

    void mdelay(unsigned long msecs);

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

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

    实现毫秒级或更长延迟还有其它一些函数,不涉及忙等待,

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

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

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

  • 相关阅读:
    【SpringMVC源码三千问】Spring官方@RequestMapping路径匹配用法大全
    Iceberg Flink FLIP-27实现
    武汉链(基于ETH)BSN官方DDC链上数据解析
    【计算机毕业设计】32.学生宿舍管理系统源码
    pip install 下载速度太慢
    JavaScript 讲述数据结构 - 栈结构
    ProNas-振动噪声工程界新一代的前沿技术
    33 WEB漏洞-逻辑越权之水平垂直越权全解
    JVM 虚拟机 ----> Java 类加载机制
    WPF 控件分辨率自适应问题
  • 原文地址:https://blog.csdn.net/dongyoubin/article/details/126554313