嵌入式LINUX驱动学习之7中断相关(五)延迟处理函数


linux系统中,任务的延迟分为两种:
一种:是忙延迟,主要用在中断相关的函数中,实现的方式为原地空转,类似于while(n),这种方式不会释放资源,而是一直处理等待状态;
另一种:是休眠延迟,这种方式主要用于进程,一但使用休眠延迟,进程将释放资源,待延迟时间结束后重新获取资源,继续运行

一、忙延迟方法头文件及说明(主要用于中断处理函数内)

//源码位置:arch/arm/include/asm/delay.h
//udelay(n)函数功能:延迟n微秒后继续向下执行
#define udelay(n)                                                       \
        (__builtin_constant_p(n) ?                                      \
          ((n) > (MAX_UDELAY_MS * 1000) ? __bad_udelay() :              \
                        __const_udelay((n) * ((2199023U*HZ)>>11))) :    \ 
          __udelay(n))
          //__const_udelay函数和__udelay函数源码位置:arch/arm/lib/delay.S
          
//源码位置:include/linux/delay.h
//ndelay函数功能:延迟x纳秒后继续向下执行
static inline void ndelay(unsigned long x)
{
    
    
        udelay(DIV_ROUND_UP(x, 1000));
        /*
           DIV_ROUND_UP函数位置:linux/kernel.h
           #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
        */
}

//源码位置:include/linux/delay.h
//mdelay函数功能:延迟n毫秒后继续向下执行
#ifndef MAX_UDELAY_MS
#define MAX_UDELAY_MS   5
#endif
#ifndef mdelay
#define mdelay(n) (\
        (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \
        ({unsigned long __ms=(n); while (__ms--) udelay(1000);}))
#endif

二、休眠延迟方法头文件、函数及说明(进程中使用)

/*  msleep(n) : 
    功能 : 休眠n毫秒后继续向下执行
    源码头文件位置:include/linux/delay.h
    源码实现位置:kernel/delay.c
*/
void msleep(unsigned int msecs)
{
    
    
        unsigned long timeout = msecs_to_jiffies(msecs) + 1;
        while (timeout)
                timeout = schedule_timeout_uninterruptible(timeout);
}
EXPORT_SYMBOL(msleep);

/* ssleep(n):
    功能 : 休眠n秒后,继续向下执行
    源码位置:include/linux/delay.h
*/
static inline void ssleep(unsigned int seconds)
{
    
    
        msleep(seconds * 1000);
}

schedule() 
/*
    功能:永久休眠,但可以被中断打断
    头文件位置:include/linux/sched.h
               asmlinkage void schedule(void);
*/

schedule_timeout(signed long timeout)
/*
    功能:休眠timeout(一般有HZ。如:1*HZ表示1秒),但可以被中断打断
          当timeout 为: MAX_SCHEDULE_TIMEOUT时,表示永久休眠,等同于schedule() 函数
    头文件位置:include/linux/sched.h
               signed long __sched schedule_timeout(signed long timeout)

*/

猜你喜欢

转载自blog.csdn.net/weixin_47273317/article/details/107984530