歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux基礎 >> Linux教程

Linux hrtimer的實現

1. Linux hrtimer的實現方案

Linux hrtimer的實現是依賴硬件(通過可編程定時器來實現)的支持的,而且此定時器有自己的專用寄存器, 硬中斷和頻率。比如我的板子上的對應參數如下:

Timer at Vir:0xE0100200 = Phy:0xE0100200, using Irq:27, at Freq:250000000,由此可見,其頻率為250MHz,所以其精度為:1/250000000=4ns,比系統時鐘jiffy(HZ=100,精度為10ms)的精度高得太多了。可是支持此高精度timer是需要付出硬件成本的。即它是一個硬件時鐘。這裡所說的硬件時鐘特指的是硬件計時器時鐘。

2. 硬件時鐘 數據結構
  和硬件計時器(本文又稱作硬件時鐘,區別於軟件時鐘)相關的數據結構主要有兩個:
  struct clocksource :對硬件設備的抽象,描述時鐘源信息

  1. struct clocksource {  
  2.     /* 
  3.      * First part of structure is read mostly 
  4.      */  
  5.     char *name;  
  6.     struct list_head list;  
  7.     int rating;  
  8.     cycle_t (*read)(struct clocksource *cs);  
  9.     int (*enable)(struct clocksource *cs);  
  10.     void (*disable)(struct clocksource *cs);  
  11.     cycle_t mask;  
  12.     u32 mult;  
  13.     u32 shift;  
  14.     u64 max_idle_ns;  
  15.     unsigned long flags;  
  16.     cycle_t (*vread)(void);  
  17.     void (*suspend)(struct clocksource *cs);  
  18.     void (*resume)(struct clocksource *cs);  
  19. #ifdef CONFIG_IA64   
  20.     void *fsys_mmio;        /* used by fsyscall asm code */  
  21. #define CLKSRC_FSYS_MMIO_SET(mmio, addr)      ((mmio) = (addr))   
  22. #else   
  23. #define CLKSRC_FSYS_MMIO_SET(mmio, addr)      do { } while (0)   
  24. #endif   
  25.   
  26.     /* 
  27.      * Second part is written at each timer interrupt 
  28.      * Keep it in a different cache line to dirty no 
  29.      * more than one cache line. 
  30.      */  
  31.     cycle_t cycle_last ____cacheline_aligned_in_smp;  
  32.   
  33. #ifdef CONFIG_CLOCKSOURCE_WATCHDOG   
  34.     /* Watchdog related data, used by the framework */  
  35.     struct list_head wd_list;  
  36.     cycle_t wd_last;  
  37. #endif   
  38. };  

struct clock_event_device :時鐘的事件信息,包括當硬件時鐘中斷發生時要執行那些操作(實際上保存了相應函數的指針)。本文將該結構稱作為“時鐘事件設備”。

  1. /** 
  2.  * struct clock_event_device - clock event device descriptor 
  3.  * @name:       ptr to clock event name 
  4.  * @features:       features 
  5.  * @max_delta_ns:   maximum delta value in ns 
  6.  * @min_delta_ns:   minimum delta value in ns 
  7.  * @mult:       nanosecond to cycles multiplier 
  8.  * @shift:      nanoseconds to cycles divisor (power of two) 
  9.  * @rating:     variable to rate clock event devices 
  10.  * @irq:        IRQ number (only for non CPU local devices) 
  11.  * @cpumask:        cpumask to indicate for which CPUs this device works 
  12.  * @set_next_event: set next event function 
  13.  * @set_mode:       set mode function 
  14.  * @event_handler:  Assigned by the framework to be called by the low 
  15.  *          level handler of the event source 
  16.  * @broadcast:      function to broadcast events 
  17.  * @list:       list head for the management code 
  18.  * @mode:       operating mode assigned by the management code 
  19.  * @next_event:     local storage for the next event in oneshot mode 
  20.  * @retries:        number of forced programming retries 
  21.  */  
  22. struct clock_event_device {  
  23.     const char      *name;  
  24.     unsigned int        features;  
  25.     u64         max_delta_ns;  
  26.     u64         min_delta_ns;  
  27.     u32         mult;  
  28.     u32         shift;  
  29.     int         rating;  
  30.     int         irq;  
  31.     const struct cpumask    *cpumask;  
  32.     int         (*set_next_event)(unsigned long evt,  
  33.                           struct clock_event_device *);  
  34.     void            (*set_mode)(enum clock_event_mode mode,  
  35.                         struct clock_event_device *);  
  36.     void            (*event_handler)(struct clock_event_device *);  
  37.     void            (*broadcast)(const struct cpumask *mask);  
  38.     struct list_head    list;  
  39.     enum clock_event_mode   mode;  
  40.     ktime_t         next_event;  
  41.     unsigned long       retries;  
  42. };  
  43.    

上述兩個結構內核源代碼中有較詳細的注解,分別位於文件 clocksource.h 和 clockchips.h 中。需要特別注意的是結構 clock_event_device 的成員 event_handler ,它指定了當硬件時鐘中斷發生時,內核應該執行那些操作,也就是真正的時鐘中斷處理函數。

Linux 內核維護了兩個鏈表,分別存儲了系統中所有時鐘源的信息和時鐘事件設備的信息。這兩個鏈表的表頭在內核中分別是 clocksource_list 和 clockevent_devices 。 

Copyright © Linux教程網 All Rights Reserved