首页 > 技术文章 > (七) 定时器

wolfrickwang 2013-09-03 15:21 原文

  定时器是一种轮询的机制,每隔一段时间去执行下相关的函数。

(1) 内核中 定时器结构

  Linux在include/linux/timer.h头文件中定义了数据结构timer_list来描述一个内核定时器  

CODE>struct timer_list { 
struct list_head list; 
unsigned long expires; 
unsigned long data; 
void (*function)(unsigned long); 
}

  1> list:  双向链表元素list:用来将多个定时器连接成一条双向循环队列。

  2> expires:指定定时器到期的时间,这个时间被表示成自系统启动以来的时钟滴答计数(也即时钟节拍数)。当一个定时器的expires值小于或等于jiffies变量时,我们就说这个定时器已经超时或到期了。在初始化一个定时器后,通常把它的expires域设置成当前expires变量的当前值加上某个时间间隔值(以时钟滴答次数计 expires = jiffies +delay)。

  3> data: 初始化处理函数的参数值,若处理函数没有参数则可简单设置为0或任意其他数值。

  4> 函数指针function:指向一个可执行函数。当定时器到期时,内核就执行function所指定的函数。而data域则被内核用作function函数的调用参数。

(2)定时器的使用

  1> timer_list my_time 调用init_timer(&my_time)用来初始化一个定时器,初始化所有成员为空。

  2> 设定定时时器的到期节拍数 my_timer.expires = jiffies +delay ;该设置让定时器的触发时间设置为 激活定时器后的delay个节拍点

  3> 设定处理函数my_timer.function = 处理函数的名称 该设置设置定时器触发时处理的函数

  4> 设定参数 my_timer.data 初始化处理函数的参数值,若处理函数没有参数则可简单设置为0或任意其他数值

5> 激活定时器:即内核会开始定时  add_timer(&mytimer);

6> 使用完毕释放定时器 del_timer(&mytimer);

include <linux/module.h>    // for init_module() 
#include <linux/timer.h>
#define    SECONDS_COUNT 10

char modname[] = "trytimer";// module's name
struct timer_list timer;    // kernel object
unsigned int up_seconds;    // my timer data

void my_timer_function( unsigned long data )
{
    unsigned int    *data_ptr = (unsigned int*)data;
    *data_ptr += SECONDS_COUNT;
    printk( "  up for %u seconds \n", up_seconds );
    mod_timer( &timer, jiffies + HZ * SECONDS_COUNT );    
}

int init_module( void )
{
    printk( "<1>\nInstalling \'%s\' module\n", modname );
    
    // initialize our kernel timer
    init_timer( &timer );
    
    // setup our timer's structure fields
    timer.expires = jiffies + HZ * SECONDS_COUNT;
    timer.data = (unsigned int)&up_seconds;
    timer.function = my_timer_function;

    // add our timer to the kernel's timer queue
    add_timer( &timer );
    return    0;  // SUCCESS
}

void cleanup_module( void )
{
    int    status = del_timer_sync( &timer );
    printk( "<1>Removing \'%s\' module\n", modname );
    printk( "  status=%08X \n", status );
}

MODULE_LICENSE("GPL");

 

 

推荐阅读