Linux核心開發之中斷與時鐘(三)

來源:互聯網
上載者:User

  晚上7點10分..

“小濤哥,這章不是叫Linux裝置驅動程式之中斷與時鐘,前邊你講了中斷,還給了我很多模版,我都看懂了,這次是不是要開始講時鐘了..”

“真聰明,越來越喜歡你這聰明的樣子了,說的不錯,今天就要開始一個新的模組--核心時鐘”我很少夸人,為啥今天誇她呢了,呵呵.

  定時器,意思大家都明白,我就不說了,要是不明白,把它想成個鬧鐘總可以吧..

  定時器分為硬體和軟體定時器,軟體定時器最終還是要依靠硬體定時器來完成。核心在時鐘中斷髮生後檢測各定時器是否到期,到期後的定時器處理函數將作為非強制中斷在底半部執行。實質上,時鐘中斷處理常式執行update_process_timers函數,該函數調用run_local_timers函數,這個函數處理TIMER_SOFTIRQ非強制中斷,運行當前處理上到期的所有定時器。

Linux核心中定義提供了一些用於操作定時器的資料結構和函數如下:

1)timer_list:說定時器,當然要來個定時器的結構體

  struct timer_list{     struct list_head entry;  //定時器列表      unsigned long expires;  //定時器到期時間      void (*function)(unsigned long) ;//定時器處理函數      unsigned long data;   //作為參數被傳入定時器處理函數      struct timer_base_s *base;}
2)初始化定時器:void init_timer(struct timer_list *timer);經過這個初始化後,entry的next為NULL,並給base賦值
3)增加定時器:void add_timer(struct timer_list *timer); 該函數用於註冊核心定時器,並將定時器加入到核心動態定時器鏈表中。
4)刪除定時器:int del_timer(struct timer_list *timer);
  說明:del_timer_sync是del_timer的同步版,主要在多處理器系統中使用,如果編譯核心時不支援SMP,del_timer_sync和del_timer等價.
5)修改定時器:int mod_timer(struct timer_list *timer, unsigned long expires);
下邊是一個使用定時器的模版:
struct xxx_dev  /*second裝置結構體*/ {  struct cdev cdev; /*cdev結構體*/  ...  struct timer_list xxx_timer; /*裝置要使用的定時器*/};int xxx_func1(...)  //xxx驅動中某函數 {  struct xxx_dev *dev = filp->private_data;    ...  /*初始化定時器*/  init_timer(&dev->xxx_timer);  dev->xxx_timer.function = &xxx_do_handle;  dev->xxx_timer.data = (unsigned long)dev;  dev->xxx_timer.expires = jiffies + delay;    add_timer(&dev->xxx_timer); /*添加(註冊)定時器*/  ...  return 0;}int xxx_func2(...)   //驅動中某函數 {  ...  del_timer(&second_devp->s_timer);  ...}static void xxx_do_timer(unsigned long arg)  //定時器處理函數 {  struct xxx_device *dev = (struct xxx_device *)(arg);    ...    //調度定時器再執行  dev->xxx_timer.expires = jiffies + delay;  add_timer(&dev->xxx_timer);}

在定時器函數中往往會在做完具體工作後,延遲expires並將定時器再次添加到核心定時器鏈表中,以便定時器能被再次觸發(這句話我也是從別處抄來的,別告訴小王哈)。

在核心定時器中,常常少不了要說下核心延遲的事,請接著往下看:

1)短延遲:在linux核心中提供了三個函數來分別實現納秒,微秒,毫秒延遲,原理上是忙等待,它根據CPU頻率進行一定次數的迴圈

void ndelay(unsigned long nsecs);                   void udelay(unsigned long usecs);                 void mdelay(unsigned long msecs);

毫秒延遲已經相當大了,當然更秒延遲當然要小一些,在核心中,為了效能,最好不要用mdelay,這會耗費大量cpu資源,那麼咋辦呢,涼拌..

void msleep(unsigned int millisecs);   unsigned long msleep_interruptible(unsigned int millisecs);   void ssleep(unsigned int seconds);

這三個是核心專門提供該我們用來處理毫秒以上的延遲。上述函數將使得調用它的進程睡眠參數指定的秒數,其中第二個是可以被打斷的,其餘的兩個是不可以的。

2)長延遲:核心中進行延遲最常用的方法就是比較當前的jiffies和目標jiffies(當前的加上時間間隔的jiffies),直到未來的jiffies達到目標jiffies。比如:

unsigned long delay = jiffies + 100;  //延遲100個jiffieswhile(time_before(jiffies, delay));

與time_before對應的還有一個time_after().其實就是#define time_before(a,b)  time_after(b,a);

另外兩個是time_after_eq(a,b)和time_before_eq(a,b)

3)睡著延遲:這顯然是比忙等待好的方法,因為在未到來之前,進程會處於睡眠狀態,把CPU空出來,讓CPU可以做別的事情,等時間到了,調用schedule_timeout()就可以喚醒它並重新調度執行。msleep和msleep_interruptible本質上都是依靠包含了schedule_timeout的schedule_timeout_uninterruptible()和schedule_

timeout_interruptible()實現。就像下邊這樣:

void msleep(unsigned int msecs)   
{    unsigned long timeout = msecs_to_jiffies(msecs) + 1;    while(timeout)         timeout = schedule_timeout_uninterruptible(timeout);}unsigned long msleep_interruptible(unsigned int msecs){    unsigned long timeout = msecs_to_jiffies(msecs) + 1;    while(timeout && !signal_pending(current))         timeout = schedule_timeout_interruptible(timeout);    return jiffies_to_msecs(timeout);}
signed long __sched schedule_timeout_interruptible()signed long timeout){    __set_current_state(TASK_INTERRUPTIBLE);    return schedule_timeout(timeout);}signed long __sched schedule_timeout_uninterruptible()signed long timeout){    __set_current_state(TASK_UNINTERRUPTIBLE);    return schedule_timeout(timeout);}
另外還有如下:time_on_timeout(wait_queue_head_t *q, unsigned long  timeout);interruptible_sleep_on_timeout(wait_queue_head_t *q, unsigned long timeout);這兩個將當前進程添加到等待隊列,從而在等待隊列上睡眠,當逾時發生時,進程將被喚醒。 “小王,有關中斷和系統時鐘的咱們也講完了,下次就給你來一個有關係統時鐘的裝置驅動例子,鞏固一下吧,你可要抓緊哦..“
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.