linux 之定时器

Table of Contents

定时器简介

1、HZ

2、jiffies

3、tick (节拍)

定时器编程步骤

1、定时器初始化

2、添加定时器到内核并启动定时器

3、编写定时处理函数

4、其他操作

参考代码


 

定时器简介

1、HZ

系统定时器频率,与体系结构相关,系统启动根据HZ设置定时器硬件

HZ = (100) (ARM 平台)

2、jiffies

内核全局变量,32位,unsigned long,记录自开机依赖发生了多少次时钟中断,每发生一次,jiffies+1

系统时间以秒为单位就等于jiffies/HZ

以秒为单位的时间转化为jiffies:  Seconds*HZ

msecs_to_jiffies()毫秒转jiffies

3、tick (节拍)

它是HZ的倒数,也就是每发生一次硬件定时器中断的时间间隔 ,如HZ为100 ,tick为10毫秒

定时器编程步骤

1、定时器初始化

定时器对应的数据结构
  struct timer_list {
	unsigned long expires; // 超时时候jiffies的值:jiffies + 3*HZ
	void (*function)(unsigned long); // 超时处理函数,注意要对形参进行数据类型的转换
	unsigned long data; // 内核调用超时处理函数时传递给它的参数,data存放指针
  }
static struct timer_list mytimer;

  初始化定时器
  init_timer(&mytimer);
  mytimer.function = mytimer_func; //指定定时器的处理函数
  mytimer.expires = jiffies + 3*HZ; //超时时间为3s以后
//给超时处理函数传递的参数是mydata的地址,要注意在超时处理函数中进行数据类型的转换
  mytimer.data = (unsigned long )&mydata; 

 内核要管理一大堆的定时器,因此会把定时器挂到链表上进行管理

2、添加定时器到内核并启动定时器

//启动定时器
    add_timer(&mytimer);

3、编写定时处理函数

定时处理函数记得重新刷新定时时间,否则这个函数只会被执行一次

mod_timer(&mytimer, jiffies + msecs_to_jiffies(2000));

//超时处理函数
static void mytimer_func(unsigned long data)
{
    int *pdata = (int *)data;
    
    printk("hello,kernel, data = %#x\n", *pdata);

    //重新添加定时器,如果不添加,定时器处理函数只执行一次
    mod_timer(&mytimer, jiffies + msecs_to_jiffies(2000));
}

4、其他操作

删除定时器del_timer

参考代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <asm/gpio.h>
#include <plat/gpio-cfg.h>

//分配定时器
static struct timer_list mytimer;
static int mydata = 0x5555;

//超时处理函数
static void mytimer_func(unsigned long data)
{
    int *pdata = (int *)data;
    
    printk("hello,kernel, data = %#x\n", *pdata);

    //重新添加定时器,如果不添加,定时器处理函数只执行一次
    mod_timer(&mytimer, jiffies + msecs_to_jiffies(2000));
}

static int mytimer_init(void)
{
    //初始化定时器
    init_timer(&mytimer);
    //指定定时器超时时候的时间
    mytimer.expires = jiffies + msecs_to_jiffies(2000); //2s
    mytimer.function = mytimer_func; //超时处理函数
    mytimer.data = (unsigned long)&mydata; //给超时处理函数传递参数

    //启动定时器
    add_timer(&mytimer);
    
    printk("add timer ok!\n");
    return 0;
}

static void mytimer_exit(void)
{
    del_timer(&mytimer); 
    printk("del timer ok!\n");
}
module_init(mytimer_init);
module_exit(mytimer_exit);
MODULE_LICENSE("GPL");
发布了137 篇原创文章 · 获赞 106 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/shenlong1356/article/details/103300373
今日推荐