前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux高精度定时器hrtimer使用实例

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

作者头像
开源519
发布2020-08-06 10:51:19
7.1K1
发布2020-08-06 10:51:19
举报
文章被收录于专栏:开源519开源519

简介

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

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

数据结构

代码语言:javascript
复制
/**
 * 定时器调用标志位
 */
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.定义定时器结构体变量

代码语言:javascript
复制
static struct hrtimer task1_timer;

b.初始化定时器任务

代码语言:javascript
复制
hrtimer_init(&task1_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
task1_timer.function = task1_timer_func;

c.实现定时器回调

代码语言:javascript
复制
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.开启定时器

代码语言:javascript
复制
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) 只需要重复执行指定次数,实现方法(举其中一种):

代码语言:javascript
复制
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;
}

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开源519 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档