Linux Kernel 普通定时器使用示例
本文介绍如何在 Linux 内核模块中使用普通定时器(timer_list
结构)。
示例代码
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>MODULE_LICENSE("GPL");
MODULE_AUTHOR("Example Author");
MODULE_DESCRIPTION("A simple Linux kernel timer example");static struct timer_list my_timer;// 定时器回调函数
static void my_timer_callback(struct timer_list *t)
{printk(KERN_INFO "Timer callback function called at %ld jiffies\n", jiffies);// 重新设置定时器(如果需要循环执行)mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000)); // 再次设置1秒后触发
}// 模块加载时初始化定时器
static int __init my_timer_init(void)
{printk(KERN_INFO "Initializing timer module\n");// 初始化定时器timer_setup(&my_timer, my_timer_callback, 0);// 设置定时器初始触发时间mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000)); // 1秒后触发return 0;
}// 模块卸载时清理定时器
static void __exit my_timer_exit(void)
{printk(KERN_INFO "Exiting timer module\n");// 删除定时器del_timer(&my_timer);
}module_init(my_timer_init);
module_exit(my_timer_exit);
说明
定时器初始化
- 使用
timer_setup
初始化timer_list
。 - 参数说明:
- 第一个参数是
struct timer_list
的指针。 - 第二个参数是回调函数。
- 第三个参数是标志,通常为 0。
- 第一个参数是
设置定时器
- 使用
mod_timer
函数设置定时器的触发时间。 - 示例:
mod_timer(&my_timer, jiffies + msecs_to_jiffies(delay))
,其中delay
是以毫秒为单位的延迟。
删除定时器
- 在模块卸载时,使用
del_timer
确保定时器被清除,避免内核出现未知行为。
回调函数
- 定时器触发时,内核调用指定的回调函数。
- 回调函数运行在软中断上下文中,不能进行阻塞操作。
编译和加载
创建 Makefile
obj-m += timer_example.o
编译模块
make -C /lib/modules/$(uname -r)/build M=$(pwd) modules
加载模块
sudo insmod timer_example.ko
查看日志
dmesg
卸载模块
sudo rmmod timer_example
输出示例
加载模块后,日志会显示类似如下内容:
[12345.678901] Initializing timer module
[12346.678902] Timer callback function called at 123456 jiffies
[12347.678903] Timer callback function called at 123457 jiffies
[12348.678904] Timer callback function called at 123458 jiffies
...
[12349.678905] Exiting timer module
注意事项
- 定时器的精度依赖于内核的
HZ
值(通常为 250 或 1000)。 - 在模块卸载前务必删除定时器,避免未决的回调函数访问非法内存。