时间的一个重要概念jiffies: 内核的一个全局变量,jiffies每隔一个固定时间就会增加1,
这个固定间隔由定时器中断来实现
每秒钟产生多少个定时器中断,由在<linux/param.h>中定义的宏HZ确定
HZ是一个宏
在编译内核时,这个__KERNEL__是编译选项
#ifdef __KERNEL__
#define HZ CONFIG_HZ
#define USER_HZ HZ
#else
#define HZ 1024
#endif
#define CONFIG_HZ 200
对于当前的平台
jiffies是每隔5ms会加一
使用jiffies实现一个精确的定时
内核定时器的使用
1. 依赖的头文件<linux/timer.h>
2. 定义这个结构体
struct timer_list mytimer
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;
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. 初始化这个定时器
void init_timer(struct timer_list * timer);
mytimer.function = my_function; //系统jiffies和expires相等时,会调用定时器中断处理函数
mytimer.expires = jiffies + 1*HZ(1s); //jiffies 的值加上200后,经过的时间是
经过多久 系统的jiffies和expires相等
4. 安装定时器到内核中,定时器已经开始工作
void add_timer(struct timer_list * timer);
5. 从内核中卸载这个定时器
int del_timer(struct timer_list * timer);
6. 定时器的中断处理函数
void (*function)(unsigned long); // 定时器的处理函数
void mytimer_function(unsigned long count)
7. 修改定时的时间
mod_timer()
extern int mod_timer(struct timer_list *timer, unsigned long expires);
内核的延时机制:
1. 短延时和长延时的划分: 延时时间> jiffies 的时间间隔 为长延时
延时时间< jiffies 的时间间隔 为短延时
2. 短延时的函数
忙等待: 会一直占用cpu的资源
纳秒级延时: ndelay(unsigned long nsecs)
微妙级延时: udelay(unsigned long usecs)
毫秒级延时: mdelay()
#define mdelay(n) udelay((n) * 1000)
带睡眠机制的延时:
void msleep(unsigned int msecs)
3. 长延时的函数
time_before(jiffies, new_jiffies);
time_after(new_jiffies, jiffies)