1、初如化调用过程
1、asmlinkage void __init start_kernel(void)
2、void __init init_timers(void)
3、void open_softirq(int nr, void (*action)(struct softirq_action *))
4、static void run_timer_softirq(struct softirq_action *h)
5、static inline void __run_timers(struct tvec_base *base)
6、static 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 <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/irqreturn.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <linux/timer.h>
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