MicroC/OS-II在80C196上的移植實現(xiàn)
時間:2022-11-17 10:05:00
導語:MicroC/OS-II在80C196上的移植實現(xiàn)一文來源于網(wǎng)友上傳,不代表本站觀點,若需要原創(chuàng)文章可咨詢客服老師,歡迎參考。
摘要:在嵌入式系統(tǒng)中使用實時操作系統(tǒng),可以提高系統(tǒng)的穩(wěn)定性、可靠性和實時性。microc/os-ii是一個完整的,可移植、可固化、可剪裁的搶占式多任務實時內核,并且開放源代碼,得到了廣泛應用。本文結合具體應用,介紹了MicroC/OS-II在80c196上移植實現(xiàn)過程和注意事項。
關鍵詞:實時操作系統(tǒng)MicroC/OS-II80C196移植
在嵌入式系統(tǒng)開發(fā)中,很長時間以來,一直采用傳統(tǒng)的嵌入式系統(tǒng)軟件設計模式:無限循環(huán)+中斷服務。該模式下,主程序為一個無限循環(huán),單任務順序執(zhí)行各個處理任務。在循環(huán)之外,設計一個或多個中斷服務函數(shù),用于處理異步事件。在相對簡單的應用中,這種模式,完全可以勝任。而對于實時性要求較高、處理任務較多的應用,就會暴露出實時性差的缺點,甚至不能夠達到應用的要求,系統(tǒng)可靠性低,穩(wěn)定性差。引入實時操作系統(tǒng),可以較好解決這個問題。
MicroC/OS-II是一個完整的,可移植、可固化、可剪裁的搶占式多任務實時內核,并且開放源代碼,在嵌入式系統(tǒng)中得到了廣泛應用。為了實現(xiàn)老系統(tǒng)功能升級,達到了不改變硬件設計,增加系統(tǒng)功能、提高系統(tǒng)性能的目的,從而采用該實時操作系統(tǒng)。本文介紹了將其移植應用于80C196的具體實現(xiàn)和注意事項。
所謂移植,就是使一個實時內核能夠在其他微處理器或微控制器上運行。移植要做的是,修改或編寫與處理器硬件相關的代碼。由于80C196系統(tǒng)的資源有限,除了代碼移植,還要根據(jù)具體應用,對MicroC/OS-II進行裁剪,以達到系統(tǒng)的設計要求。
1.MicroC/OS-II簡介
MicroC/OS-II的系統(tǒng)結構見圖1。
MicroC/OS-II最主要的特點之一是源代碼開放,有利于用戶根據(jù)具體應用對操作系統(tǒng)進行充分的裁減。這也使得其可移植性非常的強。
MicroC/OS-II是為嵌入式應用專門設計的,完全可與應用軟件融合在一起,進行編譯、連接,進而作為產品的一部分。
MicroC/OS-II是完全可剝奪型的實時內核,總是運行就緒任務中最高優(yōu)先級的任務,即準備就緒的高優(yōu)先級任務可以剝奪正在運行的低優(yōu)先級任務的CPU使用權。
2.移植的基本思路
2.1編譯器
采用TASKING公司的C196編譯器,可以方便的嵌入?yún)R編語言,因此該移植所有的函數(shù)都在OS_CPU_C.C中實現(xiàn),沒有OS_CPU_A.ASM文件。能夠采用C語言編碼的,盡量采用C語言編碼;不能采用C代碼的,采用嵌入?yún)R編的方式。以此降低代碼的分散度,提高代碼的可讀性。
2.2代碼移植
代碼移植,需要修改或編寫與處理器硬件相關的代碼。包括與處理器相關的數(shù)據(jù)類型定義,函數(shù)定義,存儲器操作等。其中的主要任務有:
1)重新編輯INCLUDES.H文件,增加與應用相關的頭文件;改寫OS_CPU.H文件;
2)改寫OS_CFG.H文件;編寫OS_CPU_C.C;
3)優(yōu)化代碼效率。
2.3存儲資源
由于80C196系統(tǒng)的物理資源十分有限,需要對系統(tǒng)內核進行充分的裁剪。
片內可用內存為220個字節(jié),在系統(tǒng)中外部擴展3584(3.5K)個字節(jié)。為了提高系統(tǒng)速度,操作系統(tǒng)盡量使用片內存儲區(qū)。系統(tǒng)應用中經常使用的變量,也需要分配在片內存儲區(qū)。
為了節(jié)約存儲資源采取以下措施:
1)裁剪不使用的功能模塊和其使用相應變量。
2)根據(jù)應用的需要裁剪所需資源的規(guī)模。例如,在應用中實際使用任務為6個,所以將OSRdyTbl由一個數(shù)組,更改為一個8位變量,并去掉OSRdyGrp,因為其永遠是0。
3)修改OS_InitTaskIdle內容,將OS_TaskIdle任務換為應用的最低優(yōu)先級的任務。
4)裁剪OS_TCB的內容。例如,永遠不會使用的變量OSTCBY和OSTCBBitY。
5)裁剪中斷嵌套的相關內容。
2.4時間資源
MicroC/OS-II推薦的時鐘節(jié)拍為10~200ms,而本系統(tǒng)的實際時鐘節(jié)拍為250μs,這樣系統(tǒng)額外開銷必然大幅度增加,系統(tǒng)時間資源十分緊張。
為了節(jié)約時間資源采取以下措施:
1)棄用OSTimeDly函數(shù),直接操作任務定時器,調用OS_Sched函數(shù)。
2)棄用OSIntExit和OSIntCtxSw函數(shù),將其源代碼直接加入軟件定時器中斷服務函數(shù)。
3)降低其他中斷服務函數(shù)的代碼長度,且不進行任務切換,降低系統(tǒng)時鐘的誤差。
4)根據(jù)編譯得到的匯編代碼,對部分C語言代碼進行優(yōu)化。
3.移植實現(xiàn)
3.1任務分配
一個任務,也稱為一個線程,是一個簡單的程序,該程序可以認為CPU完全屬于自己。每個任務有獨立的堆??臻g和優(yōu)先級。
根據(jù)每個任務的內容可以在相應位置,使任務就緒。而任務就緒和任務切換可以分開。例如,在接收中斷中,使可以CAN通信任務就緒,但可以不進行任務切換,而在系統(tǒng)時鐘函數(shù)中進行任務切換。系統(tǒng)總是讓處于就緒態(tài)的、優(yōu)先級最高的任務先運行。
3.2時鐘節(jié)拍
時鐘節(jié)拍是特定的周期性中斷,根據(jù)應用系統(tǒng)的需要,時鐘節(jié)拍的周期為250μs,采用軟件定時器實現(xiàn)。在該服務函數(shù)中實現(xiàn)任務切換,為了節(jié)省時間和存儲資源,不進行函數(shù)調用。
軟件定時器中斷服務函數(shù)實現(xiàn)代碼如下:
voidOSTickISR(void)
{
……//重置軟件定時器
OS250usCount++;//計數(shù)器加1
if((OS250usCount&0x03)==0){
……
OS1msCount++;//1ms定時器
OS50msDly++;//50ms定時器
OSRdyTbl|=0x20;//1ms定時到,就緒TaskChk任務
……}
//OSIntExit()中斷退出任務切換
OSPrioHighRdy=OSUnMapTbl[OSRdyTbl];//取得最高優(yōu)先級就緒任務的優(yōu)先級
if(OSPrioHighRdy!=OSPrioCur)//判斷當前任務優(yōu)先級是否與最高優(yōu)先級就緒任務的優(yōu)先級相同
{
//OSIntCtxSw();
OSTCBCur->OSTCBStkPtr=psp;//存儲被中斷任務的堆棧指針
OSTCBCur=OSTCBPrioTbl[OSPrioHighRdy];//取得最高優(yōu)先級就緒任務的TCB
OSPrioCur=OSPrioHighRdy;//設當前任務優(yōu)先級為最高優(yōu)先級就緒任務的優(yōu)先級
psp=OSTCBCur->OSTCBStkPtr;//取得堆棧指針
asm{//現(xiàn)場恢復
popdx;popcx;popbx;popax;popa;
ret;//切換到最高優(yōu)先級就緒任務,必須要有的
}
}
}
3.3中斷
由于中斷的存在,任何代碼在任何時候,都有可能被中斷。而有些代碼是不可分割的,如果被中斷將會產生不可預料的后果。因此定義臨界段,以處理不可分割的代碼。一旦該部分代碼開始執(zhí)行,不允許任何中斷插入。為了確保臨界段代碼的執(zhí)行不被中斷,在進入臨階段之前,必須關中斷,臨界段代碼執(zhí)行結束,開中斷。
為80C196定義OS_ENTER_CRITICAL和OS_EXIT_CRITICAL如下:
//中斷禁止函數(shù)
#defineOS_ENTER_CRITICAL()asmDI
//中斷使能函數(shù)
#defineOS_EXIT_CRITICAL()asmEI
3.4其他代碼實現(xiàn)
3.4.1任務堆棧初始化函數(shù)
任務堆棧初始化函數(shù)代碼如下:
OS_STK*OSTaskStkInit(void(*task)(void*pd),void*pdata,OS_STK*ptos,INT16Uopt)
{
……
stk=(OS_STK*)ptos;
*--stk=(OS_STK)task;//任務開始地址
*--stk=(OS_STK)0x0000|gimask;//PSWIMASK
*--stk=(OS_STK)0x0000|gimask1;//IMASK1WSR
*--stk=(OS_STK)4;//DX
*--stk=(OS_STK)3;//CX
*--stk=(OS_STK)2;//BX
*--stk=(OS_STK)1;//AX
return((OS_STK*)stk);
}
3.4.2開始運行最高優(yōu)先級就緒任務
系統(tǒng)開始運行時,調用該函數(shù),以開始運行,其實現(xiàn)代碼如下:
voidOSStartHighRdy(void)
{
OSRunning=TRUE;//置系統(tǒng)正在運行標志
……
OSTCBCur=OSTCBHighRdy;//置當前TCB為最高優(yōu)先級就緒任務的TCB
psp=OSTCBHighRdy->OSTCBStkPtr;//取得堆棧指針
asm{//恢復現(xiàn)場
popdx;popcx;popbx;popax;popa;//轉到新任務
}
}
3.4.3現(xiàn)場切換函數(shù)
OS_Sched函數(shù)調用該函數(shù)實現(xiàn)真正的任務切換。
voidOSCtxSw(void)
{
asm{//保存被中斷任務的現(xiàn)場
pusha;pushax;pushbx;pushcx;pushdx;
}
OSTCBCur->OSTCBStkPtr=psp;//存儲被中斷任務的堆棧指針
OSTCBCur=OSTCBPrioTbl[OSPrioHighRdy];//取得最高優(yōu)先級就緒任務的TCB
OSPrioCur=OSPrioHighRdy;//設當前任務優(yōu)先級為最高優(yōu)先級就緒任務的優(yōu)先級
psp=OSTCBCur->OSTCBStkPtr;//取得堆棧指針
asm{//現(xiàn)場恢復
popdx;popcx;popbx;popax;popa;
}
}
4.注意事項
在實現(xiàn)過程中的得到如下經驗教訓:
1)盡量減少任務的數(shù)量,以減少系統(tǒng)額外開銷。相對少的任務數(shù),可以減少,系統(tǒng)花在任務切換上的時間。
2)合理分配各個任務的優(yōu)先級。
3)注意開中斷、關中斷的時機。
4)注意入棧和出棧要匹配。如果堆棧指針出現(xiàn)錯位,將會出現(xiàn)災難性后果。特別注意中斷服務函數(shù)的處理,其調用時的入棧內容和退出中斷的出棧內容要對應,而中斷退出有兩種可能:正常退出和任務切換。
5)合理選擇定時器時間周期。
6)同類型工作,也同樣需要有優(yōu)先級區(qū)分。例如:同樣是通信任務,接收數(shù)據(jù)需要較高的優(yōu)先級,而通信故障處理需要較低的優(yōu)先級。一般情況下,通信處理都有一定的故障容忍時間,只要在容忍時間內得到處理就可以了。如果發(fā)生不可恢復性錯誤,故障處理將會占用大量的時間,如果在較高優(yōu)先級,將會影響整個系統(tǒng)的性能。
5.結論
通過在80C196上移植實現(xiàn)MicroC/OS-II,達到了不改變硬件設計,增加應用功能,提高了應用系統(tǒng)性能的目的。在嵌入式系統(tǒng)中使用嵌入式實時操作系統(tǒng),不但可以提高系統(tǒng)的實時性、可靠性和穩(wěn)定性,還可以提高應用軟件的可移植性和可維護性,降低開發(fā)人員的工作量。因此,只要硬件環(huán)境允許,應盡量采用實時操作系統(tǒng)。
參考文獻:
1.JeanJ.Labrosse著,邵貝貝等譯,《嵌入式實時操作系統(tǒng)μC/OS-II(第二版)》,北京航空航天大學出版社,2003年5月第1版
2.孫涵芳主編,《Intel16位單片機》,北京航空航天大學出版社,1995年11月第1版