timer(内核定时器)函数及其用法(初级)
写在最前
- 本文有demo版本,见:timer实例,可以结合代码一起看本文。
- 由于timer的函数接口在不同的内核版本大有不同,所以导致某些函数在某些版本不适用,本文所使用的代码版本为linux-5.10.60,其他版本的内核需要检查下函数接口。
- 从timer框架层面来说,没有太大变化,整体的设计思想要是弄明白了,timer也就完全够用了。
- 本文是timer的初级文章,只介绍关键的数据结构和函数,不做深入探究,在后续的中级文章中,我们会去探究timer硬件层面的设计。
timer原理(初级)
linux kernel 提供了内核定时器机制,其核心是由硬件产生中断来追踪时间流动情况,定时器到期(expires)后,会执行指定的某个具体的函数(function)。
timer代码分析
再次说明:下面的代码是基于linux-5.10.60,可能与你正在使用的内核有一定的差别,一切以你正在使用的内核为准,本文只做引导分析,让你知道如何使用timer。
关键数据结构
1 | /** |
关键函数
- 函数使用流程:
初始化(初始化函数中)->添加到内核timer中(初始化函数中)->重新添加到内核timer中(回调函数中)->注销(注销函数中) - 函数的实际用法可以参考文章前面的链接,也就是:timer实例
- 具体的函数如下
初始化
1 | /** |
调用timer_setup后还要进行如下赋值操作:
timer.expires = xxx;
在旧的版本里面用的是init_timer(timer)接口,所以旧版本除了上面还有额外的赋值操作:
timer.data = 0;
timer.function = funcyyy;
注册/开启 timer
timer要生效,还要必须被连接到内核专用的链表中。
1 | /* @timer: the timer in question 定时器名 */ |
重新注册(修改)timer
定时器在到期之后,如何不重新注册(修改)到内核,那么timer就不会再接着执行,这种有点类似“一次性”,所以我们要修改到期时间,让其接着运行(类似望梅止渴,就是让定时器程序一直看不到终点(到期时间))。
1 | /** |
注销timer
在模块退出或者不再使用timer时,要将timer注销。
1 | /* @timer: the timer in question 定时器名 */ |
这里要说明一下,注销timer有两个,我们一般用del_timer_sync这个函数就好了。
其他函数
当前还有一些其他的函数没有做介绍,因为一般情况下用不上,所以放到后续的中级文章中再做介绍。