linux 内核定时器

1、初如化调用过程

1、asmlinkage void __init start_kernel(void)

2void __init init_timers(void)

3void open_softirq(int nr, void (*action)(struct softirq_action *))

4static void run_timer_softirq(struct softirq_action *h)

5static inline void __run_timers(struct tvec_base *base)

6static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),

2 timer_list 结构体

在linux 的内核中,timer_list结构体的实例对应着一个定时器,timer_list 定义在:include/linux/timer.h

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;  //每个CPU管理的tvec_base结构

    void (*function)(unsigned long); //回调函数
    unsigned long data; //传入回调函数的参数

    int slack;

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

3 静态初始化

#define TIMER_INITIALIZER(_function, _expires, _data) {     \
        .entry = { .prev = TIMER_ENTRY_STATIC },    \
        .function = (_function),            \
        .expires = (_expires),              \
        .data = (_data),                \
        .base = &boot_tvec_bases,           \
        .slack = -1,                    \
        __TIMER_LOCKDEP_MAP_INITIALIZER(        \
            __FILE__ ":" __stringify(__LINE__)) \
    }

#define DEFINE_TIMER(_name, _function, _expires, _data)     \
    struct timer_list _name =               \
        TIMER_INITIALIZER(_function, _expires, _data)

4 增加定时器

extern void add_timer(struct timer_list *timer);

上述函数将timer注册进内核,加入到内核的动态定时器链表中,一般在驱动的__init函数中来调用。如:probe

5 删除定时器

int del_timer(struct timer_list *timer)

上述函数用于删除定时器,一般用于__exit函数内。

5 修改定时器的过期时间

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

6 应用简单例子

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

struct timer_list timer;
void timer_handler(unsigned long data)
 {
    printk(KERN_INFO"timer pending:%d\n", timer_pending(&timer));
    mod_timer(&timer, jiffies+msecs_to_jiffies(10000)); //下次软中断的过期时间
    printk(KERN_INFO"jiffies:%ld, data:%ld\n", jiffies, data);
}

static void  __init timerTest_init(void)
{
    init_timer(&timer);
    timer.data = 100; //传参
    timer.function = timer_handler; //回调函数
    timer.expires = jiffies + HZ; //过期时间
    add_timer(&timer);

}

static void __exit timerTest_exit()
{
        del_timer(&timer);
}

module_init(timerTest_init);
module_exit(timerTest_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Joey");
MODULE_DESCRIPTION("kernel timer test");

参考

https://blog.csdn.net/droidphone/article/details/8051405
https://blog.csdn.net/yao_guet/article/details/49470137

你可能感兴趣的:(Linux)