Linux内核定时器子系统比较复杂,这里先给出动态定时器的使用。
动态定时器的使用很简单,你只需要执行一些初始化工作,设置一个超时事件,指定超时发生后执行的函数,然后激活定时器就可以了。指定的函数将在定时器到期时执行。动态定时器并不像系统定时器那样周期性的运行,它在超时后就自动撤销,之后还可以继续创建,因此这种定时器才被称为动态定时器。
动态定时器可以不断的被创建和销毁,而且它的运行次数也不受限制,因此在内核中应用得非常普遍。
定时器由结构timer_list表示,定义在文件<linux/timer.h>中
struct timer_list {
struct list_head entry; //定时器链表的入口
unsigned long expires; //单位与jiffies相同,指超时时间
void (*function) (unsigned long); //定时器处理函数
unsigned long data; //传给处理函数的参数
struct tvec_t_base_s *base; //定时器内部值,用户不需要使用
}
1.创建定时器需要先定义: struct timer_list m_timer;
2.使用辅助函数来初始化定时器内部值:init_timer(&m_timer);
3.填充timer结构中需要的值:
m_timer.expires = jiffies + delay; //定时器超时值
m_timer.function = timer_handler; //定时器处理函数
m_timer.data = 0; //定时器处理函数参数
定时器处理函数原型:void timer_handler(unsigned long data);
其中多个动态定时器可以复用一个定时器处理函数,处理内部可以使用data对不同定时器做区分。
4.最后需要激活定时器:add_timer(&m_timer);
这里需要注意,动态定时器是用软件实现的,在执行定时器中断函数时可能会有一定的延时,因此不能使用动态定时器来实现任何硬实时要求。
5.同时还可以通过mod_timer(&m_timer, jiffies + new_delay); 来实现修改已激活的定时器超时时间,并激活该定时器。
注意:定时器已超时,会自动被删除就不要再使用用mod_timer;一个定时器处理函数正在被其它处理器运行,这时候要等运行完才能删除,所以可以使用del_timer_sysc(&m_timer);来删除工作。
到此为止,timer的用法介绍完了,使用起来也比较简单。从timer_list结构来看,这是一个用软件链表来维护的定时器,下面研究一下它的实现。