Linux 定时器(内核态)
2015-11-24 17:58
501 查看
本文参考文档
头文件:
setup_timer(&test_timer, timer_print, 1234);
test_timer.expires = jiffies + 5 * HZ;
add_timer(&test_timer);
很容易可以看出,这个函数只是简单的往test_timer这个数据结构中填充一些内容。其实在add_timer这个函数执行之前,test_timer结构里的数据都可以随意更改。其中1234是随手写的一个数据,将会作为参数传入触发器的function中(在这里是timer_print)。其实这个data参数可以通过强转传入指针,例如:
在这句代码中expires成员是定时器,设定了触发函数的时间。HZ代表的是系统每一秒的滴答时钟计算数,可以从config中查到(shell命令,本人内核是3.7.10)。
其中jiffies是LINUX中定义的一个全局变量,记录的是从系统启动到当前使用的时间。假如要计算系统已经运行的时间,可以简单通过以下计算获得:
这一句的意思是将定时器设置为5秒后触发(由于程序运行本身需要消耗一些时间,因此并不是绝对精确的。假如在这句语句定义后调用msleep(1000)睡眠3秒,那么可能定时器就会在add_timer之后,只剩下不足4秒的时间了)。
4. 添加定时器
Linux内核中定时器的实现涉及到一个双向链表,这个链表中的每一个节点都是
类型。初始化的的简单调用过程,从kernel/init/main.c到kernel/kernel/timer.c
更深一层的内容原理请查看参考文档
头文件以及简单使用流程
头文件: #include <linux/timer.h>
简单使用流程:
struct timer_list test_timer;setup_timer(&test_timer, timer_print, 1234);
test_timer.expires = jiffies + 5 * HZ;
add_timer(&test_timer);
说明
1. 定义定时器 test_timer
值得注意的是,定义定时器时注意定时器为全局变量或者是通过kmalloc从堆中申请到的内存。否则定时器会在函数生命周期结束后被销毁,导致出现错误。
2. setup_timer初始化test_timer
首先来看一下setup_timer的源代码#define setup_timer(timer, fn, data) \ __setup_timer((timer), (fn), (data), 0) #define __setup_timer(_timer, _fn, _data, _flags) \ do { 4000 \ __init_timer((_timer), (_flags)); \ (_timer)->function = (_fn); \ (_timer)->data = (_data); \ } while (0)
很容易可以看出,这个函数只是简单的往test_timer这个数据结构中填充一些内容。其实在add_timer这个函数执行之前,test_timer结构里的数据都可以随意更改。其中1234是随手写的一个数据,将会作为参数传入触发器的function中(在这里是timer_print)。其实这个data参数可以通过强转传入指针,例如:
(unsigned long)&test_timer;
3. 设定时间
test_timer.expires = jiffies + 5 * HZ;
在这句代码中expires成员是定时器,设定了触发函数的时间。HZ代表的是系统每一秒的滴答时钟计算数,可以从config中查到(shell命令,本人内核是3.7.10)。
#cat /boot/config-3.7.10 |grep CONFIG_HZ
其中jiffies是LINUX中定义的一个全局变量,记录的是从系统启动到当前使用的时间。假如要计算系统已经运行的时间,可以简单通过以下计算获得:
jiffies / HZ
这一句的意思是将定时器设置为5秒后触发(由于程序运行本身需要消耗一些时间,因此并不是绝对精确的。假如在这句语句定义后调用msleep(1000)睡眠3秒,那么可能定时器就会在add_timer之后,只剩下不足4秒的时间了)。
4. 添加定时器 add_timer(&test_timer);
Linux内核中定时器的实现涉及到一个双向链表,这个链表中的每一个节点都是struct timer_list
类型。初始化的的简单调用过程,从kernel/init/main.c到kernel/kernel/timer.c
start_kernel()->init_timers()
更深一层的内容原理请查看参考文档
代码
源代码 test_timer.c
#include <linux/module.h> #include <linux/timer.h> struct timer_list test_timer; /*static DEFINE_TIMER(test_timer, test_print, 0, 0)*/ void timer_print(unsigned long data) { printk(KERN_INFO "timer_printk %ld\n", data); return; } static int __init test_init(void) { printk(KERN_INFO "test_timer\n"); setup_timer(&test_timer, timer_print, 900); test_timer.expires = jiffies + 5*HZ; add_timer(&test_timer); return 0; } static void test_exit(void) { printk(KERN_INFO "test_exit\n"); del_timer(&test_timer); return; } module_init(test_init); module_exit(test_exit); MODULE_LICENSE("GPL");
Makefile
ccflags-y += -O0 -g obj-m := test_timer.o KDIR :=/lib/modules/$(shell uname -r)/build PWD :=$(shell pwd) default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean
相关文章推荐
- Linux socket 初步
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断
- 谁是桌面王者?Win PK Linux三大镇山之宝