内核Timer的使用方法

一、内核定时器的作用
  • 在linux中周期性的干一些事情
  • 在特定某个时间干一件事情

比如:按键扫描,控制灯闪烁等 。

二、内核定时器的数据组成–timer_list结构体
struct timer_list {
  /**
   * All fields that change during normal runtime grouped to the
   * same cacheline
   */
  struct list_head entry;    
  unsigned long expires;       /* 定时器唤醒(超时)时间 */
  struct tvec_base *base;
  void (*function)(unsigned long);  /* 唤醒后要做的事 */
  unsigned long data;
  int slack;

#ifdef CONFIG_TIMER_STATS
  void *start_site;
  char start_comm[16];
  int start_pid;
#endif

#ifdef CONFIG_LOCKDEP
  struct lockdep_map lockdep_map;
#endif
};

P.S.>其中我们主要来填充唤醒时间和唤醒后要做的事。其它参数初始化可以使用系统提供的固定的定时器初始化函数。

三、 timer的API函数:

初始化定时器:

void init_timer(struct timer_list * timer);

增加定时器:

void add_timer(struct timer_list * timer);

删除定时器:

int del_timer(struct timer_list * timer);

判断一个处在定时器管理队列中的定时器对象是否已经被调度执行:

static inline int timer_pending(const struct timer_list * timer)

修改定时器的expire,常用于重复定时:

int mod_timer(struct timer_list *timer, unsigned long expires);

P.S.>

关于pending:一个处于pending状态的定时器是处在处理器的定时器管理队列中正等待被调度执行的定时器对象 。add_timer只是把一个定时器对象加入到内核的管理队列,但是何时执行实际上由时钟中断(更确切地,是内核在时钟中断的softirq部分才开始扫描定时器管理队列),一个定时器对象pending意味着它的回调函数(timer->function) 尚未被调度执行,而一旦一个定时器对象被调度执行,之后它将被从定时器管理队列中摘除,除非它再次被提交。

关于expires参数:它的单位是jiffies。

四、使用定时器的一般流程为:

(1)创建timer、编写超时定时器处理函数function;

(2)为timer的expires、data、function赋值;

(3)调用add_timer添加一个定时器;此函数会把初始化的参数加入到定时器链表中去。这里要注意的是内核定时器是一个单次的定时器;

(4)在定时器到期时,function被执行;

(5)在程序中涉及timer控制的地方适当地调用del_timer、mod_timer删除timer或修改timer的expires。

五、应用举例
#include <linux/time.h>

/* 定义一个定时器指针 */
static struct timer_list *timer;

/* 参数是timer中的变量data */
void function_handle(unsigned long data)
{
  /* 做你想做的事 */
  ......
      
  /* 因为内核定时器是一个单次的定时器,所以如果想要多次重复定
   * 时需要在定时器绑定的函数结尾重新装载时间,并启动定时。
   * Kernel Timer restart
   */
  mod_timer(timer,jiffies + HZ/50);
}

int xxxx_init(void)
{
  timer = kzalloc(sizeof(struct timer_list), GFP_KERNEL);
  if (!timer )
  {
      /* 错误处理 */
  }

  /* 具体任务的注册等 */
  ......
  /* 初始化定时器 */

  init_timer(timer ); 
  /* 绑定定时时间到后的执行函数 */
  timer->function = function_handle; 
  /* 定时的时间点,当前时间的20ms之后 */ 
  timer->expires = jiffies + (HZ/50); 
  /* 添加并启动定时器 */
  add_timer(timer); 
}

void xxxx_exit(void)
{
  /* 具体任务的卸载等 */
  ......
      
  /* 删除定时器 */
  del_timer(timer);
}

module_init(xxxx_init);
module_exit(xxxx_exit);
MODULE_LICENSE("GPL");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值