20_内核定时器的使用

了解内核定时器及其使用

Posted by Jerry Chen on August 13, 2019

了解内容

内核定时器知识

宏定义:HZ决定时钟中断的频率,通过宏CONFIG_HZ设置,范围是100~1000;

全局变量:jiffies(节拍数,内核定时器产生中断次数),系统启动时该变量初始为0,故jiffies/HZ即内核启动的秒数。

开始

定时器的使用

1、定义定时器结构体timer_list;

1
static struct timer_list my_timer;

2、结构体内容添加;

定义一个定时器时间到了的处理函数(中断触发该函数)

1
2
3
4
static void timer_func(unsigned long data)
{
	printk("%s ,secs = %ld!\n",(char *)data,jiffies/HZ);
}

添加超时时间,处理函数和处理函数的传参

1
2
3
4
init_timer(&my_timer); /*初始化my_timer的部分内部成员*/
my_timer.expires = jiffies + 5*HZ; //当前时间(jiffies)的后5秒(5*HZ)
my_timer.function = timer_func; //指定定时器处理函数
my_timer.data = (unsigned long)123; //设定定时器处理函数的传参,甚至可传字符串

3、激活定时器;

1
2
3
4
5
6
//方式一:添加即启动定时器
add_timer(&my_timer);
//方式二:改变超时时间
//如果目前没超时,就会更新时间;
//如果目前已触发超时,就相当于更新时间并再次启动一次
mod_timer(&my_timer,jiffies + 10*HZ);

例程

驱动例程

timer_demo.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("jerry");

static struct timer_list my_timer;

static void timer_func(unsigned long data)
{
	printk("%s ,secs = %ld!\n",(char *)data,jiffies/HZ);
	//方式二:改变超时时间
	//如果目前没超时,就会更新时间;
	//如果目前已触发超时,就相当于更新时间并再次启动一次
	mod_timer(&my_timer,jiffies + 5*HZ);
}

static int __init demo_init(void){
	init_timer(&my_timer); /*初始化my_timer的部分内部成员*/
	my_timer.expires = jiffies + 2*HZ; //当前时间(jiffies)的后2秒(2*HZ)
	my_timer.function = timer_func; //指定定时器处理函数
	my_timer.data = (unsigned long)"haha"; //设定定时器处理函数的传参,这里指针强转
	
	//方式一:添加即启动定时器
	add_timer(&my_timer);
	printk(KERN_EMERG "mytimer start!\n");
	
	return 0;
}
static void __exit demo_exit(void){
	printk(KERN_EMERG "mytimer exit!\n");
	del_timer(&my_timer);
	return;
}

module_init(demo_init);
module_exit(demo_exit);
测试结果

编写简单Makefile:参考这里

编译生成模块后,拷贝到开发板中:

  • 加载模块后第一次2s触发定时器中断,后面每5s触发一次。