Timer类型
- 低分辨率时钟: 基于Linux内核配置的HZ周期性触发,可以通过硬件或者高分辨率时钟实现
- 高分辨率始终: 基于时钟硬件,可以根据设定的时间出发,精度取决于硬件
低分辨率时钟
- HZ配置
- 多数设置为250
- 较高的HZ是系统有更好的交互型和响应速度,但是开销会随之增大
- List item
- Timer数据结构
struct timer_list {
struct list_head entry;
unsigned long expires;
void (*function)(unsigned long);
unsigned long data;
struct tvec_t_base_s *base;
}
- function : 超时回调函数
- data : 回调函数参数
- expires : 定时器超时时间
- base : 基元素,每个处理器一个,其中的定时器按时间排序
typedef struct tvec_s {
struct list_head vec[TVN_SIZE];
} tvec_t
typedef struct tvec_root_s {
struct list_head vec[TVR_SIZE]'
} tvec_root_t
struct tvec_t_base_s {
unsigned long timer_jiffies;
tvec_root_t tv1;
tvec_t tv2;
tvec_t tv3;
tvec_t tv4;
tvec_t tv5;
}
-
tv1 : 第0-255个时钟中期的到期时间
-
tv2 : 256 - 2 14 2^{14} 214 -1
-
tv3 : 2 14 2^{14} 214 - 2 20 2^{20} 220 -1
-
tv4 : 2 20 2^{20} 220 - 2 26 2^{26} 226 -1
-
tv5 : 2 26 2^{26} 226 - 2 32 2^{32} 232 -1
==> 各个组(tvx)都有一个索引, tv1的索引项指向的数组元素,是下一个时钟周期后要执行的定时器,每个时钟周期后,取出数组中的链表执行后,将索引项加1,所有索引处理完成后,用tv2中第一个数组的所有定时器补充到第一组,其他各组的处理方法类似,只是索引的追加时机不同。 -
Timer注册
static inline void add_timer(struct timer_list *timer)
-
将定时器追加到对应CPU的tvec_t_base_t相关Timer链表中
-
处理流程
-
低分辨率Timer中断处理流程
- 软中断处理流程