76 模块编程之高精度定时器
前言
这个 主要是 最开始的时候了解驱动的时候, 看到的一系列的 case, 这里 来大致剖析一下 相关的道理
这些模块 是怎么和内核交互的, 内核的这些业务是怎么实现的
这里主要是一个模块创建了一个 hrtimer, 然后 0.3秒后执行, 然后 在执行的过程中递归加入当前任务到下一次队列
然后这里主要是设计了 模块来调用 timer 的相关系统函数, 以及 kthread 的相关知识
测试用例
测试模块如下, 模块主要是来自于 某git仓库, 这里未记录信息, 感谢原作者
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>#define MS_TO_NS(x) (x * 1E6L)static struct hrtimer hr_timer;
static int hr_timer_isr_count = 0;enum hrtimer_restart my_hrtimer_callback( struct hrtimer *timer )
{pr_info( "my_hrtimer_callback called (%ld).\n", jiffies );hr_timer_isr_count++;if(hr_timer_isr_count < 5){hrtimer_restart(&hr_timer);return HRTIMER_RESTART;}return HRTIMER_NORESTART;
}static int __init hr_timer_init(void)
{ktime_t ktime;unsigned long delay_in_ms = 200L;pr_info("HR Timer module installing\n");/** * ktime = ktime_set(0, 200 * 1000 * 1000);* * 200 ms = 10 * 1000 * 1000 ns* */ktime = ktime_set( 0, MS_TO_NS(delay_in_ms) );hrtimer_init( &hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );hr_timer.function = &my_hrtimer_callback;pr_info( "Starting timer to fire in %ldms (%ld)\n", \delay_in_ms, jiffies );hrtimer_start( &hr_timer, ktime, HRTIMER_MODE_REL );return 0;
}static void __exit hr_timer_exit(void)
{int ret;ret = hrtimer_cancel( &hr_timer );if (ret)pr_info("The timer was still in use...\n");hr_timer_isr_count = 0;pr_info("HR Timer module uninstalling\n");return;
}module_init(hr_timer_init);
module_exit(hr_timer_exit);MODULE_AUTHOR("e665106");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("A simple hr-timer Module");
MODULE_ALIAS("a simplest module");
hrtimer_init 和 hrtimer_start
hrtimer_init 中主要是更新了 timer->base, timer->node
然后在 模块的外层 设置了 timer->function
hrtimer_start 主要是讲给定的 timer 放入 base
hrtimer_restart
这是 module_init 中的第一次 hrtimer_start 的情况如下
expires 为 1598515692970, 待执行函数为 my_hrtimer_callback
然后 这里是 my_hrtimer_callback 中调用 hrtimer_restart 到 hrtimer_start_range_ns 的情况如下
可以看到的是 expires, function 均是一样, 是第一次调用的过期时间
因此 这里 hrtimer_restart 的处理是 将原始 hrtimer 从队列中删除, 然后重新加进来
hrtimer_restart 的实现如下
可以看到的是 以绝对时间执行, 过期时间为 timer 本身的 过期时间, delta 有一些 稍许的计算调整
hr_timer 是在哪里执行的?
根据 timer 来确定, 这里执行的 timer 是我们上面的 my_hrtimer_callback
完