第一类延时函数原型是:(忙等) ( 头文件是 #include<linux/delay.h> )
void ndelay(unsigned long nsecs);
void udelay(unsigned long usecs);
void mdelay(unsigned long msecs);
说明:内核函数 ndelay, udelay, 以及 mdelay 对于短延时好用,分别延后执行指定的纳秒数,微秒数或者毫秒数。它们涉及到的延时常常是最多几个毫秒。
第二类延时函数原型是:(使进程进入休眠)
void msleep(unsigned int millisecs);
unsigned long msleep_interruptible(unsigned int millisecs);
void ssleep(unsigned int seconds)
这类方法获得毫秒 (和更长) 延时而不用涉及到忙等待,前 2 个函数使调用进程进入睡眠给定的毫秒数.
一个对 msleep 的调用是不可中断的;你能确保进程睡眠至少给定的毫秒数.
如果你的驱动位于一个等待队列并且你想唤醒来打断睡眠,使用 msleep_interruptible. 从 msleep_interruptible 的返回值正常地是 0; 如果这个进程被提早唤醒,返回值是在初始请求睡眠周期中剩余的毫秒数。对 ssleep 的调用使进程进入一个不可中断的睡眠给定的秒数.

区别:
mdelay 是忙等待函数,在延迟过程中无法运行其他任务.这个延迟的时间是准确的.是需要等待多少时间就会真正等待多少时间.
msleep 是休眠函数,它不涉及忙等待.你如果是 msleep (10),那实际上延迟的时间,大部分时候是要多于 10ms 的,是个不定的时间值.
根据个人经验,10ms 以下的延时对时序要求比较高的地方最好还是用 mdelay,100ms 以上的延时最好还是用 msleep,100ms 以上的延迟
对 linux 的多任务系统运行还是有一定影响的。至于 10ms 到 100ms 之间的延时看时序的要求情况和应用场景灵活决定了。

在Linux Driver 开发中,经常要用到延迟函数:msleep,mdelay/udelay.虽然 msleep 和 mdelay 都有延迟的作用,但他们是有区别的.
1.) 对于模块本身
mdelay 是忙等待函数,在延迟过程中无法运行其他任务.这个延迟的时间是准确的.是需要等待多少时间就会真正等待多少时间.
msleep 是休眠函数,它不涉及忙等待.你如果是 msleep (10),那实际上延迟的时间,大部分时候是要多于10ms 的,是个不定的时间值.

2.) 对于系统:
mdelay () 会占用 cpu 资源,导致其他功能此时也无法使用 cpu 资源。
msleep () 则不会占住 cpu 资源,其他模块此时也可以使用 cpu 资源。
delay 函数是忙则等待,占用 CPU 时间;而 sleep 函数使调用的进程进行休眠。

3.) udelay () mdelay () ndelay () 区别:
udelay (); mdelay (); ndelay (); 实现的原理本质上都是忙等待,ndelay 和 mdelay 都是通过 udelay 衍生出来的。
我们使用这些函数的实现往往会碰到编译器的警告 implicit declaration of function ‘udelay’,这往往是由于头文件的使用不当造成的。
在 include/asm-*/delay.h 中定义了 udelay(),而在 include/linux/delay.h 中定义了 mdelay 和 ndelay.
udelay 一般适用于一个比较小的 delay,如果你填的数大于 2000,系统会认为你这个是一个错误的 delay 函数,因此如果需要 2ms 以上的 delay 需要使用 mdelay 函数。

4.) msleep,ssleep 区别:
休眠单位不同

5.) 秒的单位
ms 是毫秒 = 0.001 秒
us 是微秒 = 0.000001 秒
ns 是纳秒 = 0.000000001 秒