新聞中心

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

μC/OS-II在51單片機上的移植

作者: 時間:2012-04-27 來源:網(wǎng)絡(luò) 收藏

4.1 任務(wù)堆棧初始化函數(shù)OSTaskStkInit()
此函數(shù)是在任務(wù)創(chuàng)建函數(shù)OSTaskCreat()或OSTaskCreatExt()中調(diào)用的。因為系統(tǒng)為每個任務(wù)申請了一個數(shù)組作為棧,當(dāng)一個任務(wù)運行時,就把堆棧指針指向本任務(wù)的棧,任務(wù)堆棧初始化函數(shù)就是在任務(wù)創(chuàng)建時將要創(chuàng)建任務(wù)的堆棧進行初始化。但C51的堆棧指針SP是8位的,只能在片內(nèi)RAM的256個字節(jié)內(nèi)尋址。因其尋址空間有限且SP唯一,不能像DSP或ARM那樣為每一段程序或每一種模式定義堆棧,需小心管理堆??臻g。為了適應(yīng)上述情況,需要換一種思路,不是讓SP去指向各任務(wù)堆棧空間,而是把各任務(wù)堆??臻g的內(nèi)容復(fù)制到系統(tǒng)棧中。至于堆棧數(shù)組空間要有多大以及堆棧數(shù)組空間里放些什么內(nèi)容,可以借鑒keil中中斷函數(shù)的壓棧情況,當(dāng)中斷函數(shù)不指定寄存器組時,編譯器一般將PC、ACC、B、DPTR、PSW、R0~R7寄存器入棧,其中PC和DPTR是雙字節(jié)的,其它都是單字節(jié)的,一共15個字節(jié),所以把堆棧數(shù)組設(shè)計成至少15個字節(jié)的,以保證任務(wù)所用的寄存器都在堆棧數(shù)組中包含著。因為每個數(shù)組里放的是寄存器的值,在此就把這每個任務(wù)的堆棧數(shù)組叫做寄存器數(shù)組,暫且把寄存器數(shù)組設(shè)計成15個字節(jié),依次存放PC、ACC、B、DPTR、PSW、R0~R7。
函數(shù)OSTaskStkInit()傳遞4個參數(shù),第1個參數(shù)task是所創(chuàng)建任務(wù)的起始地址,這個參數(shù)須保存到PC在寄存器數(shù)組的對應(yīng)位置,第2個參數(shù)ppdata是所創(chuàng)建任務(wù)的參數(shù),C51規(guī)則中用R1~R3來傳遞參數(shù)指針,這個參數(shù)須存放到R1~R3在寄存器數(shù)組中的對應(yīng)位置。第3個參數(shù)ptos是棧底指針,從當(dāng)前地址開始初始化堆棧指針,第4個參數(shù)opt是附加參數(shù),一般不用。
4.2 運行等待任務(wù)中優(yōu)先級最高任務(wù)函數(shù)OSStartHighRdy()
此函數(shù)在啟動操作系統(tǒng)函數(shù)OSStart()的最后一行調(diào)用,且此函數(shù)不返回,經(jīng)過此函數(shù)后μC/OS接管系統(tǒng)。OSStartHighRdy()不是去調(diào)用用戶任務(wù)函數(shù),而是讓PC指針指向任務(wù)函數(shù)首地址。且任務(wù)函數(shù)的傳遞參數(shù)只有一個,若此參數(shù)正確,則可保證任務(wù)函數(shù)運行正確。在調(diào)用OSStartHighRdy()之前OSStart()已經(jīng)把最高優(yōu)先級任務(wù)的任務(wù)表準備好了,只要把最高優(yōu)先級任務(wù)表的數(shù)據(jù)恢復(fù)到堆棧中,再執(zhí)行返回指令即可,以上最關(guān)鍵的是如何讓其返回到最高優(yōu)先級任務(wù)中而不是返回到被調(diào)函數(shù)中。
當(dāng)函數(shù)OSStart()調(diào)用函數(shù)OSStartHighRdy()時,斷點地址入棧;當(dāng)OSStartHighRdy()執(zhí)行完之后,返回斷點。在OSStartHighRdy()中把SP及SP-1的值改為最高優(yōu)先級任務(wù)的地址,這樣OSStartHighRdy()就會返回到最高優(yōu)先級任務(wù)中去運行。
4.3 任務(wù)級的任務(wù)切換函數(shù)OSCtxSw()
此函數(shù)是保存當(dāng)前任務(wù)的狀態(tài),然后運行處于就緒態(tài)中的最高優(yōu)先級任務(wù)。前面介紹過不是更改SP去指向寄存器數(shù)組,而是把寄存器數(shù)組的數(shù)復(fù)制到堆棧中。先看下一般的情況,在用戶任務(wù)MyTask(void*ppdtat)中調(diào)用TimeDly(),TimeDly()中調(diào)用OSSched(),在OSSched()中有一個宏OS_TASK_SW(),這個宏的目的是讓程序進人函數(shù)OSCtxSw()。參看圖1,就如Fun4為OSCtxSw(),F(xiàn)un3為OSSched(),F(xiàn)un2為TimeDly(),F(xiàn)un1為MyTask()。ADD_D存的是OSSched()的斷點,ADD_C為TimeDly()的斷點,ADD_B為MyTask()的斷點。如果進行任務(wù)切換,應(yīng)該把高優(yōu)先級任務(wù)的地址值賦給ADD_B(即SP-4與SP-5)。
以上考慮的是最簡單的情況,當(dāng)任務(wù)比較復(fù)雜時,可能更改了ACC、PSW、DPTR或R0~R7的值,在進入高優(yōu)先任務(wù)時,寄存器并不是此任務(wù)的寄存器值,運行的結(jié)果可能不正確。
在上述情況下如何保證CPU寄存器的值正確,要分兩個階段。第一個階段是把CPU寄存器值保存到要掛起任務(wù)的寄存器數(shù)組中,當(dāng)剛進入OSCtxSw()時,CPU寄存器的值是要掛起任務(wù)的寄存器值,所以一開始就要鎖定CPU寄存器的值。如果OS_TASK_SW()定義為中斷的話,在進入OSCtxSw()時,CPU寄存器的值被自動壓棧;如果把OS_TASK_SW()定義為函數(shù)時,在進入函數(shù)時使用內(nèi)嵌匯編的方法把CPU寄存器入棧。這時堆棧中又壓入了13個字節(jié),就如在圖1的ADD_D上又壓入了13個字節(jié)的數(shù)據(jù),然后從堆棧中把值取出來放到相應(yīng)任務(wù)的寄存器數(shù)組中。第二個階段是把將要執(zhí)行任務(wù)的寄存器數(shù)組的值復(fù)制到堆棧中。此時PC指針在堆棧中對應(yīng)的位置是SP-17與SP-18,SP到SP-12的13個字節(jié)對應(yīng)ACC、B、DPTR、PSW、R0~R7。
4.4 中斷級的任務(wù)切換函數(shù)OSIntCtxSw()
此函數(shù)和上一個函數(shù)基本思想一致,都要保存當(dāng)前任務(wù)的狀態(tài),運行處于就緒態(tài)中的優(yōu)先級最高的任務(wù)。二者的不同在于,上個函數(shù)的堆棧中SP-17與SP-18是PC值的位置,SP到SP-12是13個寄存器的位置。當(dāng)中斷來時,在中斷中調(diào)用函數(shù)OSIntExit(),函數(shù)OSIntExit()調(diào)用函數(shù)OSIntCtxSw(),在OSIntCtxSw()中實現(xiàn)任務(wù)切換。在進入函數(shù)OSIntExit()之前寄存器的值已經(jīng)入棧,所以運行到本函數(shù)時堆棧中SP-17與SP-18是PC值的位置。SP-4到SP-16是13個寄存器的位置。在圖1上,上個函數(shù)的13個寄存器的值被壓入ADD_D上面的13個字節(jié)中,而本函數(shù)是在ADD_B于ADD_C之間壓入的這13個寄存器。
4.5 周期節(jié)拍中斷函數(shù)OSTickISR()
這個函數(shù)是給系統(tǒng)提供一個節(jié)拍,一般每秒10~100次。如果節(jié)拍頻率太高,μC/OS系統(tǒng)會占用大量硬件資源;如果太低,任務(wù)間的切換又會很慢。
此函數(shù)首先要保證產(chǎn)生一個周期性的中斷,可以使用硬件定時器,也可以從交流電中獲得50/60Hz的時鐘頻率。這個函數(shù)至少要做3件事:1)進入中斷時,把中斷嵌套層數(shù)計數(shù)器加1,說明又進入一次中斷,也可以直接調(diào)用OSIntEnter()函數(shù);2)調(diào)用時鐘節(jié)拍函數(shù)OSTimeTick(),告知系統(tǒng)又經(jīng)過了一個節(jié)拍;3)調(diào)用OSIntExit()函數(shù),說明要退出中斷了,此函數(shù)會自動處理。

5 結(jié)束語
文中闡述了在堆棧空間有限的51運行μC/系統(tǒng)的過程,利用系統(tǒng)棧SP作為數(shù)據(jù)交換的樞紐。在實際應(yīng)用中,如果用系統(tǒng)棧來,只需根據(jù)文中的基本思想進行適當(dāng)?shù)母膶?,即可運行于其他處理器上。如果處理器的堆棧指針尋址空間足夠大,也可以為每個任務(wù)開辟一個棧,通過改變堆棧指針指向不同任務(wù)的棧空間,來實現(xiàn)任務(wù)調(diào)度。
通過在51的運行,可以看出μC/也能在堆??臻g比較少的CPU上運行。

本文引用地址:http://m.butianyuan.cn/article/171557.htm

上一頁 1 2 3 下一頁

關(guān)鍵詞: 移植 機上 單片 OS-II

評論


相關(guān)推薦

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

關(guān)閉