序言
之前有写过一篇《Linux内核定时器》,明天来瞧瞧高精度定时器,它可以为我们提供毫秒级的定时精度linux内核定时器,以满足对精确时间有急迫需求的内核驱动。
高精度定时器编程
Linux版本:4.20
Linux内核中linux内核定时器,使用hrtimer来描述一个高精度定时器。
struct hrtimer {
struct timerqueue_node node;
ktime_t _softexpires; //定时器到期时间
enum hrtimer_restart (*function)(struct hrtimer *); //回调函数
struct hrtimer_clock_base *base;
u8 state;
u8 is_rel;
u8 is_soft;
};
(1)初始化高精度定时器
void hrtimer_init(struct hrtimer *timer,
clockid_t which_clock,
enum hrtimer_mode mode);
which_clock:
mode:
(2)启动高精度定时器
int hrtimer_start(struct hrtimer *timer, ktime_t time,
const enum hrtimer_mode mode);
按照time和mode参数的值估算hrtimer的超时时间。
(3)取消高精度定时器
int hrtimer_cancel(struct hrtimer *timer);
(4)设置超时反弹
timer.function = hr_callback;
初始化时须要对structhrtimer中的超时反弹函数进行形参。定时器一旦到期linux空间,function数组指定的反弹函数会被调用,该函数的返回值为一个枚举值,它决定了该hrtimer是否须要被重新激活。
enum hrtimer_restart {
HRTIMER_NORESTART, /* Timer is not restarted */
HRTIMER_RESTART, /* Timer must be restarted */
};
事例
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
unsigned int timer_count=0;
struct hrtimer hrtimer_test_timer;
ktime_t m_kt;
int value=2000;
static enum hrtimer_restart hrtimer_test_timer_poll(struct hrtimer *timer)
{
printk("================timer_count=%d ==============n",timer_count++);
//把hrtimer的到期时间推进一个tick周期
hrtimer_forward(timer, timer->base->get_time(), m_kt);
//重启高精度定时器
return HRTIMER_RESTART;
}
ssize_t hrtimer_test_write(struct file *f, const char __user *buf, size_t t, loff_t *len){
int i;
int ret = -1;
printk("hrtimer Debug buf:%x size:%dn",*buf,t);
if(*buf == '0'){
printk("hrtimer_startn");
m_kt=ktime_set(value / 1000, (value % 1000) * 1000000);
//启动高精度定时器
hrtimer_start(&hrtimer_test_timer,m_kt, HRTIMER_MODE_REL);
}
else if(*buf == '1'){
printk("hrtimer_canceln");
//取消定时器
hrtimer_cancel(&hrtimer_test_timer);
}
return t;
}
static const struct file_operations hrtimer_test_fops =
{
.owner = THIS_MODULE,
.write = hrtimer_test_write,
};
struct miscdevice hrtimer_test_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "hrtimer_test",
.fops = &hrtimer_test_fops,
};
static int __init hrtimer_test_init(void)
{
int ret;
//注册混杂设备
ret = misc_register(&hrtimer_test_dev);
//初始化高精度定时器
hrtimer_init(&hrtimer_test_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
//设置回调函数
hrtimer_test_timer.function = hrtimer_test_timer_poll;
return 0;
}
static void __exit hrtimer_test_exit(void)
{
misc_deregister(&hrtimer_test_dev);
}
module_init(hrtimer_test_init);
module_exit(hrtimer_test_exit);
MODULE_AUTHOR("hrtimer");
MODULE_LICENSE("GPL");
里面驱动通过应用层打开设备节点,之后写入‘0’来启动高精度定时器LINUX社区,写入‘1’来关掉高精度定时器。