Linux设备驱动-内核定时器

在嵌入式软件开发中,使用定时器的目的是为了实现周期性地执行某项工作;同样地,linux内核也实现了一种定时器,用于实现内核周期性执行某项工作。

1.基本概念

linux内核实现的这种定时器,称之为动态定时器,是内核用来控制在未来某个时间点(基于jiffies)调度执行某个函数的一种机制,它的实现位于Linux/timer.h 和 kernel/timer.c 文件中。
被调度的函数是异步执行的,类似于一种“软件中断”,处于非进程的上下文中,所以这个被调度函数应该遵循如下规则:

  1. 没有 current 指针,不允许访问用户空间。因为没有进程上下文,相关代码和被中断的进程没有任何联系;
  2. 不能执行休眠(或可能引起休眠的函数)和调度;
  3. 任何被访问的数据结构都应该针对并发访问进行保护,以防止竞争条件;
  4. 被调度函数运行过一次后就不会再被运行了(相当于自动注销),但可以通过在被调度的函数中重新调度自己来周期运行;
  5. 定时函数实现不能太耗时,耗时要尽量短。

2.数据结构

内核提供给驱动许多函数来声明, 注册, 以及删除内核定时器:

#include <linux/timer.h>
struct timer_list {
	/*
	 * All fields that change during normal runtime grouped to the
	 * same cacheline
	 */
	struct hlist_node	entry;
	unsigned long		expires;
	void			(*function)(struct timer_list *);
	u32			flags;
	......
};

3.初始化

#define timer_setup(timer, callback, flags)			\
	__init_timer((timer), (callback), (flags))

需要注意的是kernel版本4.15之前初始化函数是init_timer,在4.15之后改为timer_setup。

4. 注册

初始化定时器成功之后,我们需要注册该定时器,函数为:

void add_timer(struct timer_list *timer);

5.修改定时时长

定时运行过程中的定时器周期修改函数为:

int mod_timer(struct timer_list *timer, unsigned long expires);

通常要实现循环定时功能一般是在定时函数结束的时候通过mod_timer重新设置定时时长来实现的:

void timer_fun(struct timer_list *timer)
{
	// do some thing
	mod_timer(timer, jiffies + HZ);
}

6.删除定时器

当不需要定时器时通过如下函数删除定时器:

int del_timer(struct timer_list * timer);

7.测试

完整的测试代码如下:
https://github.com/zhaoxd298/Linux_drivers/tree/master/timer

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值