Linux内核延时研究与函数代码分析

Linux 内核中的延时函数 udelay 一般适用于一个比较小的 delay,如果你填的数大于 2000,系统会认为你这个是一个错误的 delay 函数,因此如果需要 2ms 以上的 delay 需要使用 mdelay 函数。msleep 是休眠函数,它不涉及忙等待.你如果是 msleep (10),那实际上延迟的时间,大部分时候是要多于 10ms 的,是个不定的时间值.。msleep 是休眠函数,它不涉及忙等待.你如果是 msleep (10),那实际上延迟的时间,大部分时候是要多于10ms 的,是个不定的时间值.。 阅读详情
jiffies 以前提过,但是用来计算函数调用的时间确实显得粒度太大(一个 jiffies = 1ms or 4ms )
gettimeofday (用户态)和do_gettimeofday(内核态)用下来感觉不错。粒度可以达到us级别。
试验过一个while 循环
unsigned long i =0xffffffff; while(i--);
按代码来讲,这个时间应该不算短,测出来的时间却是0. 估计是代码优化了。
加个volatile :
volatile unsigned long i=0xffffffff; while(i--);
跑了半天才跑出来。。。

==========================================

Linux内核延时研究与函数代码分析

 

 

有时驱动程序需要非常短的延迟来与硬件同步。此时,使用jiffies值无法达到目的。这时就要用内核函数udelay和mdelay。u表示希腊字母“mu”(m),它代表“微”。它们的原型如下:

#include <Linux/delay.h>

void udelay(unsigned long usecs); //软件循环延迟指定数目的微秒数

void mdelay(unsigned long msecs); //使用 udelay 做循环

该函数在绝大多数体系结构上是作为内联函数编译的。udelay函数里要用到BogoMips值:它的循环基于整数值loops_per_second,这个值是在引导阶段计算BogoMips时得到的结果。

udelay函数只能用于获取较短的时间延迟,因为loops_per_second值的精度只有8位,所以,当计算更长的延迟时会积累出相当大的误差。尽管最大能允许的延迟将近1s(因为更长的延迟就要溢出),推荐的udelay函数参数最大值是取1000us(1ms)。当延迟大于11ms时可以使用函数mdelay。许多驱动程序需要将任务延迟到以后处理,但又不想借助中断。Linux为此提供了三种方法:任务队列、tasklet和内核定时器。

要特别注意的是udelay是个忙等待函数,在延迟的时间段内无法运行其他的任务。源码见头文件<asm/delay.h>。

 

目前内核不支持大于1微秒而小于1个时钟滴答的延迟,但这不是个问题,因为延迟是给硬件或者人去识别的。百分之一秒的时间间隔对人来说延迟精度足够了,而1毫秒对硬件来说延迟时间也足够长。如果你真的需要其间的延迟间隔,你只要建立一个连续执行udelay(1000)函数的循环。

linux内核延时函数代码示例: 

1、#include <linux/time.h>

void do_gettimeofday(struct timeval *tv)

{

 unsigned long flags;

 unsigned long usec, sec;

 read_lock_irqsave(&xtime_lock, flags);

 sec = xtime.tv_sec;

 usec = xtime.tv_usec + do_gettimeoffset();

 read_unlock_irqrestore(&xtime_lock, flags);

 while (usec >= 1000000) {

  usec -= 1000000;

  sec++;

 }

 tv->tv_sec = sec;

 tv->tv_usec = usec;

}

void MyDelay(unsigned long delay)

{

 struct timeval tv;

 do_gettimeofday(&tv)

 unsigned long start = tv.tv_usec;//unsigned long start = tv.tv_sec;

 while(tv.tv_usec - start <delay)

    do_gettimeofday(&tv)

}

2、如果驱动程序使用等待队列等待某个事件,而你又想确保在一段时间后运行该驱动程序时

extern inline long sleep_on_timeout(wait_queue_head_t *q, signed long timeout)

{

    signed long early = 0;

       

    current->timeout = jiffies + timeout;

    sleep_on (q);

    if (current->timeout > 0) {

        early = current->timeout - jiffies;

        current->timeout = 0;

    }

    return early;

}

extern inline long interruptible_sleep_on_timeout(wait_queue_head_t *q,

                signed long timeout)

{

    signed long early = 0;

       

    current->timeout = jiffies + timeout;

    interruptible_sleep_on (q);

    if (current->timeout > 0) {

        early = current->timeout - jiffies;

        current->timeout = 0;

    }

    return early;

}

3.无需等待其他事件,则可直接延时等待

extern inline void schedule_timeout(int timeout)

{

    current->timeout = jiffies + timeout;

    current->state = TASK_INTERRUPTIBLE;

    schedule();

    current->timeout = 0;

}

set_current_state(TASK_INTERRUPTIBLE);

schedule_timeout(jit_delay*HZ);

4 非常短的延时与硬件同步 udelay推荐最大1000us

#include<linux/delay.h>

void __delay(int loops)

{

 long long dummy;

 __asm__ __volatile__("gettr " __t0 ", %1/n/t"

        "_pta 4, " __t0 "/n/t"

        "addi %0, -1, %0/n/t"

        "bne %0, r63, " __t0 "/n/t"

        "ptabs %1, " __t0 "/n/t":"=r"(loops),

        "=r"(dummy)

        :"0"(loops));

}

void __udelay(unsigned long long usecs, unsigned long lpj)

{

 usecs *= (((unsigned long long) HZ << 32) / 1000000) * lpj;

 __delay((long long) usecs >> 32);

}

#ifdef notdef

#define mdelay(n) (/

 {unsigned long msec=(n); while (msec--) udelay(1000);})

#else

#define mdelay(n) (/

 (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : /

 ({unsigned long msec=(n); while (msec--) udelay(1000);}))

#endif

延时函数介绍 文章目录基本介绍一、sleep二、usleep三、mdelay四、udelay五、ndelay 在操作系统中和单片机处理延时方式就完全不一样了,不可能是使用for循环浪费系统资源。而是有专门的接口函数。 基本介绍 Linux 中常用的函数有以下函数 sleep、usleep、ndelay、udelay、mdelay 等 Linux 系统编程下用到的延时函数在头文件“#include <unistd.h>”中,包括函数 sleep、 usleep。 Linux 内核中用到的延时函数在“#incl 阅读详情

相关推荐

用友U8自定义按钮开发:从基础配置到实战业务集成

本文详细介绍了用友U8自定义按钮开发的完整流程,从基础配置到实战业务集成。通过实际案例演示如何在U8系统中添加和替换功能按钮,包括数据库配置、SQL脚本编写和VB组件开发等关键技术点,帮助企业用户实现业务场景的深度定制。

weixin_29698641的博客 254

LINUX内核延时研究与函数代码分析

有时驱动程序需要非常短的延迟来与硬件同步。此时,使用jiffies值无法达到目的。这时就要用内核函数udelay和mdelay。u表示希腊字母“mu”(m),它代表“微”。它们的原型如下: #include <Linux/delay.h> void udelay(unsigned long usecs); //软件循环延迟指定数目的微秒数 void m...

weixin_33747129的博客 188

给STM32 LWIP做一次‘性能体检’:手把手教你用Wireshark和iperf诊断网络瓶颈

本文详细介绍了如何使用Wireshark和iperf工具对STM32 LWIP网络性能进行全面诊断,帮助开发者精准定位网络瓶颈问题。通过搭建测试环境、集成iperf测试框架、深度报文分析和LWIP配置优化,实现从9KB/s到80MB/s的性能飞跃,特别适用于解决TCP发送速率和卡死问题。

weixin_29631169的博客 288

linux 内核获取时间,Linux内核中的jiffies 以及时间的获取time

硬件给内核提供一个系统定时器用以计算和管理时间,内核通过编程预设系统定时器的频率,即节拍率(tick rate),每一个周期称作一个tick(节拍)。Linux内核从2.5版内核开始把频率从100调高到1000(当然带来了很多优点,也有一些缺点).jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数。譬如,如果计算系统运行了多长时间,可以用 jiffies/tick rate ...

weixin_39609170的博客 931

Unity 游戏实例开发集合 之 Car Racing 2D (2D赛车) 休闲小游戏快速实现

Unity 游戏实例开发集合 之 Car Racing 2D (2D赛车) 休闲小游戏快速实现 目录 Unity 游戏实例开发集合 之 Car Racing 2D (2D赛车) 休闲小游戏快速实现 一、简单介绍 二、Car Racing 2D (2D赛车) 游戏内容与操作 三、相关说明 四、游戏代码框架 五、知识点 六、游戏效果预览 七、实现步骤 八、工程源码地址 九、延伸扩展 一、简单介绍 Unity 游戏实例开发集合,使用简单易懂的方式,讲解常见游戏的开发实现过程,方便

仙魁XAN 7701

1.嵌入式控制器EC学习,编译环境搭建

工欲善其事,必先利其器。 在学习EC相关知识之前,首先需要完成EC代码编译环境的搭建,需要如下内容: Keil C51(用于EC中C代码的编译器环境) EC源代码,我们使用从网上可以下载到的 ITE_V12.4_Update 版的代码为例进行学习 代码编辑器,这个可以根据自己的习惯选择,VS Code或者Source Insight等 Keil C51下载地址: http://www.downcc.com/soft/307131.html 下载完成后请进行破解 EC源代码 ...

qq_30135687的博客 3916

Linux驱动程序记录时间差的方法--jiffies和do_gettimeofday()区别。

Linux驱动程序记录时间差的方法 常用的Linux内核空间记录一个事务的时间差有两种方法–使用jiffies变量和do_gettimeofday()函数。这两天接到一个测量PCIe总线带宽的任务,使用芯片自带的PCIe 内部DMA读取PCIe地址空间的数据以测量PCIe的总线带宽,使用了两种测量DMA启动到DMA传输完成的时间差。 1. jiffies记录时间差的特点 使用jiffies较为...

Milicat Blog 2519

JavaSwing_4.2: JDialog、JOptionPane(对话框)

JDialog,对话框。使用 JDialog 类可以创建自定义有的对话框,或者调用 JOptionPane 中的多个静态方法快速创建各种标准的对话框。JOptionPane是 JavaSwing 内部已实现好的,以静态方法的形式提供调用,能够快速方便的弹出要求用户提供值或向其发出通知的标准对话框。

谢TS的博客 7万+

Linux系统信息的获取(系统中的时间,获取使用随机数,proc文件系统)

1.linux系统中的时间 (1)jiffies是linux内核中的一个全局变量,jiffies记录了系统启动以来,经过了多少tick(系统时间片),jiffies变量开机时有一个基准值,然后内核每过一个节拍时间(tick)jiffies就会加1,然后到了系统的任意一个时间我们当前时间就被jiffies这个变量所标注。 (2)常用的时间相关的API和C库函数有9个:time/ctime/localtime/gmtime/mktime/asctime/strftime/gettimeofday/set..

weixin_49303682的博客 637

[Python从零到壹] 十三.机器学习之聚类算法四万字总结全网首发(K-Means、BIRCH、树状聚类、MeanShift)

欢迎大家来到“Python从零到壹”,在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界。所有文章都将结合案例、代码和作者的经验讲解,真心想把自己近十年的编程经验分享给大家,希望对您有所帮助,文章中不足之处也请海涵。Python系列整体框架包括基础语法10篇、网络爬虫30篇、可视化分析10篇、机器学习20篇、大数据分析20篇、图像识别30篇、人工智能40篇、Python安全20篇、其他技巧10篇。您的关注、点赞和转发就是对秀璋最大的支持,知识无价人有情,希望

杨秀璋的专栏 2万+

基于DSIFT多尺度图像融合的MATLAB代码

多尺度图像融合是一种常用的图像处理技术,它可以将具有不同尺度和空间频率特征的图像融合成一幅更具信息丰富度和视觉效果的图像。DSIFT算法是一种基于SIFT算法的改进版本,它在提取图像特征时采用了密集采样的方法,能够有效地提取图像的局部特征。多尺度图像融合基于DSIFT算法的思想,通过在不同尺度下提取图像的DSIFT特征,并将这些特征进行融合,得到最终的融合图像。然后,通过DSIFT算法提取了两幅图像的特征。通过运行上述代码,我们可以在MATLAB中实现基于DSIFT多尺度图像融合的算法,并观察到融合结果。

IELLQUI9的博客 180

linux设备驱动七(时间、延迟及延缓操作)

知识点: 如何度量时间差,如何比较时间 如何获得当前时间 如何将操作延迟指定一段时间 如何调度异步函数到指定时间之后执行 度量时间差 HZ指一秒内产生的时钟中断次数,即时钟中断频率 jiffies_64记录自上一次操作系统引导以来的时钟滴答数。即使在32位架构上也是64位。 驱动程序通常访问jiffies变量。它是unsigned long类型,要么和jiffies_64相同,要么仅仅是jiffies_64的低32位.使用它的原因是访问快,而对6...

oscube的博客 2865

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

linux 内核udelay的准确度,LINUX内核延时研究与函数代码分析

有时驱动程序需要非常短的延迟来与硬件同步。此时,使用jiffies值无法达到目的。这时就要用内核函数udelay和mdelay。u表示希腊字母“mu”(m),它代表“微”。它们的原型如下:#include void udelay(unsigned long usecs); //软件循环延迟指定数目的微秒数void mdelay(unsigned long msecs); //使用 udelay 做...

weixin_42425075的博客 2413

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

转载_Linux内核延时研究与函数代码分析

jiffies 以前提过,但是用来计算函数调用的时间确实显得粒度太大(一个 jiffies = 1ms or 4ms )gettimeofday (用户态)和do_gettimeofday(内核态)用下来感觉不错。粒度可以达到us级别。试验过一个while 循环unsigned long i =0xffffffff; while(i--);按代码来讲,这个时间应该不算短,测出来的时间却是0. 估计

williamwanglei的专栏 785

Linux内核中的延时函数详解

本文讲述了内核中涉及的两种不同性质的延时函数,并分析了各自的应用场景。

Leon的博客 1万+

Linux 内核延时函数

linux内核提供3个函数分别进行纳秒,微妙和毫秒延时: void ndelay(unsigned long nsecs); void udelay(unsigned long usecs); void mdelay(unsigned long msecs); 这3个函数的延时原理是忙等待,也就是说在延时的过程中并没有放弃cpu,根据cpu的频率进行一定次数

Wait for 的专栏 1万+

【Linux】内核延时机制详解:底层原理与实现

延时是指在程序中插入一段等待时间,使得程序在这段时间内不执行任何操作。等待硬件设备完成某个操作:例如,等待一个I/O操作完成。软件上的同步:例如,等待其他进程或线程完成某些任务。调试目的:例如,人为插入延时以便观察系统行为。32延时是Linux内核编程中的一个重要概念,合理使用延时机制不仅能够保证程序的正确执行,还能优化系统的性能。本文从底层原理出发,详细介绍了Linux内核中的几种延时方法及其适用场景,并给出了相应的示例代码。

极客代码 2041

内核延时函数

转载至:http://oss.org.cn/kernel-book/ldd3/ch07s03.html 当一个设备驱动需要处理它的硬件的反应时间, 涉及到的延时常常是最多几个毫秒. 在这个情况下, 依靠时钟嘀哒显然不对路. The kernel functions ndelay, udelay, and mdelay serve well for short delays, delaying

闲云孤鹤 2101

Linux系统编程——延时函数

1. 延时函数简介 Linux 中常用的延时函数有 sleep,usleep,ndelay,udelay,mdelay等。 Linux 系统编程下用到的延时函数在头文件 #include <unistd.h> 包括 sleep,usleep; Linux 内核中用到的延时函数在头文件 #include <linux/delay.h> 包括 ndelay,udelay,mdelay。 2. sleep 函数简介 函数 sleep 是秒延时,函数原型如下: unsigned

Kenneth的博客 1万+

linux内核的延时函数,linux中内核延时函数 (转)

第一类延时函数原型是:(忙等)void ndelay(unsigned long nsecs);void udelay(unsigned long usecs);void mdelay(unsigned long msecs);说明:内核函数 ndelay, udelay, 以及 mdelay 对于短延时好用, 分别延后执行指定的纳秒数, 微秒数或者毫秒数. 它们涉及到的延时常常是最多几个毫秒。第...

weixin_28965077的博客 1101

Linux内核中的延时函数

第一类延时函数原型是:(忙等) ( 头文件是 #include<linux/delay.h> ) void n...

biaotai的博客 1550

linux内核态延时函数及头文件,Linux内核延时函数

linux内核提供3个函数分别进行纳秒,微妙和毫秒延时(使用时包要含头文件):void ndelay(unsigned long nsecs);void udelay(unsigned long usecs);void mdelay(unsigned long msecs);这3个函数的延时原理是忙等待,也就是说在延时的过程中并没有放弃cpu,根据cpu的频率进行一定次数的循环。在内核中对于毫秒级...

weixin_35241413的博客 1914

全面解析Linux内核延时机制及其应用

本文将深入探讨Linux内核中的延时机制,包括忙等待和睡眠等待的具体实现方式、优缺点及其应用场景,并结合实际案例进行详细解析。在实际开发中,应根据具体需求选择合适的延时函数,合理利用忙等待和睡眠等待方式,以达到最佳的系统性能。这些函数的实现依赖于CPU的时钟频率,因此在不同的平台上可能会有不同的行为。需要注意的是,忙等待方式在延时期间不会释放CPU,因此不适用于需要长时间延时的场景。通过深入理解这些机制,开发者可以更好地控制和优化Linux系统的延时操作,提高系统的可靠性和性能。

极客代码 1587
上一篇: SVN简易使用手册
下一篇: Linux内核线程编程方法
flyingcloud_2008
博客等级 码龄19年 10粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值