我是靠谱客的博主 笨笨皮带,最近开发中收集的这篇文章主要介绍(十二)linux内核定时器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

        • (一)内核定时器介绍
        • (二)内核定时器相关接口
        • (三)使用步骤
        • (四)实例代码

(一)内核定时器介绍

内核定时器并不是用来简单的定时操作,而是在定时时间后,触发事件的操作,类似定时器中断,是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,内核中采用的定时器以jiffies为单位。 单位秒=jiffies/HZ

几个重要跟时间有关的名词或变数

HZ:Linux核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是用来定义每一秒有几次
     timer interrupts。举例来说,HZ为1000,代表每秒有1000次timer interrupts。
Tick:Tick是HZ的倒数,意即timer interrupt每发生一次中断的时间。如HZ为250时,
      tick为4毫秒(millisecond)。
Jiffies:Jiffies为Linux核心变数(unsigned long),它被用来记录系统自开机以来,已经过
         了多少tick。每发生一次timer interrupt,Jiffies变数会被加一。值得注意的是,
         Jiffies于系统开机时,并非初始化成零,而是被设为-300*HZ ,类似Linux系统
         中time(日历时间)

(二)内核定时器相关接口

和定时器先关的数据结构:

struct timer_list {
	unsigned long expires;	//未来时间点,即超时时间
	void (*function)(unsigned long);//超时回调函数
	unsigned long data;	//传递给回调函数的数据,也就是定时器数据		
};

初始化定时器相关的数据结构

1. 静态定以定时器数据结构:
#define DEFINE_TIMER(_name, _function, _expires, _data)		
	struct timer_list _name =				
		TIMER_INITIALIZER(_function, _expires, _data)

2. 动态初始化:-----手动对变量进行初始化
#define init_timer(timer)						
	do {								
		static struct lock_class_key __key;			
		init_timer_key((timer), #timer, &__key);		
	} while (0)

可延时定时:

#define init_timer_deferrable(timer)					
	do {								
		static struct lock_class_key __key;			
		init_timer_deferrable_key((timer), #timer, &__key);	
	} while (0)

设置定时时间

#define setup_timer(timer, fn, data)					
do {								
    static struct lock_class_key __key;			
    setup_timer_key((timer), #timer, &__key, (fn), (data));
} while (0)

向内核添加定时器:

/**
 * add_timer - start a timer
 * @timer: the timer to be added
 *
 * The kernel will do a ->function(->data) callback from the
 * timer interrupt at the ->expires point in the future. The
 * current time is 'jiffies'.
 *
 * The timer's ->expires, ->function (and if the handler uses it, ->data)
 * fields must be set prior calling this function.
 *
 * Timers with an ->expires field in the past will be executed in the next
 * timer tick.
 */
void add_timer(struct timer_list *timer)
{
	BUG_ON(timer_pending(timer));
	mod_timer(timer, timer->expires);
}

从内核删除定时器:

/**
 * del_timer - deactive a timer.
 * @timer: the timer to be deactivated
 *
 * del_timer() deactivates a timer - this works on both active and inactive
 * timers.
 *
 * The function returns whether it has deactivated a pending timer or not.
 * (ie. del_timer() of an inactive timer returns 0, del_timer() of an
 * active timer returns 1.)
 */
int del_timer(struct timer_list *timer)

修改定时时间:

/**
 * mod_timer - modify a timer's timeout
 * @timer: the timer to be modified
 * @expires: new timeout in jiffies
 *
 * mod_timer() is a more efficient way to update the expire field of an
 * active timer (if the timer is inactive it will be activated)
 *
 * mod_timer(timer, expires) is equivalent to:
 *
 *     del_timer(timer); timer->expires = expires; add_timer(timer);
 *
 * Note that if there are multiple unserialized concurrent users of the
 * same timer, then mod_timer() is the only safe way to modify the timeout,
 * since add_timer() cannot modify an already running timer.
 *
 * The function returns whether it has modified a pending timer or not.
 * (ie. mod_timer() of an inactive timer returns 0, mod_timer() of an
 * active timer returns 1.)
 */
int mod_timer(struct timer_list *timer, unsigned long expires)

jiffies和时间的转换:

extern unsigned int jiffies_to_msecs(const unsigned long j);
extern unsigned int jiffies_to_usecs(const unsigned long j);
extern unsigned long msecs_to_jiffies(const unsigned int m);
extern unsigned long usecs_to_jiffies(const unsigned int u);

(三)使用步骤

1、向内核添加定时器

   setup_timer();设置定时器
   add_timer();.

2、解绑定时器

   int del_timer(struct timer_list *timer)

(四)实例代码

#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/module.h>

struct timer_list timer;
void function(unsigned long data)
{
  static int count=0;
  printk("this is timer test:%dn",count++);
  mod_timer(&timer,jiffies+1*HZ);
}
static int __init timer_module_init(void)
{
  timer.expires = jiffies+5*HZ;
  setup_timer(&timer,function,0);
  add_timer(&timer);
  return 0;
}
static void __exit timer_module_cleanup(void)
{
  del_timer(&timer);
}

module_init(timer_module_init);
module_exit(timer_module_cleanup);
MODULE_LICENSE("GPL");

测试


本文章仅供学习交流用禁止用作商业用途,文中内容来水枂编辑,如需转载请告知,谢谢合作

微信公众号:zhjj0729

微博:文艺to青年

最后

以上就是笨笨皮带为你收集整理的(十二)linux内核定时器的全部内容,希望文章能够帮你解决(十二)linux内核定时器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(87)

评论列表共有 0 条评论

立即
投稿
返回
顶部