5. linux 内核定时器

TOC

1. 定时器简介

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

2. jiffies 变量

要说内核定时器,首先就得说说内核中关于时间的一个重要的概念: jiffies 变量,作为内核时钟的基础,jiffies 每隔一个固定的时间就会增加1,称为增加一个节拍,这个固定间隔由定时器中断来实现,每秒中产生多少个定时器中断,由在<linux/param.h>中定义的 HZ 宏来确定,如此,可以通过 jiffies 获取一段时间,比如 jiffies/HZ 表示自系统启动的秒数。下两秒就是(jiffies/HZ+2), 内核中用jiffies来计时,秒转换成的jiffies:secondsHZ,所以以jiffiy为单位,以当前时刻为基准计时2秒: (jiffies/HZ+2)HZ=jiffies+2*HZ

3.定时器相关API

#include <linux/timer.h>


void init_timer(struct timer_list *timer);
void add_timer(struvt timer_list *timer);
void mod_timer(struct timer_list *timer, unsigned long expires);
//定时器是否在运行
int timer_pending(struct timer_list *timer);
void del_timer(struct timer_list *timer);
//确保删除定时器不会在另外一个CPU上运行
void del_timer_sync(struct timer_list *timer);

4. 驱动例程

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


struct timer_list tm;


MODULE_LICENSE("GPL");


void call_back(unsigned long arg)
{
    printk("Timer is now!\n");


    //定时器执行完,需要重新注册
    tm.expires = jiffies + 2*HZ;
    add_timer(&tm);
}


static int timer_init(void)
{
    printk("Timer is Init!\n");
    init_timer(&tm);
    tm.function = call_back;
    //定时器两秒后触发
    tm.expires = jiffies + 2 * HZ;
    add_timer(&tm);


    return 0;
}


static void timer_exit(void)
{
    printk("Exist timer ...\n");

    del_timer(&tm);
}




module_init(timer_init);
module_exit(timer_exit);

说明:使用dmesg可以查看内核打印

猜你喜欢

转载自www.cnblogs.com/standardzero/p/12551012.html