新聞中心

UCOS移植心得

作者: 時(shí)間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
移植UCOS之前,你首先應(yīng)該做好三件事:


1.弄懂UCOS,這是誰(shuí)都知道的哦 ^_^

2. 弄懂你想要移植到的硬件平臺(tái)

3. 清楚你使用的編譯器是如何處理函數(shù)的局部變量和怎么樣處理函數(shù)間的參數(shù)傳遞

這里多廢話幾句第三點(diǎn):在UCOS里面,所有函數(shù)都要求具有重入性(除了OSSTAR()外,只有這個(gè)函數(shù)我覺得是不需要的,它僅僅使用了一次);重入性是多任務(wù)的基礎(chǔ),而所謂重入性從函數(shù)而言就是它的變量的保存問題,在中斷這個(gè)函數(shù)的執(zhí)行時(shí)它使用的變量需要得到保存,以便返回后的執(zhí)行是正確的,就我使用的編譯器而言,它通過堆棧傳遞函數(shù)參數(shù),

重入性問題就很容易解決拉,在中斷任務(wù)時(shí),它的參數(shù)已經(jīng)在堆棧里面了,只要你保存好CPU寄存器和堆棧指針SP就好

而如果你使用的是KEIL的話就比較復(fù)雜拉,首先KEIL是51單片機(jī)的東西,51只有很少的存儲(chǔ)空間,KEIL的重入性是通過設(shè)立模擬棧實(shí)現(xiàn)的,當(dāng)任務(wù)中斷執(zhí)行時(shí),你不僅需要保存CPU寄存器,還要保存模擬棧的內(nèi)容,特別是51的SP尋址能力不強(qiáng),只有8位,不能在64K的空間自移動(dòng),而UCOS比較大,KEIL編譯時(shí)只能用大規(guī)模方式,這就意味著所有的全局變量都會(huì)保存在片外空間,而SP無法訪問到,你需要設(shè)立一個(gè)公共的系統(tǒng)棧,保存正在運(yùn)行的任務(wù)的數(shù)據(jù),在任務(wù)切換時(shí)把這個(gè)系統(tǒng)棧的內(nèi)容拷貝到它的任務(wù)棧里,操作比較繁瑣

注意系統(tǒng)的初始化問題,我在第一個(gè)任務(wù)里調(diào)用了系統(tǒng)初始化函數(shù),在里面開中斷允許.

任務(wù)可以是關(guān)中斷時(shí)被掛起,也可以是開中斷時(shí)被掛起,那么在任務(wù)切換回來后如何保證它的中斷狀況呢?問題可以通過給每個(gè)任務(wù)設(shè)置一個(gè)中斷計(jì)數(shù)器解決,并初始化為 0,記錄每個(gè)任務(wù)的開關(guān)中斷次數(shù),關(guān)一次中斷加 1,開一次中斷減 1, 在任務(wù)調(diào)度的時(shí)候保存當(dāng)前任務(wù)的中斷計(jì)數(shù)器,切換到新任務(wù)時(shí)查看新任務(wù)的中斷計(jì)數(shù)器,如果為 0就開中斷返回,不然就直接返回(任務(wù)級(jí)切換是在關(guān)中斷下進(jìn)行的);而對(duì)于中斷級(jí)任務(wù)調(diào)度,肯定是發(fā)生在開中斷情況下的,就要查看是否需要關(guān)中斷處理

現(xiàn)在開始說我的移植:我移植到的平臺(tái)是凌陽(yáng)公司的SPCE061A 16位單片機(jī),它有2K的RAM,32K的ROM空間,基本上夠用,但不能有太多功能,我在研究了這款片子的資料后,才開始自己的移植,主要是學(xué)了一下它的匯編語(yǔ)言和混合編程以及CPU得硬件方面;在堆棧的問題上我發(fā)現(xiàn)凌陽(yáng)的SP是16位的,可以尋址64K的空間,不需要設(shè)立系統(tǒng)棧. 在OS_CPU_C.C中注意堆棧的初始化,一定要在任務(wù)切換時(shí)嚴(yán)格遵守你的初始化時(shí)假定的寄存器順序.

下面開始移植最重要的三個(gè)文件:

OS_CPU_C.C:

OSTaskStkInit():

stk=(OS_STK *)ptos;


*stk--=*((INT16U*)task+1);/*任務(wù)首地址 (PC)*/

*stk--=0x0000;/*SR(R6) */

*stk--=0x0000;/*BP(R5) */

*stk--=0x0000;/*R4*/

*stk--=0x0000;/*R3*/

*stk--=0x0000;/*R2*/

*stk--=0x0000;/*R1*/

*stk--=0x0000;/*該任務(wù)的中斷狀況計(jì)數(shù)器*/

return((void *)stk);

別的就是空函數(shù),比較簡(jiǎn)單,這里略去

這個(gè)文件比較簡(jiǎn)單,唯一要注意的是堆棧初始化函數(shù),像剛剛說到的,你假定的堆棧內(nèi)容必須在任務(wù)切換時(shí)嚴(yán)格遵守.還有就是定義幾個(gè)空函數(shù)

OS_CPU_A.ASM:

這個(gè)文件呢是移植的關(guān)鍵,需要用匯編語(yǔ)言編寫,(我有個(gè)同學(xué)很能噴,認(rèn)為匯編語(yǔ)言純屬?zèng)]用,像這種話千萬(wàn)不要相信!),在這個(gè)文件里,你需要完成UCOS的核心代碼!

首先是OSStartHighRdy():

該函數(shù)在系統(tǒng)開始時(shí)使最高優(yōu)先級(jí)任務(wù)運(yùn)行,代碼如下:

_OSStartHighRdy:

CALL_OSTaskSwHook



R1=0x0001

[_OSRunning]=R1



R1=[_OSTCBCur]

SP=[R1]

POP R1 FROM [SP]

[_InterruptC]=R1//彈出任務(wù)中斷狀況計(jì)數(shù)器

POP R1,R5 FROM [SP]

RETI

接著是OSCtxSw():

完成任務(wù)切換,代碼如下:

_OSCtxSw:

PUSH R1,R5 TO [SP]

R1=[_InterruptC]

PUSH R1 TO [SP]//保存任務(wù)中斷狀況



R2=[_OSTCBCur]

[R2]=SP

CALL _OSTaskSwHook



//OSUCBCur=OSTCBHighRdy

R1=_OSTCBCur

R2=[_OSTCBHighRdy]

[R1]=R2



//OSPrioCur=OSPrioHighRdy

R1=[_OSPrioHighRdy]

[_OSPrioCur]=R1



R1=[_OSTCBHighRdy]

SP=[R1]

POP R1 FROM [SP]

[_InterruptC]=R1//彈出任務(wù)中斷狀況

CMP R1,0//查看是否需要開中斷

JNE KAI

INT IRQ

KAI: POP R1,R5 FROM [SP]

RETI

上一頁(yè) 1 2 下一頁(yè)

關(guān)鍵詞: UCOS移植心

評(píng)論


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

關(guān)閉