内核定时器的简单应用

从离开大学到现在,接触linux内核也差不多有一个月了,基本上对于我来说只是了解一下理论知识,而并没有去用过,本篇主要是介绍了内核定时器的一个简单的应用,其实,内核定时器如果去深入的了解的话,当然是不简单,光从内核源码来看,它的数据结构就尤为复杂,但是今天这个例子, 会非常简单。
  在Linux内核中,有这样的一个定时器,叫做内核定时器,内核定时器用于控制某个函数,也就是定时器将要处理的函数在未来的某个特定的时间内执行。内核定时器注册的处理函数只执行一次,即不是循环执行的。

 

如果对延迟的精度要求不高的话,最简单的实现方法如下---忙等待:

Unsigned long  j = jiffies + jit_delay * HZ;

While(jiffies  <  j)

{

         ……

}

jiffies:全局变量,用来记录自系统启动以来产生的节拍总数。启动时内核将该变量初始化为0;

此后每次时钟中断处理程序增加该变量的值。每一秒钟中断次数HZ,jiffies一秒内增加HZ。系统运行时间 =
jiffie/HZ.

jiffies用途:计算流逝时间和时间管理

jiffies内部表示:

             extern u64 jiffies_64;

             extern unsigned long volatilejiffies;     //位长更系统有关32/64

  32位:497天后溢出

64位:……

 

在定时器中有这样一个概念,度量时间差:

时钟中断由系统的定时硬件以周期性的时间间隔产生,这个间隔说白了其实就是频率由内核根据HZ来确定,HZ是一个与体系结构无关的常数,可以配置为(50-1200),在X86平台,它的值被默认为1000
;

 

定时器数据结构被组织成双向链表,如下:

Struct  timer_list  {

              struct list_head entry;

              //定时值基于jiffies

              unsigned long expires;

              //定时器内部值

              struct tvec_base *base;

              //定时器处理函数

              void (*function)(unsigned long);

              //定时器处理函数参数

              unsigned long data;   

              ……

      };

 

对内核定时器操作有如下函数:

Void init_timer(struct timer_list *timer) ;

void add_timer(struct timer_list *timer);

int del_timer(struct timer_list *timer) ;

 

分别表示初始化定时器队列结构,启动定时器,在定时器超时前将它删除。当定时器超时后,系统会自动将它删除掉。

 

接下来我们来看一个例子:

 

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/timer.h>  /*timer*/

#include <asm/uaccess.h>  /*jiffies*/

 

MODULE_LICENSE("GPL");

MODULE_AUTHOR("yangyuanxin");

MODULE_DESCRIPTION("TimerModule");

MODULE_ALIAS("timer module");

 

struct timer_list timer;

//定时器超时执行函数 

void timer_function(int para)

{

   printk("<0>Timer Expired and para is %d !!\n",para);   

}
 

int timer_init()

{

         init_timer(&timer);                   //初始化内核定时器

         timer.data= 5;                       //给执行的函数传参

         timer.expires= jiffies + (5 * HZ);         //当前jiffies的值加上5秒钟之后

         timer.function= timer_function;        //如果超时了就执行这个函数

         add_timer(&timer);                  //启动定时器

        

         return0;

void timer_exit()

{

         del_timer(&timer );

}

 

module_init(timer_init);

module_exit(timer_exit);

时间: 2024-09-17 04:25:02

内核定时器的简单应用的相关文章

Linux驱动技术(七) _内核定时器与延迟工作

内核定时器 软件上的定时器最终要依靠硬件时钟来实现,简单的说,内核会在时钟中断发生后检测各个注册到内核的定时器是否到期,如果到期,就回调相应的注册函数,将其作为中断底半部来执行.实际上,时钟中断处理程序会触发TIMER_SOFTIRQ软中断,运行当前处理器上到期的所有定时器. 设备驱动程序如要获得时间信息以及需要定时服务,都可以使用内核定时器. jiffies 要说内核定时器,首先就得说说内核中关于时间的一个重要的概念:jiffies变量,作为内核时钟的基础,jiffies每隔一个固定的时间就会

内核定时器的使用(好几个例子add_timer)【转】

转自:http://blog.csdn.net/jidonghui/article/details/7449546   LINUX内核定时器是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,其实现位于 <linux/timer.h> 和 kernel/timer.c 文件中.被调度的函数肯定是异步执行的,它类似于一种"软件中断",而且是处于非进程的上下文中,所以调度函数必须遵守以下规则: 1) 没有 current 指针.不允许访问用户空间.因

linux驱动开发--内核定时器

1.内核定时器 时钟中断:由系统的定时硬件以周期性的时间间隔发生,这个间隔(也就是频率)由内核根据常数HZ来确定. HZ常数:她是一个与体系结构无关的常数,可以配置50-1200之间,可以在内核中配置 tick:她是HZ的倒数,也就是每发生一次硬件定时器中断的事件间隔.如HZ为200,tick为5毫秒. jiffies核心变数:它是linux核心变数(32位变数,unsigned long),它被用记录自开机以来,已经过多少个tick.每发生一次硬件定时器中断,jiffies变数会被加1. 定时

5-3 Linux内核计时、延时函数与内核定时器【转】

转自:http://www.xuebuyuan.com/510594.html 5-3 Linux内核计时.延时函数与内核定时器  计时 1. 内核时钟 1.1   内核通过定时器(timer)中断来跟踪时间流 1.2   硬件定时器以周期性的间隔产生时间中断,这个间隔(即频率)由内核根据HZ来确定,HZ是一个与体系结构无关的常数. 1.3   这个时间间隔通常取1ms到10ms. 2. jiffies计算器 2.1每次当定时器中断发生时,内核内部通过一个64位的变量jiffies_64做加一计

gpio口、内核定时器使用

/*申请gpio*/ int gpio_request(unsigned gpio, const char *label); /*设置gpio为输入状态,即设置如(GPH0CON)*/ int gpio_direction_input(unsigned gpio);   /*设置gpio为输出状态,即设置如(GPH0CON)*/ int gpio_direction_output(unsigned gpio, int value);   /*设置gpio为输入或输出状态,即设置如(GPH0CON

实现jquery定时器的简单代码

 项目遇到一个消息的模块,在导航条最上面.想实现,当收到消息的时候能够及时的刷新,显示收到消息的条数,下面为大家介绍两种不错的方法,感兴趣的朋友可以参考下 简单的代码实现jquery定时器.    今天,项目遇到一个消息的模块,在导航条最上面.想实现,当收到消息的时候能够及时的刷新,显示收到消息的条数.想了半天.想了2种方法,    1.利用struts2的Ajax标签.    2.利用jquery.    struts2有点麻烦,jquery比较简单用jquery了.下面贴上代码:实现每隔3S

一个使用多媒体定时器的简单例子

1)新建一个工程,保存 2)添加一个Button和一个Label 3)修改unit1.h代码如下: // --------------------------------------------------------------------------- #ifndef Unit1H #define Unit1H // --------------------------------------------------------------------------- #include <Cl

linux 内核驱动编程 简单例子 与_IO, _IOR, _IOW, _IOWR 宏解析

一._IO, _IOR, _IOW, _IOWR 宏的用法与解析 在驱动程序里, ioctl() 函数上传送的变量 cmd 是应用程序用于区别设备驱动程序请求处理内容的值.cmd除了可区别数字外,还包含有助于处理的几种相应信息. cmd的大小为 32位,共分 4 个域:bit31~bit30 2位为 "区别读写" 区,作用是区分是读取命令还是写入命令.bit29~bit15 14位为 "数据大小" 区,表示 ioctl() 中的 arg 变量传送的内存大小.bit2

KVM基于内核的虚拟机简单教程

KVM(Kernel-based Virtual http://www.aliyun.com/zixun/aggregation/39569.html">Machine) http://www.linux-kvm.org/ ,基于内核的虚拟机,配合QEMU(处理器虚拟软件),需要CPU支持虚拟化技术(并且在BIOS里打开虚拟化选项),效率可达到物理机的80%以上.此外,它对SMP的支持很好. 对比 1.Vmware的功能全面,设置全面,速度相对最慢: 2.VirtualBox的效率比Vmw