Linux高精度定时器hrtimer使用实例

Posted H₂O₂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux高精度定时器hrtimer使用实例相关的知识,希望对你有一定的参考价值。

简介

随着内核不断更新演进,内核对定时器的分辨率要求越来越高。硬件的高速发展也逐渐能够满足内核的这一要求,因此内核针对硬件提供的便利,开始设计了更高分辨率的定时器(hrtimer),可达到ns级别。本文主要讲解如何使用高精度定时器。

更多介绍详见内核文档目录kernel/Documentation/timers/hrtimers.txt

数据结构

/** * 定时器调用标志位 */enum hrtimer_restart {    HRTIMER_NORESTART, /* Timer is not restarted */    HRTIMER_RESTART, /* Timer must be restarted */};
/** * struct hrtimer - 基本的hrtimer结构 * @node:timerqueue节点,它也管理node.expires, * 计时器内部的绝对到期时间 * 表示形式。时间与时钟有关 * 计时器基于的。通过添加进行设置 * 松弛到_softexpires值。对于非范围计时器 * 与_softexpires相同。 * @_softexpires:hrtimer的绝对最早到期时间。 * 计时器的到期时间 * 武装。 * @function: 计时器到期回调函数 * @base: 指向计时器基础的指针(每个cpu和每个时钟) * @state: 状态信息(请参见上面的位值) * @is_rel: 设置计时器 * @start_pid:计时器统计信息字段,用于存储任务的pid * 启动计时器 * @start_site:计时器统计信息字段,用于存储计时器所在的站点 * 开始了 * @start_comm:计时器统计信息字段,用于存储其中的进程名称 * 启动计时器 * * hrtimer结构必须由hrtimer_init()初始化 */struct hrtimer { struct timerqueue_node node; ktime_t _softexpires; enum hrtimer_restart (*function)(struct hrtimer *); struct hrtimer_clock_base *base; u8 state; u8 is_rel;#ifdef CONFIG_TIMER_STATS int start_pid; void *start_site; char start_comm[16];#endif};


使用流程

a.定义定时器结构体变量

static struct hrtimer task1_timer;


b.初始化定时器任务

hrtimer_init(&task1_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);task1_timer.function = task1_timer_func;


c.实现定时器回调

static enum hrtimer_restart task1_timer_func(struct hrtimer *timer) {    queue_work(test1_workqueue, &test1_item);      hrtimer_start(&task1_timer, ktime_set(2, 0), HRTIMER_MODE_REL);  // 2s    return HRTIMER_NORESTART;}


d.开启定时器

hrtimer_cancel(&task1_timer);/* ktime_set第一个参数为秒单位,第二个参数为纳秒,定时时间0s + 900000000ns */hrtimer_start(&task1_timer, ktime_set(0, 900000000), HRTIMER_MODE_REL);


注意事项

(1) 在需要调用开启函数hrtimer_start,先调用hrtimer_cancel将定时器关闭。避免定时器被被开启两次,导致bug。

(2) 重复调用定时器可以在定时器回调函数,返回值返回HRTIMER_RESTART。也可以重新调用hrtimer_start,返回HRTIMER_NORESTART。

(3) 只需要重复执行指定次数,实现方法(举其中一种):

int i = 0, num = 4; static enum hrtimer_restart task1_timer_func(struct hrtimer *timer) {    if(i < num) {        i++;        queue_work(test1_workqueue, &test1_item);        hrtimer_start(&task1_timer, ktime_set(0, 900000000), HRTIMER_MODE_REL);  // 0.9s    } else {        i = 0;    }
return HRTIMER_NORESTART;}



记录历经的路,分享个人总结与感悟。

关注“开源519”,聊天窗口发送 “hrtimer代码” 获取笔者本篇代码实例,更多驱动学习资料尽在“开源519”公众号。

以上是关于Linux高精度定时器hrtimer使用实例的主要内容,如果未能解决你的问题,请参考以下文章

Linux 高精度定时器hrtimer 使用示例

Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现

Linux时间子系统之六:高精度定时器(HRTIMER)的原理和实现

Linux下的hrtimer高精度定时器

使用linux内核hrtimer高精度定时器实现GPIO口模拟PWM,原创

linux下jiffies定时器和hrtimer高精度定时器