Linux hrtimer分析--配置高精度模式


本文介绍Linux2.6.29中,配置高精度模式的hrtimer与未配置高精度模式时行为的区别。本文暂不考虑高精度模式对Linux系统时钟中断的影响。

在没有配置高精度模式时,hrtimer的超时在系统时钟中断的轮循中检查,所以此时hrtimer的定时精度(jiffy)还是以轮循的间隔为单位,精度与传统的时间轮定时器一样。

在配置高精度模式后,hrtimer的超时由struct clock_event_device的超时中断完成。clock_event_device一般来说描述的都是一个硬件定时器,其定时精度由硬件定时器决定,比如我的板子上的此定时器参数为:Timer at Vir:0xE0100200 = Phy:0xE0100200, using Irq:27, at Freq:250000000,可见其精度之高:250MHz,这也是高精度时钟这个名称的由来。

  1. struct clock_event_device {  
  2.     const char      *name;  
  3.     unsigned int        features;  
  4.     u64         max_delta_ns;  
  5.     u64         min_delta_ns;  
  6.     u32         mult;  
  7.     u32         shift;  
  8.     int         rating;  
  9.     int         irq;  
  10.     const struct cpumask    *cpumask;  
  11.     int         (*set_next_event)(unsigned long evt,  
  12.                           struct clock_event_device *);  
  13.     void            (*set_mode)(enum clock_event_mode mode,  
  14.                         struct clock_event_device *);  
  15.     void            (*event_handler)(struct clock_event_device *);  
  16.     void            (*broadcast)(const struct cpumask *mask);  
  17.     struct list_head    list;  
  18.     enum clock_event_mode   mode;  
  19.     ktime_t         next_event;  
  20.     unsigned long       retries;  
  21. };  

下面简要介绍一下在配置了高精度模式之后hrtimer的实现细节。

1.     添加hrtimer

在配置高精度模式后,添加hrtimer也是由函数hrtimer_start完成,这与没有配置高精度模式时一样。但是,高精度模式时,如果添加的hrtimer在红黑树的最左边一个节点,即要添加的hrtimer是将会第一个到期的hrtimer时,那么这时会调用子函数hrtimer_enqueue_reprogram重新设置clock_event_device的超时中断

hrtimer_enqueue_reprogram

       hrtimer_reprogram

              tick_program_event

                     tick_dev_program_event

                            clockevents_program_event

                                   struct clock_event_device * pDev->set_next_event

比如我的平台的clock_event_device的定义如下:

  1. static struct clock_event_device timer0_clockevent = {  
  2.     .name       = "my_timer_evt",  
  3.     .features       = CLOCK_EVT_FEAT_PERIODIC,  
  4.     .set_mode       = my_set_mode,  
  5.     .set_next_event = my_set_next_event,  
  6.     .rating     = 300,  
  7.     .cpumask        = cpu_all_mask,  
  8. };  

其中timer_set_next_event主要是设置硬件设备的相关registers.

  • 1
  • 2
  • 下一页

相关内容