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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > μC/OS-II在80x86上的移植

          μC/OS-II在80x86上的移植

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

          之間。但由于PC環(huán)境的特殊性,時鐘節(jié)拍由硬件產(chǎn)生,間隔54.93ms(18.20648Hz)。我們將時

          鐘節(jié)拍頻率設(shè)為200Hz。PC時鐘節(jié)拍的中斷向量為0x08,μC/OS-II將此向量截取,指向了μC/OS

          的中斷服務(wù)函數(shù)OSTickISR(),而原先的中斷向量保存在中斷129(0x81)中。為滿足DOS的需要,

          原先的中斷服務(wù)還是每隔54.93ms(實際上還要短些)調(diào)用一次。圖F9.6為安裝μC/OS-II前后的

          中斷向量表。

          在μC/OS-II中, 當(dāng)調(diào)用OSStart()啟動多任務(wù)環(huán)境后, 時鐘中斷的作用是非常重要的。 但在PC

          環(huán)境下,啟動μC/OS-II之前就已經(jīng)有時鐘中斷發(fā)生了,實際上我們希望在μC/OS-II初始化完成之后再發(fā)生時鐘中斷,調(diào)用OSTickISR()。與此相關(guān)的有下述過程:

          PC_DOSSaveReturn()函數(shù)(參看PC.C):該函數(shù)由main()調(diào)用,任務(wù)是取得DOS下時鐘中斷向量,并將其保存在0x81中。

          main()函數(shù):

          設(shè)定中斷向量0x80指向任務(wù)切換函數(shù)OSCtxSw()

          至少創(chuàng)立一個任務(wù)

          當(dāng)初始化工作完成后調(diào)用OSStart()啟動多任務(wù)環(huán)境

          第一個運(yùn)行的任務(wù):

          設(shè)定中斷向量0x08指向函數(shù)OSTickISR()

          將時鐘節(jié)拍頻率從18.20648改為200Hz

          圖F9.6 PC 中斷向量表(IVT).

          在程序清單L9.6給出了函數(shù)OSTickISR()的偽碼。和μC/OS-II中的其他中斷服務(wù)程序一樣,OSTickISR()首先在被中斷任務(wù)堆棧中保存CPU寄存器的值,然后調(diào)用OSIntEnter()。

          μC/OS-II要求在中斷服務(wù)程序開頭調(diào)用OSIntEnter(), 其作用是將記錄中斷嵌套層數(shù)的全局

          變量OSIntNesting加1。如果不調(diào)用OSIntEnter(),直接將OSIntNesting加1也是允許的。接下來計數(shù)器OSTickDOSCtr減1[程序清單L9.6(3)],每發(fā)生11次中斷,OSTickDOSCtr減到0,則調(diào)用DOS的時鐘中斷處理函數(shù)[程序清單L9.6(4)],調(diào)用間隔大約是54.93ms。如果不調(diào)用DOS時鐘中斷函數(shù),則向中斷優(yōu)先級控制器(PIC)發(fā)送命令清除中斷標(biāo)志。如果調(diào)用了DOS中斷,則此項操作可免,因為在DOS的中斷程序中已經(jīng)完成了。隨后,OSTickISR()調(diào)用OSTimeTick(),檢查所有處于延時等待狀態(tài)的任務(wù),判斷是否有延時結(jié)束就緒的任務(wù)[程序清單L9.6(6)]。 在OSTickISR()的最后調(diào)用OSIntExit(), 如果在中斷中 (或其他嵌套的中斷)有更高優(yōu)先級的任務(wù)就緒,并且當(dāng)前中斷為中斷嵌套的最后一層。OSIntExit()將進(jìn)行任務(wù)調(diào)度。注意如果進(jìn)行了任務(wù)調(diào)度,OSIntExit()將不再返回調(diào)用者,而是用新任務(wù)的堆棧中的寄存器數(shù)值恢復(fù)CPU現(xiàn)場,然后用IRET實現(xiàn)任務(wù)切換。如果當(dāng)前中斷不是中斷嵌套的最后一層,或中斷中沒有改變?nèi)蝿?wù)的就緒狀態(tài),OSIntExit()將返回調(diào)用者OSTickISR(),最后OSTickISR()返回被中斷的任務(wù)。

          程序清單L9.7給出了OSTickISR()的完整代碼。

          程序清單L 9.6 OSTickISR()偽碼.

          voidOSTickISR(void)

          {

          Saveprocessorregisters;(1)

          OSIntNesting++;(2)

          OSTickDOSCtr—-;(3)

          if(OSTickDOSCtr==0){

          ChainintoDOSbyexecutingan'INT81H'instruction;(4)

          }else{

          SendEOIcommandtoPIC(PriorityInterruptController);(5)

          }

          OSTimeTick();(6)

          OSIntExit(); (7)

          Restoreprocessorregisters;(8)

          Executeareturnfrominterruptinstruction(IRET);(9)

          }

          程序清單L9.7 OSTickISR().

          _OSTickISRPROCFAR

          ;

          PUSHA; 保存被中斷任務(wù)的CPU環(huán)境

          PUSHES

          PUSHDS

          ;

          MOVAX,SEG_OSTickDOSCtr; 載入 DS

          MOVDS,AX

          ;

          INCBYTEPTR_OSIntNesting; 標(biāo)示 uC/OS-II 進(jìn)入中斷

          ;

          DECBYTEPTRDS:_OSTickDOSCtr

          CMPBYTEPTRDS:_OSTickDOSCtr,0

          JNESHORT_OSTickISR1; 每11個時鐘節(jié)拍(18.206Hz)調(diào)用DOS時鐘中斷

          ;

          MOVBYTEPTRDS:_OSTickDOSCtr,11

          INT081H; 調(diào)用DOS時鐘中斷處理過程

          JMPSHORT_OSTickISR2

          _OSTickISR1:

          MOVAL,20H; 向中斷優(yōu)先級控制器發(fā)送命令,清除標(biāo)志位.

          MOVDX,20H;

          OUTDX,AL;

          ;

          _OSTickISR2:

          CALLFARPTR_OSTimeTick; 調(diào)用OSTimeTick()函數(shù)

          ;

          CALLFARPTR_OSIntExit; 標(biāo)示uC/OS-II退出中斷

          ;

          POPDS; 恢復(fù)被中斷任務(wù)的CPU環(huán)境

          POPES

          POPA

          ;

          IRET; 返回被中斷任務(wù)

          ;

          _OSTickISRENDP

          如果不更改DOS下的時鐘中斷頻率(保持18.20648Hz),OSTickISR()函數(shù)還可以簡化。程序清單L9.8為18.2Hz的OSTickISR()函數(shù)的偽碼。同樣,函數(shù)開頭要保存所有的CPU寄存器[程序清單L9.8(1)],將OSIntNesting加1[程序清單L9.8(2)]。接下來調(diào)用DOS的時鐘中斷處理過程[程序清單L9.8(3)],此處就不需要清除中斷優(yōu)先級控制器的操作了,因為DOS的時鐘中斷處理中包含了這一過程。然后調(diào)用OSTimeTick()檢查任務(wù)的延時是否結(jié)束[程序清單L9.8(4)], 最后調(diào)用OSInt Exit()[程序清單L9.8(5)]。 結(jié)束部分是恢復(fù)CPU寄存器的內(nèi)容[程序清單L9.8(6)],執(zhí)行IRET指令返回被中斷的任務(wù)。如果采用8.2Hz的OSTickISR()函數(shù),系統(tǒng)初始化過程就不用調(diào)用PC_SetTickRate(),同時將文件OS_CFG.H中的常量OS_TICKS_PER_SEC由200改為18。

          程序清單L9.9給出了18.2HzOSTickISR()的完整代碼。

          程序清單L9.818.2Hz OSTickISR()偽碼.

          voidOSTickISR(void)

          {

          Saveprocessorregisters;(1)

          OSIntNesting++;(2)

          ChainintoDOSbyexecutingan'INT81H'instruction;(3)

          OSTimeTick();(4)

          OSIntExit(); (5)

          Restoreprocessorregisters;(6)

          Executeareturnfrominterruptinstruction(IRET);(7)

          }

          9.05 OS_CPU_C.C

          μC/OS-II的移植需要用戶改寫OS_CPU_C.C中的六個函數(shù):



          關(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); })();