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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > μC/OS-II的內(nèi)核結(jié)構(gòu)

          μC/OS-II的內(nèi)核結(jié)構(gòu)

          作者: 時(shí)間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

          上述兩步完成以后,用戶可以開始服務(wù)于叫中斷的設(shè)備了[L3.15(3)]。這一段完全取決于應(yīng)用。μC/OS-Ⅱ允許中斷嵌套,因?yàn)?mu;C/OS-Ⅱ跟蹤嵌套層數(shù)OSIntNesting。然而,為允許中斷嵌套,在多數(shù)情況下,用戶應(yīng)在開中斷之前先清中斷源。

          調(diào)用脫離中斷函數(shù)OSIntExit()[L3.15(4)]標(biāo)志著中斷服務(wù)子程序的終結(jié),OSIntExit()將中斷嵌套層數(shù)計(jì)數(shù)器減1。當(dāng)嵌套計(jì)數(shù)器減到零時(shí),所有中斷,包括嵌套的中斷就都完成了,此時(shí)μC/OS-Ⅱ要判定有沒有優(yōu)先級較高的任務(wù)被中斷服務(wù)子程序(或任一嵌套的中斷)喚醒了。如果有優(yōu)先級高的任務(wù)進(jìn)入了就緒態(tài),μC/OS-Ⅱ就返回到那個(gè)高優(yōu)先級的任務(wù),OSIntExit()返回到調(diào)用點(diǎn)[L3.15(5)]。保存的寄存器的值是在這時(shí)恢復(fù)的,然后是執(zhí)行中斷返回指令[L3.16(6)]。注意,如果調(diào)度被禁止了(OSIntNesting>0),μC/OS-Ⅱ?qū)⒈环祷氐奖恢袛嗔说娜蝿?wù)。

          以上描述的詳細(xì)解釋如圖F3.5所示。中斷來到了[F3.5(1)]但還不能被被CPU識別,也許是因?yàn)橹袛啾?mu;C/OS-Ⅱ或用戶應(yīng)用程序關(guān)了,或者是因?yàn)镃PU還沒執(zhí)行完當(dāng)前指令。一旦CPU響應(yīng)了這個(gè)中斷[F3.5(2)],CPU的中斷向量(至少大多數(shù)微處理器是如此)跳轉(zhuǎn)到中斷服務(wù)子程序[F3.5(3)]。如上所述,中斷服務(wù)子程序保存CPU寄存器(也叫做CPUcontext)[F3.5(4)],一旦做完,用戶中斷服務(wù)子程序通知μC/OS-Ⅱ進(jìn)入中斷服務(wù)子程序了,辦法是調(diào)用OSIntEnter()或者給SIntNesting直接加1[F3.5(5)]。然后用戶中斷服務(wù)代碼開始執(zhí)行[F3.5(6)]。用戶中斷服務(wù)中做的事要盡可能地少,要把大部分工作留給任務(wù)去做。中斷服務(wù)子程序通知某任務(wù)去做事的手段是調(diào)用以下函數(shù)之一:OSMboxPost(),OSQPost(),OSQPostFront(),OSSemPost()。中斷發(fā)生并由上述函數(shù)發(fā)出消息時(shí),接收消息的任務(wù)可能是,也可能不是掛起在郵箱、隊(duì)列或信號量上的任務(wù)。用戶中斷服務(wù)完成以后,要調(diào)用OSIntExit()[F3.5(7)]。從時(shí)序圖上可以看出,對被中斷了的任務(wù)說來,如果沒有高優(yōu)先級的任務(wù)被中斷服務(wù)子程序激活而進(jìn)入就緒態(tài),OSIntExit()只占用很短的運(yùn)行

          時(shí)間。進(jìn)而,在這種情況下,CPU寄存器只是簡單地恢復(fù)[F3.5(8)]并執(zhí)行中斷返回指令

          [F3.5(9)]。如果中斷服務(wù)子程序使一個(gè)高優(yōu)先級的任務(wù)進(jìn)入了就緒態(tài),則OSIntExit()將占用

          較長的運(yùn)行時(shí)間,因?yàn)檫@時(shí)要做任務(wù)切換[F3.5(10)]。新任務(wù)的寄存器內(nèi)容要恢復(fù)并執(zhí)行中

          斷返回指令[F3.5(12)]。

          圖 3.5 中斷服務(wù)

          進(jìn)入中斷函數(shù) OSIntEnter()的代碼如程序清單 L3.16 所示,從中斷服務(wù)中退出函數(shù)

          OSIntExit()的代碼如程序清單 L3.17 所示。如前所述,OSIntEnter()所做的事是非常少的。

          程序清單 L3.16 通知μC/OS-Ⅱ,中斷服務(wù)子程序開始了.

          voidOSIntEnter(void)

          {

          OS_ENTER_CRITICAL();

          OSIntNesting++;

          OS_EXIT_CRITICAL();

          }

          恢復(fù)所有CPU寄存器; (5)

          程序清單 L3.17 通知μC/OS-Ⅱ,脫離了中斷服務(wù)

          voidOSIntExit(void)

          {

          OS_ENTER_CRITICAL();(1)

          if((--OSIntNesting|OSLockNesting)==0){(2)

          OSIntExitY=OSUnMapTbl[OSRdyGrp];(3)

          OSPrioHighRdy=(INT8U)((OSIntExitY3)+

          OSUnMapTbl[OSRdyTbl[OSIntExitY]]);

          if(OSPrioHighRdy!=OSPrioCur){

          OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];

          OSCtxSwCtr++;

          OSIntCtxSw();(4)

          }

          }

          OS_EXIT_CRITICAL();

          }

          OSIntExit()看起來非常像OSSched()。但有三點(diǎn)不同。第一點(diǎn),OSIntExit()使中斷

          嵌套層數(shù)減1[L3.17(2)]而調(diào)度函數(shù)OSSched()的調(diào)度條件是:中斷嵌套層數(shù)計(jì)數(shù)器和鎖定

          嵌套計(jì)數(shù)器(OSLockNesting)二者都必須是零。第二個(gè)不同點(diǎn)是,OSRdyTbl[]所需的檢索

          值Y是保存在全程變量OSIntExitY中的[L3.17(3)]。這是為了避免在任務(wù)棧中安排局部變

          量。這個(gè)變量在哪兒和中斷任務(wù)切換函數(shù)OSIntCtxSw()有關(guān),(見9.04.03節(jié),中斷任務(wù)

          切換函數(shù))。最后一點(diǎn),如果需要做任務(wù)切換,OSIntExit()將調(diào)用OSIntCtxSw()[L3.17

          (4)]而不是調(diào)用OS_TASK_SW(),正像在OSSched()函數(shù)中那樣。

          調(diào)用中斷切換函數(shù)OSIntCtxSw()而不調(diào)用任務(wù)切換函數(shù) OS_TASK_SW(),有兩個(gè)原因,

          首先是,如程序清單中L3.5(1)和圖F3.6(1)所示,一半的工作,即CPU寄存器入棧的工作

          已經(jīng)做完了。第二個(gè)原因是,在中斷服務(wù)子程序中調(diào)用OSIntExit()時(shí),將返回地址推入

          了堆棧[L3.15(4)和F3.6(2)]。OSIntExit()中的進(jìn)入臨界段函數(shù)OS_ENTER_CRITICAL()或

          許將CPU的狀態(tài)字也推入了堆棧L3.7(1)和F3.6(3)。這取決于中斷是怎么被關(guān)掉的(見第8

          章移植μC/OS-Ⅱ)。最后,調(diào)用OSIntCtxSw()時(shí)的返回地址又被推入了堆棧[L3.17(4)和

          F3.1(4)],除了棧中不相關(guān)的部分,當(dāng)任務(wù)掛起時(shí),棧結(jié)構(gòu)應(yīng)該與μC/OS-Ⅱ所規(guī)定的完全

          一致。OSIntCtxSw()只需要對棧指針做簡單的調(diào)整,如圖F3.6(5)所示。換句話說,調(diào)整

          棧結(jié)構(gòu)要保證所有掛起任務(wù)的棧結(jié)構(gòu)看起來是一樣的。

          圖3.6中斷中的任務(wù)切換函數(shù)OSIntCtxSw()調(diào)整棧結(jié)構(gòu)

          有的微處理器,像Motorola68HC11中斷發(fā)生時(shí)CPU寄存器是自動入棧的,且要想允許

          中斷嵌套的話,在中斷服務(wù)子程序中要重新開中斷,這可以視作一個(gè)優(yōu)點(diǎn)。確實(shí),如果用

          戶中斷服務(wù)子程序執(zhí)行得非常快,用戶不需要通知任務(wù)自身進(jìn)入了中斷服務(wù),只要不在中

          斷服務(wù)期間開中斷,也不需要調(diào)用OSIntEnter()或OSIntNesting加1。程序清單L3。18

          中的示意代碼表示這種情況。一個(gè)任務(wù)和這個(gè)中斷服務(wù)子程序通訊的唯一方法是通過全程

          變量。



          關(guān)鍵詞:

          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁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); })();