迅为嵌入式linux驱动开发笔记(八)—内核定时器

内核定时器

二. Linux 内核定时器基础知识

Linux 内 核 使 用 timer_list 结 构 体表示内核定时器 ,timer_list定义在文件 include/linux/timer.h 中,定义如下:

struct timer_list { 
			struct list_head entry;
			unsigned long expires; /* 定时器超时时间,不是时长,单位是节拍数 */
			struct tvec_base *base;
			void (*function)(unsigned long); /* 定时处理函数 */
			unsigned long data; /* 要传递给 function 函数的参数 */ 
			int slack; 
};

在这个结构体中,有几个参数需要重点关注。 一是 expires 到期时间,单位是节拍数。 等于定时的当前的时钟节拍计数(存储在系统的全局变量 jiffies)+定时时长对应的时钟节拍数量。

那么怎么把时间转换成节拍数量呢?

示例:从现在开始定时 1 秒:内核中有一个宏 HZ, 表示一秒对应的时钟节拍数,那么就可以通过这个宏来把时间转换成节拍数。 所以,定时 1 秒就是:expires = jiffies + 1*HZ 。 HZ 的值是可以设置的,也就是说一秒对应的时钟拍数是可以设置的,Linux 内核会使用CONFIG_HZ 来设置系统时钟 。

打 开 文 件 include/asm generic/param.h , 有如下内容:

# undef HZ 
# define HZ CONFIG_HZ 
# define USER_HZ 100

HZ 就是 CONFIG_HZ,因此 HZ=100,表示一秒的节拍数是 100 , 在编译 Linux 内核的时候可以通过图形化界面设置系统节拍率,按照如下路径打开配置界面。在这里插入图片描述通过上图可以发现可选的系统节拍率为 100Hz 、 200Hz 、 250Hz 、 300Hz 、 500Hz 和 1000Hz 。 默认是 100Hz 。

第二个需要关心的参数是 function 超时处理函数,这个并不是硬件中断服务程序。 原型:void function(unsigned long data);

第三个参数是 data 传递给超时处理函数的参数,可以把一个变量的地址转换成 unsigned long 。

三、Linux 内核定时器相关操作函数

1、时间转换函数
<1>ms 转换为时钟节拍函数
 unsigned long msecs_to_jiffies(const unsigned int m) 
<2>us 转换为时钟节拍函数
 unsigned long usecs_to_jiffies(const unsigned int u) 

举例:

<1> 定时10ms

计算: jiffies +msecs_to_jiffies(10)

<2> 定时10us

计算: jiffies +usecs_to_jiffies(10)

<2> 宏 DEFINE_TIMER

原型: #define DEFINE_TIMER(_name, _function, _expires, _data)

作用:静态定义结构体变量并且初始化初始化 function, expires, data 成员。

参数: _name 变量名;

_function 超时处理函数 ;

_data 传递给超时处理函数的参数 _expires 到点时间,一般在启动定时前需要重新初始化。

<3>add_timer 函数

原型: void add_timer(struct timer_list *timer)

作用: add_timer函数用于向Linux 内核注册定时器,使用 add_timer 函数向内核注册定时器以后,定时器就会开始运行

参数:
timer : 要注册的定时器。

<4>del_timer 函数

原型: int del_timer(struct timer_list * timer)

作用: del_timer 函数用于删除一个定时器,不管定时器有没有被激活,都可以使用此函数删除。 在多处理器系统上,定时器可能会在其他的处理器上运行,因此在调用 del_timer 函数 删除定时器之前要先等待其他处理器的定时处理器函数退出

timer : 要删除的定时器。

返回值: 0 , 定时器还没被激活; 1 , 定时器已经激活。

<5>mod_timer 函数

函数原型: int mod_timer(struct timer_list *timer, unsigned long expires)

作用: mod_timer 函数用于修改定时值,如果定时器还没有激活的话, mod_timer 函数会 激活定时器!

参数:
timer : 要修改超时时间 ( 定时值 ) 的定时器。
expires : 修改后的超时时间。

返回值:
0 , 调用 mod_timer 函数前定时器未被激活;
1 , 调用 mod_timer 函数前定时器已被激活。

实践课

每隔1s,打印一句话。

定时器初始化:

#include <linux/timer.h>

DEFINE_TIMER(test_timer,timer_function,0,0);

static int hello_init(void)
{
    printk("hello world\n");

    test_timer.expires = jiffies + 1*HZ;
		//jiffies相当于手机的当前时刻!!!
    add_timer(&test_timer);//启动定时器

    return 0;
}

超时处理函数,让超时之后继续加载:

static void timer_function(unsigned long data)
{
    printk("This is timer function\n");
		//重新开启定时器
    mod_timer(&test_timer,jiffies + 1*HZ);
}

按键消抖

#include <linux/timer.h>

DEFINE_TIMER(test_timer,timer_function,0,0);

static void timer_function(unsigned long data)
{
    //超时时间处理函数
}

中断处理函数:

irq_handler_t test_key(int irq, void *args)//中断处理函数
{
    test_timer.expires = jiffies + msecs_to_jiffies(20) ;
    //jiffies相当于手机的当前时刻!!!
    add_timer(&test_timer);//启动定时器

    return IRQ_HANDLED;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值