1.内核时间管理
1)设置硬件定时器提供的时钟源频率,系统采用定时中断来计时。
在内核图形化配置界面的Kernel Features>Timer frequency可以配置。或者修改内核.config文件下的CONFIG_HZ项也可以。
高节拍率:时间精度高,但是中断更频繁,加重系统负担。
2)jiffies绕回,与ms,us等转换,代码超时判断:
unsigned long timeout;
timeout = jiffies + (2 * HZ); /* 超时的时间点 */
/*************************************
具体的代码
************************************/
/* 判断有没有超时 */
if(time_before(jiffies, timeout)) {
/* 超时未发生 */
} else {
/* 超时发生 */
}
3)内核定时器
Linux内核使用timer_list结构体表示内核定时器。使用时需要提供超时时间和定时处理函数,要注意的是内核定时器不会周期性运行,所以需要在处理函数中重新开启定时器才可以周期定时。
struct timer_list {
struct list_head entry;
unsigned long expires; /* 定时器超时时间,单位是节拍数 */
struct tvec_base *base;
void (*function)(unsigned long); /* 定时处理函数 */
unsigned long data; /* 要传递给 function 函数的参数 */
int slack;
};
初始化定时器函数:
①init_timer:初始化timer_list类型变量。
void init_timer(struct timer_list *timer)
/*timer是要初始化的定时器*/
②add_timer:向内核注册定时器。然后定时器才会激活,开始运行。
void add_timer(struct timer_list *timer)
③del_timer:删除一个定时器。需要等待其它处理器的定时处理函数退出。
int del_timer(struct timer_list * timer)
/*返回值:0代表定时器还没激活,1代表定时器已激活*/
④del_timer_sync:删除一个定时器(同步版)。不能用在中断中。
int del_timer_sync(struct timer_list *timer)
/*返回值:0代表定时器还没激活,1代表定时器已激活*/
⑤mod_timer:修改定时值,如果定时器还没激活,会进行激活。
int mod_timer(struct timer_list *timer, unsigned long expires)
/*para:要修改的定时器,修改后的超时时间*/
/*返回值:0代表调用该函数前定时器还没激活,1代表定时器已激活*/
一般使用流程:
struct timer_list timer; /*定义定时器*/
/*定时处理函数*/
void function(unsigned long arg) {
/*定时器处理代码*/
/*如果需要周期定时需要使用mod_timer*/
mod_timer(&dev->timertest, jiffies + msecs_to_jiffies(2000));
}
/* 初始化函数 */
void init(void) {
init_timer(&timer); /* 初始化定时器 */
timer.function = function; /* 设置定时处理函数 */
timer.expires=jffies + msecs_to_jiffies(2000); /* 超时时间 2 秒 */
timer.data = (unsigned long)&dev; /* 将设备结构体作为参数传给超时处理函数 */
add_timer(&timer); /* 启动定时器 */
}
/* 退出函数 */
void exit(void) {
del_timer(&timer); /* 删除定时器 */
/* 或者使用 */
del_timer_sync(&timer);
}