嵌入式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)
*/