#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/slab.h>
struct timer_desc {
struct timer_list timer;
struct device dev;
unsigned long jiffies_before;
unsigned long jiffies_after;
};
void timer_callback(struct timer_list *timer)
{
struct timer_desc *timer_dev = container_of(timer, struct timer_desc, timer);
if (!timer_dev) {
printk(KERN_ALERT "%s timer desc address error\n", __func__);
return;
}
timer_dev->jiffies_after = get_jiffies_64();
printk(KERN_ALERT "HZ = %ld\n", HZ);
printk(KERN_ALERT "jiffies_after - jiffies_before = %ld\n", timer_dev->jiffies_after - timer_dev->jiffies_before);
}
static int timer_init(void)
{
struct timer_desc *timer_dev = NULL;
printk(KERN_ALERT "Hello timer Test\n");
timer_dev = kmalloc(sizeof(struct timer_desc), GFP_KERNEL);
if (!timer_dev) {
printk(KERN_ALERT "%s kmalloc fail\n", __func__);
return -ENOMEM;
}
dev_set_drvdata(&timer_dev->dev, timer_dev);
timer_dev->timer.expires = jiffies + msecs_to_jiffies(2000);
timer_setup(&timer_dev->timer, timer_callback, 0);
timer_dev->jiffies_before = get_jiffies_64();
add_timer(&timer_dev->timer);
printk(KERN_ALERT "timer init OK!");
return 0;
}
static void timer_exit(void)
{
printk(KERN_ALERT "GoodBye timer Test\n");
}
module_init(timer_init);
module_exit(timer_exit);
测试运行结果如下:
当前Linux版本使用的是Kernel-5.10,HZ是300,代码中我需要延迟2sec,最终log打印的结果是654,按照HZ=300计算,当前一个jiffies是1/300sec,也就是3.33~ms,654*3.33~约等于2180ms。
对比我设置的2000ms,低精度定时器误差大概在180ms,也就代表如果对精度要求比较高的设备,建议还是不要使用低精度定时器,毕竟误差太大。(以上是个人学习的见解,有问题还请大佬指出,感谢)
\par \cf0\highlight0 [ 6.624769][ C6] HZ = 300\cf1\highlight2
\par \cf0\highlight0 [ 6.624779][ C6] jiffies_after - jiffies_before = 654\cf1\highlight2
低分辨率定时器是用jiffies
来定时的,所以会受到HZ
影响,如果HZ
为200
,代表每秒种产生200
次中断,那一个jiffies
就需要5
毫秒,所以精度为5
毫秒。