前言
低分辨率定时器是用jiffies
来定时的,所以会受到HZ
影响,如果HZ
为200
,代表每秒种产生200
次中断,那一个jiffies
就需要5
毫秒,所以精度为5
毫秒。
如果精度需要达到纳秒级别,则需要使用高精度定时器hrtimer
。
相关接口
高分辨率定时器(hrtimer
)以ktime_t
来定义时间,精度可以达到纳秒级别,ktime_t
定义如下:
typedef s64 ktime_t;
可以用ktime_set
来初始化一个ktime
对象,常用方法如下:
ktime_t t = ktime_set(secs, nsecs);
高分辨率hrtimer
结构体定义如下:
struct hrtimer { struct timerqueue_node node; ktime_t _softexpires; enum hrtimer_restart (*function)(struct hrtimer *); struct hrtimer_clock_base *base; unsigned long state; ...... }; enum hrtimer_restart { HRTIMER_NORESTART, /* Timer is not restarted */ HRTIMER_RESTART, /* Timer must be restarted */ };
struct hrtimer
结构体中最主要的成员就是回调函数function
,回调函数的返回值可以为HRTIMER_NORESTART
或HRTIMER_RESTART
。HRTIMER_NORESTART
代表不需要重启定时器,HRTIMER_RESTART
代表需要重启定时器。
最常用的接口如下:
hrtimer_init(struct hrtimer *timer, clockid_t clock_id , enum hrtimer_mode mode) hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode) hrtimer_forward_now(struct hrtimer *timer,ktime_t interval) hrtimer_cancel(struct hrtimer *timer)
hrtimer_init
:初始化 struct hrtimer
结构对象。 clockid_t
是时钟的类型, 种类很多,常见的有四种:
CLOCK_REALTIME
:系统实时时间。CLOCK_MONOTONIC
:从系统启动时开始计时,自系统开机以来的单调递增时间CLOCK_PROCESS_CPUTIME_ID
:本进程到当前代码系统CPU花费的时间,包含该进程下的所有线程。CLOCK_THREAD_CPUTIME_ID
:本线程到当前代码系统CPU花费的时间。
mode
是时间的模式,可以是 HRTIMER_MODE_ABS
, 表示绝对时间, 也可以是 HRTIMER_MODE_REL,
表 示相对时间。hrtimer_start
:启动定时器。 tim
是设定的到期时间, mode
和hrtimer_init
中的 mode
参数含义相同。hrtimer_forward_now
: 修改到期时间为从现在开始之后的 interval
时间。hrtimer_cancel
:取消定时器。
使用示例
单次定时
加载驱动一秒后输出“hrtimer handler
”:
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/ktime.h> #include <linux/hrtimer.h> static struct hrtimer timer; static enum hrtimer_restart timer_handler(struct hrtimer *timer ) { printk("hrtimer handler\n"); return HRTIMER_NORESTART; } static int __init my_init(void) { ktime_t tim; hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); timer.function = timer_handler; tim = ktime_set(1,0); //1s hrtimer_start(&timer,tim,HRTIMER_MODE_REL); return 0; } static void __exit my_exit(void) { printk("%s enter\n", __func__); hrtimer_cancel(&timer); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL");
循环定时
循环定时可以在回调函数中调用hrtimer_forward_now()
重新设置定时时间,然后将返回值设置为HRTIMER_RESTART
代表重启定时器,就可以做到循环定时的效果。
每隔一秒输出“hrtimer handler
”:
#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/ktime.h> #include <linux/hrtimer.h> static struct hrtimer timer; static enum hrtimer_restart timer_handler(struct hrtimer *timer ) { printk("hrtimer handler\n"); hrtimer_forward_now(timer, ktime_set(1,0));//重新设置定时时间 return HRTIMER_RESTART;//重启定时器 } static int __init my_init(void) { ktime_t tim; hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); timer.function = timer_handler; tim = ktime_set(1,0); //1 s hrtimer_start(&timer,tim,HRTIMER_MODE_REL); return 0; } static void __exit my_exit(void) { printk("%s enter\n", __func__); hrtimer_cancel(&timer); } module_init(my_init); module_exit(my_exit); MODULE_LICENSE("GPL");
end
往期推荐