linux 内核笔记之时间管理(三) : 高精度timer

来源:互联网 发布:网上配眼镜靠谱吗 知乎 编辑:程序博客网 时间:2024/05/24 02:48

低精度定时器基于时间轮算法,与jiffies关系紧密,精度为ms级,应用场景一般为“超时”退出。
因此,对于精度要求较高的驱动或应用场景,内核重新设计了一套软件架构,它可以提供纳秒级的定时精度,基于红黑树实现。

hrtimer的结构

与普通timer类似,每一个CPU也维护一个hrtimer的结构hrtimer_cpu_base,

struct hrtimer_cpu_base {    raw_spinlock_t          lock;    seqcount_t          seq;    struct hrtimer          *running;    unsigned int            cpu;    unsigned int            active_bases;    unsigned int            clock_was_set_seq;    bool                migration_enabled;    bool                nohz_active;#ifdef CONFIG_HIGH_RES_TIMERS   //高精度配置    unsigned int            in_hrtirq   : 1,                    hres_active : 1,                    hang_detected   : 1;    ktime_t             expires_next;  //定时器的到期时间    struct hrtimer          *next_timer;    unsigned int            nr_events;    unsigned int            nr_retries;    unsigned int            nr_hangs;    unsigned int            max_hang_time;#endif    struct hrtimer_clock_base   clock_base[HRTIMER_MAX_CLOCK_BASES]; //时钟源} ____cacheline_aligned;

其中hrtimer的结构,

struct hrtimer {    struct timerqueue_node      node;    ktime_t             _softexpires; //到期时间    enum hrtimer_restart        (*function)(struct hrtimer *);    struct hrtimer_clock_base   *base;   //时钟源    u8              state;     //hrtimer当前状态    u8              is_rel;#ifdef CONFIG_TIMER_STATS    int             start_pid;    void                *start_site;    char                start_comm[16];#endif};

hrimer的有以下几种状态,

enum  hrtimer_base_type {      HRTIMER_BASE_MONOTONIC,  // 单调递增的monotonic时间,不包含休眠时间      HRTIMER_BASE_REALTIME,   // 平常使用的墙上真实时间      HRTIMER_BASE_BOOTTIME,   // 单调递增的boottime,包含休眠时间      HRTIMER_MAX_CLOCK_BASES, // 用于后续数组的定义  }; 

hrtimer的使用

初始化hrtimer:

void hrtimer_init(struct hrtimer *timer, clockid_t which_clock,               enum hrtimer_mode mode);  

激活hrtimer:

int hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode);

hrtimer_start函数将一个hrtimer加入到一个按照到期时间排序的红黑树中

如果需要指定到期范围,则可以使用hrtimer_start_range_ns

hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,              unsigned long range_ns, const enum hrtimer_mode mode);  

取消hrtimer:

int hrtimer_cancel(struct hrtimer *timer);  

推迟hrtimer的到期时间:

extern u64  hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval);  /* Forward a hrtimer so it expires after the hrtimer's current now */  static inline u64 hrtimer_forward_now(struct hrtimer *timer,                        ktime_t interval)  {      return hrtimer_forward(timer, timer->base->get_time(), interval);  }  

使用示例

#include <linux/module.h>#include <linux/kernel.h>#include <linux/hrtimer.h>#include <linux/jiffies.h>static struct hrtimer timer;ktime_t kt;static enum hrtimer_restart hrtimer_handler(struct hrtimer *timer){    //kt = ktime_set(1, 10);    printk("hrtimer start\n");    hrtimer_forward(timer, timer->base->get_time(), kt);    return HRTIMER_RESTART;}static int __init test_init(void){    pr_info("timer resolution: %lu\n", TICK_NSEC);    kt = ktime_set(1, 10); /* 1 sec, 10 nsec */    hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);    //hrtimer_set_expires(&timer, kt);    hrtimer_start(&timer, kt, HRTIMER_MODE_REL);    timer.function = hrtimer_handler;    printk("test init\n");    return 0;}static void __exit test_exit(void){    hrtimer_cancel(&timer);    printk(" test exit\n");    return;}MODULE_LICENSE("GPL");module_init(test_init);module_exit(test_exit);

更多hrtimer的知识参考博文:
http://blog.csdn.net/droidphone/article/details/8074892

1 0
原创粉丝点击