<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > 實時操作系統(tǒng)的任務調度原因分析

          實時操作系統(tǒng)的任務調度原因分析

          作者: 時間:2016-12-01 來源:網(wǎng)絡 收藏
          最近看了一些實時操作系統(tǒng)的源碼,關于任務調度是實時操作系統(tǒng)的重要組成部分,但是何時發(fā)生調度,怎樣才能發(fā)生調度卻不是非常的清晰,書中一本而言所說的都是“如果有更高優(yōu)先級任務就緒,就會發(fā)生調度”,這會讓很多的讀者產(chǎn)生很大的歧義:

          在當前的任務中,并沒有關于就緒表等全局變量的訪問,當前的任務也有自己的堆??臻g,我并不知道是否有更高優(yōu)先級的任務就緒,之所以產(chǎn)生這些疑惑是沒有搞清楚什么時候發(fā)生調度,怎么知道需要調度。當前運行的任務,一般而言就是所謂的最高優(yōu)先級的任務,在沒有訪問一系列全局變量的過程中,內核又是如何知道存在一個更高優(yōu)先級的任務被就緒了呢?

          一般而言,對于搶占型實時內核,一般在同步、或者通信的過程中會主動的調用調度函數(shù),或者任務的掛起函數(shù)中使用調度函數(shù),其他的函數(shù)中并沒有發(fā)現(xiàn)其他的調度函數(shù),而且這種情況下都是手動的調度任務,那么在沒有這些函數(shù)的情況下,實時操作系統(tǒng)中內核是如何知道需要調度的呢?

          我仔細查找了一些資料,別人總結了一些操作系統(tǒng)發(fā)生調度的原因如下:
            (1)正在執(zhí)行的進程執(zhí)行完畢。這時,如果不選擇新的就緒進程執(zhí)行,將浪費處理機資源。
            (2)執(zhí)行中進程自己調用阻塞原語將白己阻塞起來進入睡眠等狀態(tài)。
            (3)執(zhí)行中進程調用了P原語操作,從而因資源不足而被阻塞;或調用了v原語操作激活了等待資源的進程隊列。
            (4)執(zhí)行中進程提出I/O請求后被阻塞。
            (5)在分時系統(tǒng)中時間片已經(jīng)用完。
            (6)在執(zhí)行完系統(tǒng)調用等系統(tǒng)程序后返回用戶進程時,這時可看作系統(tǒng)進程執(zhí)行完畢,從而可調度選擇一新的用戶進程執(zhí)行。
            以上都是在可剝奪方式下的引起進程調度的原因。在CPU執(zhí)行方式是可剝奪時.還有
            (7)就緒隊列中的某進程的優(yōu)先級變得高于當前執(zhí)行進程的優(yōu)先級,從而也將引發(fā)進程調度。
          我對比了在實時操作系統(tǒng)中經(jīng)常使用的調度方式發(fā)現(xiàn),原因(2)、(3)、(7)是主要的原因,其他的一般在實時操作系統(tǒng)中很難找到。但是這還是不能回答什么時候發(fā)生調度這個問題。

          我認為在實時操作系統(tǒng)中發(fā)生調度的主要有兩個部分:
          (1)自身需要睡眠等待,必須手動的調用調度函數(shù)(信息量,或者通信機制)。
          (2)發(fā)生中斷過,當執(zhí)行完中斷服務函數(shù)以后,需要重新調度。

          其中原因(2)是我們在分析實時操作系統(tǒng)中實時性能的主要因素,很多人又會有很多的疑問,如果操作系統(tǒng)中很少使用中斷,實質上在實時系統(tǒng)中必須存在的一個中斷就是時間節(jié)拍中斷,這個中斷的存在就能保證實時操作系統(tǒng)的實時型。這個時間節(jié)拍選擇也是設計過程中必須注意的。我們可以參看uC/OS-II的時間節(jié)拍代碼,其中完成了所有對非任務掛起的任務的就緒操作(時間到期),這時也就知道了那個任務需要我們調度。在其他的中斷服務函數(shù)執(zhí)行完成以后也就需要那個任務需要被執(zhí)行,進而實現(xiàn)了實時操作。

          本文引用地址:http://www.ex-cimer.com/article/201612/324518.htm

          void OSTimeTick (void)
          {
          #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPUstatusregister */
          OS_CPU_SR cpu_sr;
          #endif
          OS_TCB *ptcb;

          OSTimeTickHook(); /* Call user definable hook */
          #if OS_TIME_GET_SET_EN > 0
          OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
          OSTime++;
          OS_EXIT_CRITICAL();
          #endif
          if (OSRunning == TRUE) {
          ptcb = OSTCBList; /* Point at first TCB in TCB list */
          while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { /* Go through all TCBs in TCB list */
          OS_ENTER_CRITICAL();
          if (ptcb->OSTCBDly != 0) { /* Delayed or waiting for event with TO */
          if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
          if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */
          OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make task R-to-R (timed out)*/
          OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
          } else {
          /* Yes, Leave 1 tick to prevent ... */
          ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */
          } /* ... suspension is removed. */
          }
          }
          ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
          OS_EXIT_CRITICAL();
          }
          }
          }

          從上面的代碼中我們可以知道每個任務都會被掃描一次,檢測是否能夠就緒,如果能夠就緒就將就緒表中的值設置,這樣也就知道了是否有更高優(yōu)先級的任務就緒,是否需要調度操作。因為時間節(jié)拍中斷的不斷發(fā)生就能保證最高優(yōu)先級任務的發(fā)生。因此時間節(jié)拍中斷函數(shù)是在實時操作系統(tǒng)中非常重要的函數(shù)之一。當然任務之間切換以及在中斷中切換到新的任務中的切換代碼也是非常重要的,但是這些一般涉及到CPU寄存器的值,需要匯編代碼實現(xiàn)。
          因為中斷完成以后很多的任務可能因為信號量等信息的釋放已經(jīng)就緒,這時候必然需要任務的調度操作,這時候也就知道了那個任務是最高優(yōu)先級的,那個任務應該被執(zhí)行。這時也就是發(fā)生調度的時刻。

          在UC/OS-II中通常采用關閉中斷的方式進入臨界區(qū),因為關閉了中斷,所有的中斷服務函數(shù)都不會被執(zhí)行,也就不會發(fā)生任務的調度。那么只有一個情況才會發(fā)生調度,也就是任務自身需要睡眠,手動選擇調度函數(shù),但是在臨界區(qū)中不應該發(fā)生睡眠等,因此也就不可能手動調度,因此所有發(fā)生調度的可能都被清除了,這樣也就保證了臨界區(qū)代碼的安全性。



          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();