Linux内核中的高精度定时器:hrtimer机制详解

张开发
2026/4/5 20:56:56 15 分钟阅读

分享文章

Linux内核中的高精度定时器:hrtimer机制详解
Linux内核中的高精度定时器hrtimer机制详解作为一名深耕操作系统和嵌入式开发的工程师我对Linux内核中的高精度定时器hrtimer机制有着深入的理解。hrtimer提供了微秒甚至纳秒级的定时精度是实时应用的关键基础设施。传统定时器的局限传统的基于jiffies的定时器存在以下局限精度受限受HZ值限制通常只有1-10ms精度粒度粗糙无法满足实时应用的需求累积误差长时间运行会产生较大误差hrtimer的核心特性hrtimer提供了以下特性高精度支持微秒甚至纳秒级精度多种时钟源支持多种时钟基准红黑树管理高效地管理大量定时器软中断处理在软中断上下文中执行hrtimer的核心API1. 初始化和设置// 定义hrtimer struct hrtimer my_timer; // 初始化 hrtimer_init(my_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); my_timer.function my_timer_callback; // 时钟类型 // CLOCK_REALTIME: 系统实时时钟受NTP调整影响 // CLOCK_MONOTONIC: 单调时钟不受NTP影响 // CLOCK_BOOTTIME: 包含挂起时间的单调时钟 // 模式 // HRTIMER_MODE_ABS: 绝对时间 // HRTIMER_MODE_REL: 相对时间 // HRTIMER_MODE_PINNED: 绑定到特定CPU2. 启动和取消// 启动定时器相对时间 hrtimer_start(my_timer, ms_to_ktime(100), HRTIMER_MODE_REL); // 启动定时器绝对时间 hrtimer_start(my_timer, ktime_set(5, 0), HRTIMER_MODE_ABS); // 取消定时器 hrtimer_cancel(my_timer); // 尝试取消如果正在执行则等待 int ret hrtimer_try_to_cancel(my_timer); if (ret 1) // 成功取消 else if (ret 0) // 定时器正在执行 // 重启定时器 hrtimer_restart(my_timer);3. 回调函数enum hrtimer_restart my_timer_callback(struct hrtimer *timer) { // 执行定时任务 do_timer_work(); // 如果需要周期性执行重新设置定时器 hrtimer_forward_now(timer, ms_to_ktime(100)); return HRTIMER_RESTART; // 重启定时器 // return HRTIMER_NORESTART; // 不重启 }hrtimer的实现原理1. 数据结构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; u8 is_soft; u8 is_hard; }; struct hrtimer_clock_base { struct timerqueue_head head; ktime_t resolution; ktime_t (*get_time)(void); ktime_t softirq_time; ktime_t offset; };2. 红黑树管理hrtimer使用红黑树管理定时器队列高效查找O(log n)时间复杂度快速插入O(log n)时间复杂度顺序遍历按到期时间排序3. 时钟事件设备hrtimer依赖时钟事件设备clockeventsstruct clock_event_device { const char *name; u64 mult; u32 shift; int rating; int irq; void (*set_next_event)(unsigned long evt, struct clock_event_device *); void (*set_state_shutdown)(struct clock_event_device *); void (*set_state_periodic)(struct clock_event_device *); void (*set_state_oneshot)(struct clock_event_device *); void (*tick_resume)(struct clock_event_device *); };使用场景1. 实时任务调度struct hrtimer rt_timer; void setup_rt_timer(void) { hrtimer_init(rt_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); rt_timer.function rt_task_callback; // 设置1ms周期 hrtimer_start(rt_timer, ms_to_ktime(1), HRTIMER_MODE_REL); } enum hrtimer_restart rt_task_callback(struct hrtimer *timer) { // 执行实时任务 execute_rt_task(); // 重新设置下一个周期 hrtimer_forward_now(timer, ms_to_ktime(1)); return HRTIMER_RESTART; }2. 多媒体同步struct hrtimer video_timer; ktime_t frame_interval; void init_video_sync(int fps) { frame_interval ktime_set(0, NSEC_PER_SEC / fps); hrtimer_init(video_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); video_timer.function video_frame_callback; } enum hrtimer_restart video_frame_callback(struct hrtimer *timer) { // 显示下一帧 display_next_frame(); hrtimer_forward_now(timer, frame_interval); return HRTIMER_RESTART; }3. 精确延时void precise_delay_us(unsigned int us) { ktime_t start, end; start ktime_get(); end ktime_add_us(start, us); while (ktime_before(ktime_get(), end)) cpu_relax(); }性能优化建议1. 避免频繁启停// 错误频繁创建和销毁 void do_work(void) { struct hrtimer timer; hrtimer_init(timer, ...); hrtimer_start(timer, ...); hrtimer_cancel(timer); } // 正确复用定时器 static struct hrtimer timer; void init(void) { hrtimer_init(timer, ...); } void do_work(void) { hrtimer_start(timer, ...); }2. 使用合适的时钟源// 对于不需要绝对时间的场景使用MONOTONIC hrtimer_init(timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); // 对于需要跨挂起保持的场景使用BOOTTIME hrtimer_init(timer, CLOCK_BOOTTIME, HRTIMER_MODE_REL);3. 批量处理// 将多个短定时器合并为一个长定时器 static struct hrtimer batch_timer; static LIST_HEAD(pending_work); enum hrtimer_restart batch_callback(struct hrtimer *timer) { struct work *work; // 批量处理所有待处理的工作 list_for_each_entry(work, pending_work, list) { process_work(work); } // 根据下一个工作的时间重新设置定时器 ktime_t next_time get_next_work_time(); hrtimer_set_expires(timer, next_time); return HRTIMER_RESTART; }与传统定时器的对比特性hrtimer传统timer精度微秒/纳秒毫秒时钟源多种选择基于jiffies实现红黑树链表开销较高较低适用场景实时应用一般延时调试和监控# 查看hrtimer统计 cat /proc/timer_list # 查看时钟事件设备 cat /proc/timer_list | grep Clock Event Device # 查看当前定时器 cat /proc/timer_list | grep hrtimer总结hrtimer是Linux内核中实现高精度定时的关键机制它为实时应用、多媒体同步等场景提供了必要的支持。作为嵌入式开发者理解hrtimer的工作原理和使用方法对于开发实时系统至关重要。

更多文章