新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 如何構(gòu)造一個51單片機的實時操作系統(tǒng)

如何構(gòu)造一個51單片機的實時操作系統(tǒng)

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

2 要不要占先

由上面的分析,如果要保持一個函數(shù)可重人,就得使用靜態(tài)變量,系統(tǒng)的RAM資源將是一個嚴(yán)峻的考驗;如果使用臨界區(qū)來保護運行環(huán)境,系統(tǒng)的實時性又得不到保證,而且有將占先式任務(wù)調(diào)度轉(zhuǎn)為非占先任務(wù)調(diào)度之虞。顯然,使用靜態(tài)變量簡單,但有更多的不適用性,對將來功能的調(diào)整也是一個阻礙,一般不被采用。那么,就只能從環(huán)境保護上來下功夫了,但是果真只能以進入臨界區(qū)犧牲系統(tǒng)的實時性來保證任務(wù)不被占先?下面看看臨界保護這一方法的基本思路:

①在一個任務(wù)中,如果局部變量在其作用域內(nèi)不被占先切換,則這些變量在任務(wù)被剝奪了CPU控制權(quán)后,不關(guān)心其值也不會影響任務(wù)的正確執(zhí)行;

②使用臨界區(qū)保護,可以達到上面所提到的要求;

③由此導(dǎo)致的實時性能與占先切換的減弱可以接受。由此可知,不被占先是任務(wù)保護局部變量的關(guān)鍵。既然如此,何不舍棄占先式的任務(wù)調(diào)度?這不失為一個好的出發(fā)點。針對Keil C51,非占先式任務(wù)調(diào)度,可能是一種更好的方法,更能協(xié)調(diào)51系列單片機的既定資源。下面編寫這樣一個系統(tǒng):

①使用非占先式任務(wù)調(diào)度;

②可以在小容量的芯片中使用,開發(fā)目標(biāo)是,即使是8051這樣小的芯片,也可使用這個;

③支持優(yōu)先級調(diào)度,盡可能保證其實時性。

3 的實現(xiàn)

基于以上的分析與目的,近日完成了這個操作系統(tǒng)。在堆棧上借用RTx的管理方法,即當(dāng)前任務(wù)使用全部的堆空間

3.1 堆棧的初始化與任務(wù)的創(chuàng)建

堆棧的初始化實際是初始化0STaskStackBotton數(shù)組,并將當(dāng)前任務(wù)指定為空閑任務(wù),下一個運行任務(wù)指定為最高優(yōu)先級任務(wù),即優(yōu)先級為零的任務(wù)。初始化時,將SP的值存人OSTaslkStackBotton[O],SP+2的值存入OSTaskStacKBotton[1],依此類推。而任務(wù)是調(diào)用0STa-skCreate函數(shù)建立的。實際上只是將任務(wù)(假設(shè)為n號任務(wù))的地址填人到對應(yīng)OSTaskStackBotton[n]所指向的位置,并將SP向后移動2個字節(jié),

為什么要以這樣一種規(guī)律而不是其他的方式呢?這是由于在任務(wù)建立后,還未進行任務(wù)調(diào)度之前,各任務(wù)的堆棧實際上是它們自身的地址,因而其堆棧深度為2,為了程序的簡便而直接填入。

void main(void){
OSInit(); /*初始化OSTaskStackBcBotton隊列*/
TMOD=(TMOD0XFO)│ 0XOl;
TL0=0xBF;
TH0=0xFC;
TRO=1;
ETO=1;
TFO=O:
OSTaskCreate(TaskA,NULL,0);
OSTaskCreate(TaskB.NULL,1);
OSTaskCreate(TaskC,NULL,2);
OSStart();

上面這段代碼中,所有任務(wù)建立后,便調(diào)用OSStart()開始任務(wù)調(diào)度。OSStart()是一個宏定義,如下所示:
#deflne OSStart() d0{\
OSTaskCreate(TaskIdle,NULL,OS_MAX_TASKS);\
EA=l:\
return;\
}while(O)

首先,它創(chuàng)建了一個空閑任務(wù)并打開中斷,然后便返回。返回到哪里了呢?我們知道,空閑任務(wù)是優(yōu)先級最低的任務(wù),當(dāng)調(diào)OSTaskCreate建立時,會將其地址填人到SP的位置,并把SP向后移動2個字節(jié)(見圖2及說明),因而此時處在堆棧頂端的,一定是空閑任務(wù)Taslddle。這就使得這里的return一定會返回到空閑任務(wù)。至此,系統(tǒng)進入正常運行狀態(tài)。

3.2 任務(wù)的切換

任務(wù)的切換分兩種情況,在當(dāng)前任務(wù)優(yōu)先級低于下一個取得CPU控制權(quán)的任務(wù)時,將下一個取得CPU控制權(quán)的任務(wù)的棧頂?shù)疆?dāng)前任務(wù)的棧頂之間的內(nèi)容向RAM空間的高端搬移,以空出全部的RAM空間作下一個任務(wù)的堆空間,同時更新對應(yīng)的OSTaskStackBotton,使其指向新的正確任務(wù)的堆棧棧底。如果當(dāng)前任務(wù)的優(yōu)先級高于下一個任務(wù)的優(yōu)先級,則作相反的搬移,

所有任務(wù)必須主動調(diào)用,放棄CPU的控制權(quán)。任務(wù)調(diào)用后,將選擇優(yōu)先級最高的就緒任務(wù)運行。

結(jié) 語

系統(tǒng)完成后,內(nèi)核的代碼量在400多個字節(jié)左右,占用1個定時器中斷及小量的內(nèi)存空間。系統(tǒng)設(shè)置容量為8個任務(wù),用戶實際可用任務(wù)為7個,能夠滿足一般需求,也達到了在小容量芯片中應(yīng)用的開發(fā)要求。由于沒有采用占先式的任務(wù)調(diào)度,除開全程相關(guān)的個別任務(wù)的一些局部變量外,其他局部變量已經(jīng)不存在覆蓋關(guān)系,由于是任務(wù)主動放棄CPU控制權(quán),對于個別需要保護的變量單獨進行處理也變得容易。在系統(tǒng)中,全程不需要反復(fù)地開關(guān)中斷,實時性能也很好。對個別時序要求嚴(yán)格的外設(shè)(如DSl8820)除外。


上一頁 1 2 下一頁

評論


相關(guān)推薦

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

關(guān)閉