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

          新聞中心

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

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

          在文件OS_CPU.H的末尾聲明了一個(gè)8位變量OSTickDOSCtr,將保存時(shí)鐘節(jié)拍發(fā)生的次數(shù),每發(fā)生11次,調(diào)用DOS的時(shí)鐘節(jié)拍函數(shù)一次,從而實(shí)現(xiàn)與DOS時(shí)鐘的同步。OSTickDOSCtr是專門為PC環(huán)境而聲明的,如果在其他非PC的系統(tǒng)中運(yùn)行μC/OS-II,就不用這種同步方法,直接設(shè)定時(shí)鐘節(jié)拍發(fā)生頻率就行了。

          9.04 OS_CPU_A.ASM

          μC/OS-II的移植需要用戶改寫OS_CPU_A.ASM中的四個(gè)函數(shù):

          OSStartHighRdy()

          OSCtxSw()

          OSIntCtxSw()

          OSTickISR()

          9.04.01 OSStartHighRdy()

          該函數(shù)由SStart()函數(shù)調(diào)用,功能是運(yùn)行優(yōu)先級(jí)最高的就緒任務(wù),在調(diào)用OSStart()之前,用戶必須先調(diào)用OSInit(),并且已經(jīng)至少創(chuàng)建了一個(gè)任務(wù)(請(qǐng)參考OSTaskCreate()和OSTaskCreateExt()函數(shù))。OSStartHighRdy()默認(rèn)指針OSTCBHighRdy指向優(yōu)先級(jí)最高就緒任務(wù)的任務(wù)控制塊(OS_TCB)(在這之前OSTCBHighRdy已由OSStart()設(shè)置好了)。圖F9.3給出了由函數(shù)OSTaskCreate()或OSTaskCreateExt()創(chuàng)建的任務(wù)的堆棧結(jié)構(gòu)。很明顯,OSTCBHighRdy-

          >OSTCBStkPtr指向的是任務(wù)堆棧的頂端。

          函數(shù)OSStartHighRdy()的代碼見程序清單L9.3。

          圖F9.3 任務(wù)創(chuàng)立時(shí)的80x86堆棧結(jié)構(gòu).

          為了啟動(dòng)任務(wù),OSStartHighRdy()從任務(wù)控制塊(OS_TCB)[程序清單L9.3(1)]中找到指向堆棧的指針,然后運(yùn)行POPDS[程序清單L9.3(2)],POPES[程序清單L9.3(3)],POPA[程序清單L9.3(4)],和IRET[程序清單L9.3(5)]指令。此處筆者將任務(wù)堆棧指針保存在任務(wù)控制塊的開頭,這樣使得堆棧指針的存取在匯編語言中更容易操作。

          當(dāng)執(zhí)行了IRET指令后,CPU會(huì)從(SS:SP)指向的堆棧中恢復(fù)各個(gè)寄存器的值并執(zhí)行中斷前的指令。SS:SP+4指向傳遞給任務(wù)的參數(shù)pdata。

          程序清單L 9.3 OSStartHighRdy().

          _OSStartHighRdyPROCFAR

          MOVAX,SEG_OSTCBHighRdy; 載入 DS

          MOVDS,AX;

          LESBX,DWORDPTRDS:_OSTCBHighRdy;SS:SP=OSTCBHighRdy-

          >OSTCBStkPtr (1)

          MOVSS,ES:[BX+2];

          MOVSP,ES:[BX+0];

          ;

          POPDS; 恢復(fù)任務(wù)環(huán)境 (2)

          POPES;(3)

          POPA;(4)

          ;

          IRET; 運(yùn)行任務(wù) (5)

          _OSStartHighRdyENDP

          9.04.02 OSCtxSw()

          OSCtxSw()是一個(gè)任務(wù)級(jí)的任務(wù)切換函數(shù)(在任務(wù)中調(diào)用,區(qū)別于在中斷程序中調(diào)用的

          OSIntCtxSw())。在80x86系統(tǒng)上,它通過執(zhí)行一條軟中斷的指令來實(shí)現(xiàn)任務(wù)切換。軟中斷向量

          指向OSCtxSw()。在μC/OS-II中,如果任務(wù)調(diào)用了某個(gè)函數(shù),而該函數(shù)的執(zhí)行結(jié)果可能造成系統(tǒng)

          任務(wù)重新調(diào)度(例如試圖喚醒了一個(gè)優(yōu)先級(jí)更高的任務(wù)),則在函數(shù)的末尾會(huì)調(diào)用OSSched(),

          如果OSSched()判斷需要進(jìn)行任務(wù)調(diào)度,會(huì)找到該任務(wù)控制塊OS_TCB的地址,并將該地址拷貝到

          OSTCBHighRdy,然后通過宏OS_TASK_SW()執(zhí)行軟中斷進(jìn)行任務(wù)切換。注意到在此過程中,變量

          OSTCBCur始終包含一個(gè)指向當(dāng)前運(yùn)行任務(wù)OS_TCB的指針。程序清單L9.4為OSCtxSw()的代碼。

          圖F9.4是任務(wù)被掛起或被喚醒時(shí)的堆棧結(jié)構(gòu)。在80x86處理器上,任務(wù)調(diào)用OS_TASK_SW()執(zhí)

          行軟中斷指令后[圖F9.4/程序清單L9.4(1)],先向堆棧中壓入返回地址(段地址和偏移量),

          然后是狀態(tài)字寄存器SW。緊接著用PUSHA[圖F9.4/程序清單L9.4(2)],PUSHES[圖F9.4/程序

          清單L9.4(3)],和PUSHDS[圖F9.4/程序清單L9.4(4)]保存任務(wù)運(yùn)行環(huán)境。最后用OSCtxSw()在

          任務(wù)OS_TCB中保存SS和SP寄存器。

          任務(wù)環(huán)境保存完后,將調(diào)用用戶定義的對(duì)外接口函數(shù)OSTaskSwHook()[程序清單L9.4(6)]。

          請(qǐng)注意,此時(shí)OSTCBCur指向當(dāng)前任務(wù)OS_TCB,OSTCBHighRdy指向新任務(wù)的OS_TCB。在

          OSTaskSwHook()中,用戶可以訪問這兩個(gè)任務(wù)的OS_TCB。如果不使用對(duì)外接口函數(shù),請(qǐng)?jiān)陬^文

          件中把相應(yīng)的開關(guān)選項(xiàng)關(guān)閉,加快任務(wù)切換的速度。

          程序清單L9.4 OSCtxSw().

          _OSCtxSwPROCFAR(1)

          ;

          PUSHA; 保存當(dāng)前任務(wù)環(huán)境 (2)

          PUSHES (3)

          PUSHDS (4)

          ;

          MOVAX,SEG_OSTCBCur; 載入DS

          MOVDS,AX

          ;

          LESBX,DWORDPTRDS:_OSTCBCur;OSTCBCur->OSTCBStkPtr=SS:S(5)

          MOVES:[BX+2],SS

          MOVES:[BX+0],SP

          ;

          CALLFARPTR_OSTaskSwHook(6)

          ;

          MOVAX,WORDPTRDS:_OSTCBHighRdy+2;OSTCBCur=OSTCBHighRdy(7)

          MOVDX,WORDPTRDS:_OSTCBHighRdy

          MOVWORDPTRDS:_OSTCBCur+2,AX

          MOVWORDPTRDS:_OSTCBCur,DX

          ;

          MOVAL,BYTEPTRDS:_OSPrioHighRdy;OSPrioCur=OSPrioHighRdy(8)

          MOVBYTEPTRDS:_OSPrioCur,AL

          ;

          LESBX,DWORDPTRDS:_OSTCBHighRdy;SS:SP=OSTCBHighRdy-

          >OSTCBStkPtr (9)

          MOVSS,ES:[BX+2]

          MOVSP,ES:[BX]

          ;

          POPDS; 載入新任務(wù)的CPU環(huán)境 (10)

          POPES (11)

          POPA (12)

          ;

          IRET; 返回新任務(wù) (13)

          ;

          _OSCtxSwENDP

          從對(duì)外接口函數(shù)OSTaskSwHook()返回后,由于任務(wù)的更替,變量OSTCBHighRdy被拷貝到

          OSTCBCur中[程序清單L9.4(7)],同樣,OSPrioHighRdy被拷貝到OSPrioCur中[程序清單

          L9.4(8)]。OSCtxSw()將載入新任務(wù)的CPU環(huán)境,首先從新任務(wù)OS_TCB中取出SS和SP寄存器的值

          [圖F9.4(6)/程序清單L9.4(9)],然后運(yùn)行POPDS[圖F9.4(7)/程序清單L9.4(10)],POPES

          [圖F9.4(8)/程序清單L9.4(11)],POPA[圖F9.4(9)/程序清單L9.4(12)]取出其他寄存器的值,

          最后用中斷返回指令I(lǐng)RET[圖F9.4(10)/L9.4(13)]完成任務(wù)切換。

          需要注意的是在運(yùn)行OSCtxSw()和OSTaskSwHook()函數(shù)期間,中斷是禁止的。

          9.04.03 OSIntCtxSw()

          在μC/OS-II中,由于中斷的產(chǎn)生可能會(huì)引起任務(wù)切換,在中斷服務(wù)程序的最后會(huì)調(diào)用



          關(guān)鍵詞:

          評(píng)論


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