新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > μC/OS-II在80x86上的移植

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

        作者: 時間:2016-10-08 來源:網絡 收藏

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

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

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

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

        中斷向量表。

        在μC/OS-II中, 當調用OSStart()啟動多任務環境后, 時鐘中斷的作用是非常重要的。 但在PC

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

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

        main()函數:

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

        至少創立一個任務

        當初始化工作完成后調用OSStart()啟動多任務環境

        第一個運行的任務:

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

        將時鐘節拍頻率從18.20648改為200Hz

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

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

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

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

        程序清單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; 保存被中斷任務的CPU環境

        PUSHES

        PUSHDS

        ;

        MOVAX,SEG_OSTickDOSCtr; 載入 DS

        MOVDS,AX

        ;

        INCBYTEPTR_OSIntNesting; 標示 uC/OS-II 進入中斷

        ;

        DECBYTEPTRDS:_OSTickDOSCtr

        CMPBYTEPTRDS:_OSTickDOSCtr,0

        JNESHORT_OSTickISR1; 每11個時鐘節拍(18.206Hz)調用DOS時鐘中斷

        ;

        MOVBYTEPTRDS:_OSTickDOSCtr,11

        INT081H; 調用DOS時鐘中斷處理過程

        JMPSHORT_OSTickISR2

        _OSTickISR1:

        MOVAL,20H; 向中斷優先級控制器發送命令,清除標志位.

        MOVDX,20H;

        OUTDX,AL;

        ;

        _OSTickISR2:

        CALLFARPTR_OSTimeTick; 調用OSTimeTick()函數

        ;

        CALLFARPTR_OSIntExit; 標示uC/OS-II退出中斷

        ;

        POPDS; 恢復被中斷任務的CPU環境

        POPES

        POPA

        ;

        IRET; 返回被中斷任務

        ;

        _OSTickISRENDP

        如果不更改DOS下的時鐘中斷頻率(保持18.20648Hz),OSTickISR()函數還可以簡化。程序清單L9.8為18.2Hz的OSTickISR()函數的偽碼。同樣,函數開頭要保存所有的CPU寄存器[程序清單L9.8(1)],將OSIntNesting加1[程序清單L9.8(2)]。接下來調用DOS的時鐘中斷處理過程[程序清單L9.8(3)],此處就不需要清除中斷優先級控制器的操作了,因為DOS的時鐘中斷處理中包含了這一過程。然后調用OSTimeTick()檢查任務的延時是否結束[程序清單L9.8(4)], 最后調用OSInt Exit()[程序清單L9.8(5)]。 結束部分是恢復CPU寄存器的內容[程序清單L9.8(6)],執行IRET指令返回被中斷的任務。如果采用8.2Hz的OSTickISR()函數,系統初始化過程就不用調用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中的六個函數:



        關鍵詞:

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 黑龙江省| 二连浩特市| 香格里拉县| 磐安县| 叙永县| 沙洋县| 龙南县| 自贡市| 崇文区| 景德镇市| 临海市| 东乡族自治县| 山东| 乌兰县| 呼和浩特市| 嘉祥县| 武鸣县| 九龙县| 丹巴县| 昌乐县| 射阳县| 通辽市| 弥渡县| 盐亭县| 盱眙县| 昭苏县| 惠来县| 娱乐| 枞阳县| 山丹县| 开封市| 石渠县| 古交市| 广丰县| 新竹县| 迁安市| 长兴县| 永嘉县| 潜山县| 南昌市| 花垣县|