linux之延时及内核定时器的使用

想要在内核中的实行短的延时我们可以看这两个头文件linux-3.0.1\include\linux下的delay.hlinux-3.0.1\arch\arm\include\asm下的delay.h里面包含了这样几句延时的语句

void ndelay(unsigned long nsecs); //纳秒级的延时

void udelay(unsigned long usecs); //微妙级的延时

void mdelay(unsigned long msecs); //毫秒级的延时

用这三个函数我们要重点知道他们是忙等待函数,因此在延时的同时其它程序是无法运行的,如果涉及到毫秒级以上的延时我个人不推荐使用mdelay因为对于处理器来说毫秒是一个很长的时间,在这之中它可以做很多的事情,因此我们可以使用一下的函数来替换这个函数:

void msleep(unsigned int millsecs); //毫秒级睡眠

unsigned long msleep_interruptible(unsigned int millsecs); //毫秒级带有中断唤醒的延时(通常返回值为0,但是如果提前被唤醒则返回剩余毫秒数)

void ssleep(unsigned int seconds)  //秒级的延时

个人认为这些延时过程当中系统在进行任务的调度,当延时时间到达时,内核在直接调度这个进程。 

内核定时器是基于滴答时钟实现定时,如果我们需要在将来的某一个时刻让内核调度执行某段程序,同时在这个时刻到来之前不会阻塞当前进程。

内核定时器的使用只有3个步骤

1.定义定时器结构体

struct timer_list {

struct list_head entry; //定时器列表

unsigned long expires; //定时器到期时间

struct tvec_base *base;

void (*function)(unsigned long); //定时器中断处理函数

unsigned long data; //作为参数可以传入定时器中断处理函数

};

2.给定时器结构体赋定时时间、定时中断处理函数、传参设定。

在这里我讲一下定时的数值该怎么来确定,因为内核定时器是基于jiffies,所以设置的时间要在jiffies之上加上我们的定时值,比如定时2秒则:2*HZ,看到这个HZ可能会蒙,其实很好理解,在linux-3.0.1\arch\arm\include\asm下的param.h头文件中已经给出,就是每秒中jiffies这个计数器会计多少值。

3.激活定时器add_timer;

对于上面的第2步,涉及到静态定义和动态定义两种方法

静态定义struct timer_list TIMER_INITIALIZER(_function, _expires, _data);

直接把中断函数,到期时间,传入参数写上即可。

动态定义,就是我们一般的对结构体赋值,非常简单。不过在赋值之前我们先必须初始化timer_list这个结构体,init_timer(&结构体名);

完成以上步骤之后我们就可以调用add_timer函数来激活定时器开始定时。

当我们激活定时器后,它只会执行一次处理函数,然后将定时器从内核中移除。但我们平时往往需要重复执行,所以内核给我吗提供了int mod_timer(struct timer_list *timer, unsigned long expires)

在不用定时器的时候我们需要int del_timer(struct timer_list *timer)需要删除定时器。

最后讲一下内核是如何来管理定时器的,当我们启动一个定时器的时候,定时器并不是右我们当前加载的模块来管理,而是由内核的swapper进程来接管了这个定时器,当定时器时间一到。内核将调用swapper进程执行函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值