3.0 中斷管理

因爲在任務調度中涉及到時間片這個概念,因而轉而先學習下一章,中斷管理和時間管理,一共倆小節。html

 

一、前言app

  ucos是實時多任務操做系統,系統的實時性主要體如今對中斷的響應上;除了響應時間,ucos要求對中斷服務程序(ISR)運行時間不能過長。在以前分析過的任務刪除函數中,由於涉及到有關全局變量的操做,函數關掉了中斷;而爲了不關中斷的時間太長,因而在刪除任務的過程當中又開了一次中斷。函數

  對於不一樣的硬件系統,ISR的編寫時徹底不一樣的,由於這涉及到對底層寄存器的操做,操做系統中提供的中斷管理函數位於core.c中。學習

  事實上,任務的調度大多也依靠中斷。ISR在發現了有更高優先級的就緒任務就會進行任務調度。當操做系統有其餘的外中斷時,如定時器中斷,外中斷,串口中斷等,只要中斷時打開的,並且正在運行的任務並無關中斷,就會響應中斷,這時任務就被切換了。this

  這一節只是涉及中斷管理,暫不涉及中斷設計。spa

 

二、ucos中斷的實現操作系統

上圖:設計

 

 

 

從圖中看到有三個待學習的函數:OSIntEnter()、OSIntExit()、OSIntCtxSw()code

 

三、OSIntEnter()函數orm

源碼

1 void  OSIntEnter (void)
2 {
3     if (OSRunning == OS_TRUE) {
4         if (OSIntNesting < 255u) {
5             OSIntNesting++;                      /* Increment ISR nesting level                        */
6         }
7     }
8 }

代碼中有一個全局變量OSIntNesting非常重要,表示ISR的嵌套層數,每進入一次中斷則將其加1。

注意下,在與這個函數對應的OSIntExit()中也有相似處理OSIntNesting的代碼,只不過是每退出一次中斷則將其減1。

 

四、時鐘中斷中的任務切換函數OSIntExit()函數

     ucos中任務調度分兩種:任務級任務調度和中斷級任務調度。這兒先就着中斷管理部分把中斷級任務調度講述了。

     ucos在每一個時鐘滴答進入時鐘中斷服務程序,若是有比目前運行的任務更高優先級的任務就緒,在須要時進行一次任務調度。這個任務調度函數表示OSIntExit()。

     在時鐘中斷的時候,緊接着OSTimeTick,操做系統調用OSIntExit()實現任務的切換。

源碼

 1 void  OSIntExit (void)
 2 {
 3 #if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
 4     OS_CPU_SR  cpu_sr = 0;
 5 #endif
 6 
 7 
 8 
 9     if (OSRunning == OS_TRUE) {
10         OS_ENTER_CRITICAL();
11         if (OSIntNesting > 0) {                            /* Prevent OSIntNesting from wrapping       */
12             OSIntNesting--;
13         }
14         if (OSIntNesting == 0) {                           /* Reschedule only if all ISRs complete ... */
15             if (OSLockNesting == 0) {                      /* ... and not locked.                      */
16                 OS_SchedNew();
17                 if (OSPrioHighRdy != OSPrioCur) {          /* No Ctx Sw if current task is highest rdy */
18                     OSTCBHighRdy  = OSTCBPrioTbl[OSPrioHighRdy];
19 #if OS_TASK_PROFILE_EN > 0
20                     OSTCBHighRdy->OSTCBCtxSwCtr++;         /* Inc. # of context switches to this task  */
21 #endif
22                     OSCtxSwCtr++;                          /* Keep track of the number of ctx switches */
23                     OSIntCtxSw();                          /* Perform interrupt level ctx switch       */
24                 }
25             }
26         }
27         OS_EXIT_CRITICAL();
28     }
29 }

line 9,肯定在多任務已經啓動的時候才調度。

然後關中斷。

line 14,當肯定已無中斷嵌套時(若是有嵌套,要先執行那個任務),而且調度器還未上鎖,執行OS_SchedNew ()。(嵌套一下!)

**********************************************************************************************

OS_SchedNew ()源碼

 1 //FIND HIGHEST PRIORITY TASK READY TO RUN
 2 
 3 static  void  OS_SchedNew (void)
 4 {
 5 #if OS_LOWEST_PRIO <= 63                         /* See if we support up to 64 tasks                   */
 6     INT8U   y;
 7 
 8 
 9     y             = OSUnMapTbl[OSRdyGrp];
10     OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
11 #else                                            /* We support up to 256 tasks                         */
12     INT8U   y;
13     INT16U *ptbl;
14 
15 
16     if ((OSRdyGrp & 0xFF) != 0) {
17         y = OSUnMapTbl[OSRdyGrp & 0xFF];
18     } else {
19         y = OSUnMapTbl[(OSRdyGrp >> 8) & 0xFF] + 8;
20     }
21     ptbl = &OSRdyTbl[y];
22     if ((*ptbl & 0xFF) != 0) {
23         OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl & 0xFF)]);
24     } else {
25         OSPrioHighRdy = (INT8U)((y << 4) + OSUnMapTbl[(*ptbl >> 8) & 0xFF] + 8);
26     }
27 #endif
28 }

其函數功能是找到優先級最高的任務,具體實現即是修改全局變量中有關優先級的變量。

*****************************************************************************************************

line 17,若是最高優先級就緒任務不是當前運行任務的話(若是是,便沒有調度的必要了),則進行調度。

這兒有一個新函數,叫作OSIntCtxSw()。

 

五、中斷中任務切換函數OSIntCtxSw

OSIntCtxSw()纔是真正在中斷程序中進行實際的任務切換的地方。

源碼

 1 //PERFORM A CONTEXT SWITCH (From an ISR)
 2 
 3 void OSIntCtxSw()
 4 {
 5     DWORD n = 0;
 6 
 7     if(!(SS_SP->Exit)) {
 8         n = SuspendThread(SS_SP->Handle);  9     }
10 
11     OSTaskSwHook();
12 
13     OSTrace( OBJ_SW, PT_SW_INT, OSTCBHighRdy, 0, OSPrioCur,OSPrioHighRdy,0 ); 14 
15     OSTCBCur = OSTCBHighRdy;
16     OSPrioCur = OSPrioHighRdy;
17     SS_SP = (OS_EMU_STK*) OSTCBHighRdy->OSTCBStkPtr;
18 
19     ResumeThread(SS_SP->Handle); 20 }

這個函數的具體實現,在不一樣平臺是不同的。這兒先不分解,等到學習移植的時候在看。

 

六、結束

至此,中斷管理第一部分完結,下一節涉及時間管理。

相關文章
相關標籤/搜索