linux内核延时:短延迟

博客介绍了Linux内核中的延时函数,如ndelay()、udelay()和mdelay()等,其实现原理是忙等待。还提到内核启动时会进行延迟循环校准计算lpj,若在bootargs中设置lpj=30000可省校准过程、节省开机时间。此外,讲述了在uboot中设置lpj=30000的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

        有时候为了等待硬件设置生效,我们会在设置完硬件寄存器后,添加微小的延时函数。本次介绍linux内核中的延时函数。

一 短延迟

Linux内核中提供了下列3个函数以分别进行纳秒、微秒和毫秒延迟:

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

        上述延迟的实现原理本质上是忙等待,它根据CPU频率进行一定次数的循环。有时候,人们在软件中进行下面的延迟:

void delay(unsigned int time)
{
    while(time--);
}

        ndelay()、udelay()和mdelay()函数的实现方式原理与此类似。内核在启动时,会运行一个延迟循环校准(Delay Loop Calibration),计算出lpj(Loops Per Jiffy),内核启动时会打印如下类似信息:

[    0.003137] Calibrating delay loop (skipped), value calculated using timer frequency.. 6.00 BogoMIPS (lpj=30000)

        如果我们直接在bootloader传递给内核的bootargs中设置lpj=30000,则可以省掉这个校准的过程,节省约百毫秒级的开机时间。毫秒时延(以及更大的秒时延)已经比较大了,在内核中,最好不要直接使用mdelay()函数,这将耗费CPU资源,对于毫秒级以上的时延,内核提供了下述函数:

void msleep(unsigned int millisecs);
unsigned long msleep_interruptible(unsigned int millisecs);
void ssleep(unsigned int seconds);

        上述函数将使得调用它的进程睡眠参数指定的时间为millisecs,msleep()、ssleep()不能被打断,而msleep_interruptible()则可以被打断。受系统Hz以及进程调度的影响,msleep()类似函数的精度是有限的。

二 在uboot中设置lpj=30000

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.11:/big/nfsroot/jiaocheng_rootfs,proto=tcp rw ip=192.168.0.3:192.168.0.11:192.168.0.1:255.255.255.0:::;lpj=30000;'

设置完毕后,启动内核,找到这条调试信息:

[    0.003143] Calibrating delay loop (skipped), value calculated using timer frequency.. 6.00 BogoMIPS (lpj=30000)

        并没有发现启动速度有超过百毫秒的提升。正如调试信息提示的一样Calibrating delay loop (skipped),计算过程跳过了,使用的是常量值。

结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千册

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值