Chinaunix首页 | 论坛 | 博客
  • 博客访问: 339859
  • 博文数量: 109
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 849
  • 用 户 组: 普通用户
  • 注册时间: 2018-10-15 14:13
个人简介

搭建一个和linux开发者知识共享和学习的平台

文章分类

全部博文(109)

文章存档

2025年(8)

2024年(15)

2023年(24)

2022年(27)

2019年(8)

2018年(27)

分类: LINUX

2025-02-18 10:25:05

    内核提供的定时器分辨率是受jiffies来定时的,所以会受到HZ影响,如果HZ100,代表每秒钟产生100次中断,那一个jiffies就需要10毫秒,所以精度为10毫秒,但实测过的同学定时器秒级或者毫秒级都会有点误差,如果精度需要精准或者需要微秒甚至是纳秒级别,就要用到高分辨率定时器hrtimer。

    

高分辨率定时器要的数据结构struct hrtimer

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

struct hrtimer {
    struct timerqueue_node          node;    // 用于链表管理的节点
    ktime_t                         _softexpires;// 到期时间
    enum hrtimer_restart            (*function)(struct hrtimer *);// 定时到期时的回调函数
    struct hrtimer_clock_base       *base;  //指向定时器基的指针(每个CPU和每个时钟)
    u8                              state; // 状态标志
    u8                              is_rel;//设置定时器是否相对
    u8                              is_soft;//在软中断上下文中设置hrtimer是否过期
    u8                              is_hard;//在硬中断上下文中设置hrtimer是否过期

    ANDROID_KABI_RESERVE(1);
};

枚举高精度模式定时器的到期模式
enum hrtimer_mode {
         HRTIMER_MODE_ABS        = 0x00,
         HRTIMER_MODE_REL        = 0x01,
         HRTIMER_MODE_PINNED     = 0x02,
         HRTIMER_MODE_SOFT       = 0x04,
         HRTIMER_MODE_HARD       = 0x08,

         HRTIMER_MODE_ABS_PINNED = HRTIMER_MODE_ABS | HRTIMER_MODE_PINNED,
         HRTIMER_MODE_REL_PINNED = HRTIMER_MODE_REL | HRTIMER_MODE_PINNED,

         HRTIMER_MODE_ABS_SOFT   = HRTIMER_MODE_ABS | HRTIMER_MODE_SOFT,
         HRTIMER_MODE_REL_SOFT   = HRTIMER_MODE_REL | HRTIMER_MODE_SOFT,

         HRTIMER_MODE_ABS_PINNED_SOFT = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_SOFT,
         HRTIMER_MODE_REL_PINNED_SOFT = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_SOFT,

         HRTIMER_MODE_ABS_HARD   = HRTIMER_MODE_ABS | HRTIMER_MODE_HARD,
         HRTIMER_MODE_REL_HARD   = HRTIMER_MODE_REL | HRTIMER_MODE_HARD,

         HRTIMER_MODE_ABS_PINNED_HARD = HRTIMER_MODE_ABS_PINNED | HRTIMER_MODE_HARD,
         HRTIMER_MODE_REL_PINNED_HARD = HRTIMER_MODE_REL_PINNED | HRTIMER_MODE_HARD,
};

分为五种高精度模式:

  • 绝对模式
  • 相对模式
  • 计时器绑定到CPU(仅在启动计时器时考虑)
  • 软中断到期模式(HRTIMER_MODE_SOFT)
  • 硬中断到期模式(HRTIMER_MODE_HARD)

软中断到期模式的高精度定时器,到期的时候在类型为 HRTIMER_SOFTIRQ 的软中断里面执行定时器回调函数。在实时内核中,软中断由软中断线程执行,或者在进程开启软中断的时候执行。

硬中断到期模式的高精度定时器,到期的时候在时钟中断处理程序里面执行定时器回调函数。如果没有指定到期模式,那么在实时内核中默认使用软中断到期模式。


hrtimer_init 是 Linux 内核中用于初始化高分辨率定时器的函数
void hrtimer_init(struct hrtimer *timer, clockid_t clock_id , enum hrtimer_mode mode)

hrtimer_start 是 Linux 内核中用于启动高分辨率定时器的函数
int hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode)

hrtimer_forward_now 是 Linux 内核中用于调整高分辨率定时器(high-resolution timer,hrtimer)到期时间的一个函数
void hrtimer_forward_now(struct hrtimer *timer,ktime_t interval)

hrtimer_cancel 是 Linux 内核中用于取消高分辨率定时器的函数
hrtimer_cancel(struct hrtimer *timer)

ktime_set 用于设置一个定时器的到期时间
ktime_t t = ktime_set(secs, nsecs);

高分辨率定时器使用包括单次使用和循环使用
单次定时1s
#include 
#include 
#include 
#include 
#include 

staticstruct hrtimer my_timer;
staticint count = 0;

enum hrtimer_restart my_timer_callback(struct hrtimer *timer)
{
    pr_info(KERN_INFO "High-resolution timer expired after 1 second\n");

    return HRTIMER_NORESTART; // 不重复定时器
}

static int __init my_module_init(void)
{
    ktime_t ktime;

    pr_info("High-Resolution Timer Example Module Loaded\n");

    // 设置定时器初始时间为 1 秒
    ktime = ktime_set(10); // 1 秒, 0 纳秒
    hrtimer_init(&my_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    my_timer.function = my_timer_callback;
    hrtimer_start(&my_timer, ktime, HRTIMER_MODE_REL);

    return0;
}

static void __exit my_module_exit(void)
{
    // 停止定时器
    hrtimer_cancel(&my_timer);
    pr_info("High-Resolution Timer Example Module Unloaded\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("High-Resolution Timer Example");
MODULE_AUTHOR("Pan Shuai");

循环定时1s的例子
#include 
#include 
#include 
#include 
#include 

staticstruct hrtimer my_timer;
staticint count = 0;

enum hrtimer_restart my_timer_callback(struct hrtimer *timer)
{
    count++;
    pr_info("Timer expired! Count: %d\n", count);

    // 重新启动定时器,设置下次到期时间为 1 秒
    hrtimer_forward_now(timer, ms_to_ktime(1000));
    return HRTIMER_RESTART; // 重复定时器
}

static int __init my_module_init(void)
{
    ktime_t ktime;

    pr_info("High-Resolution Timer Example Module Loaded\n");

    // 设置定时器初始时间为 1 秒
    ktime = ktime_set(10); // 1 秒, 0 纳秒
    hrtimer_init(&my_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    my_timer.function = my_timer_callback;
    hrtimer_start(&my_timer, ktime, HRTIMER_MODE_REL);

    return0;
}

static void __exit my_module_exit(void)
{
    // 停止定时器
    hrtimer_cancel(&my_timer);
    pr_info("High-Resolution Timer Example Module Unloaded\n");
}

module_init(my_module_init);
module_exit(my_module_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("High-Resolution Timer Example");
MODULE_AUTHOR("Pan Shuai");
阅读(25) | 评论(0) | 转发(0) |
0

上一篇:Linux内核时间函数

下一篇:没有了

给主人留下些什么吧!~~