内核定时器init_timer与mod_timer的使用
内核定时器为了可以在某个时间点上调用函数内核定时器的调度函数运行过一次后就不会再被运行了,但是在del_timer销毁定时之前,可以使用add_timer(注册)或者mod_timer(修改)重新调用一般重新调用的场景有1 通过在被调度的函数中重新调度自己来周期运行。2 通过某个中断服务函数中重新唤起调用这样就可以实现while(1)循环的功能,可以用于轮询设备等工作需求。这里被调度的函数是异步执
·
内核定时器为了可以在某个时间点上调用函数
内核定时器的调度函数运行过一次后就不会再被运行了,
但是在del_timer销毁定时之前,可以使用add_timer(注册)或者mod_timer(修改)重新调用
一般重新调用的场景有
1 通过在被调度的函数中重新调度自己来周期运行。
2 通过某个中断服务函数中重新唤起调用
这样就可以实现while(1)循环的功能,可以用于轮询设备等工作需求。
这里被调度的函数是异步执行的。
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/time.h>
#include <linux/timer.h>
static struct timer_list tm;
struct timeval oldtv;
static int counter;
void callback(unsigned long arg){
#if 0
struct timeval tv;
char *strp = (char*)arg;
do_gettimeofday(&tv);
printk("[%s](%s)%ld\n", __func__,strp,
tv.tv_sec);
oldtv = tv;
tm.expires = jiffies+1*HZ;
counter++;
if(counter < 5){
add_timer(&tm);
}
#endif
#if 1
struct timeval tv;
char *strp = (char*)arg;
do_gettimeofday(&tv);
printk("[%s](%s)%ld\n", __func__,strp,
tv.tv_sec);
counter++;
if(counter < 5){
mod_timer(&tm, jiffies+1*HZ);
}
#endif
}
static int __init demo_timer_init(void){
printk(KERN_INFO "[%s] START.\n", __func__);
#if 0
init_timer(&tm);
do_gettimeofday(&oldtv);
tm.function= callback;
tm.data = (unsigned long)"hello world";
tm.expires = jiffies+1*HZ;
add_timer(&tm);
#endif
#if 1
init_timer(&tm);
do_gettimeofday(&oldtv);
tm.expires = jiffies+1*HZ;
setup_timer(&tm, callback, (unsigned long)"Hello World");
add_timer(&tm);
#endif
return 0;
}
static void __exit demo_timer_exit(void){
printk(KERN_INFO "[%s] EXIT.\n", __func__);
del_timer(&tm);
}
module_init(demo_timer_init);
module_exit(demo_timer_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mr.linux.debug");
MODULE_DESCRIPTION("Demo timer for kernel module");
以上使用中可以看出
setup_timer可以直接传入tm.function和tm.data,
替代单独给function和data赋值的过程
mod_timer 和 add_timer 使用这两者都可以实现重复调用自身。
运行结果
$ insmod demo_init_timer.ko
[demo_timer_init] START.
[callback](Hello World)1591010973
[callback](Hello World)1591010974
[callback](Hello World)1591010975
[callback](Hello World)1591010976
[callback](Hello World)1591010977
$ rmmod demo_init_timer
[demo_timer_exit] EXIT.
函数使用说明
add_timer | 把定时器注册连接到内核专门的链表中(最终也是通过调用mod_timer实现) |
mod_timer | 重新注册定时器到内核专门的链表中(不管定时器函数是否被运行过) |
del_timer | 注销一个定时器(它不会等待其他CPU上的调度结束,在单核处理器上,可以直接使用) |
del_timer_sync | 注销一个定时器(用于SMP多核系统,会进入休眠等待其他CPU上的调度结束) |
timer_pending | 判断一个定时器是否被添加到了内核链表中以等待被调度运行 |
setup_timer | 建个定时器 主要负责给 function 和 data 进行赋值工作 |
由于 add_timer 最终也是调用到 mod_timer 接口实现定时器的作用,所以需要重新调用时,
也可以使用 add_timer 进行配置定时器,以使该定时器进行计时重新调度的流程内。
更多推荐
已为社区贡献4条内容
所有评论(0)