嵌入式實(shí)時操作系統(tǒng)(第13課時)85528_第1頁
嵌入式實(shí)時操作系統(tǒng)(第13課時)85528_第2頁
嵌入式實(shí)時操作系統(tǒng)(第13課時)85528_第3頁
嵌入式實(shí)時操作系統(tǒng)(第13課時)85528_第4頁
嵌入式實(shí)時操作系統(tǒng)(第13課時)85528_第5頁
已閱讀5頁,還剩19頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

嵌入式實(shí)時操作系統(tǒng)(第13課時)855287.1μc/os-II移植的一般性問題7.1.1可重入函數(shù)在多任務(wù)操作系統(tǒng)環(huán)境中,應(yīng)用程序的各個任務(wù)是并發(fā)運(yùn)行的,這些并發(fā)運(yùn)行的任務(wù)經(jīng)常會出現(xiàn)調(diào)用同一個函數(shù)的情況,那么就可能出現(xiàn)任務(wù)之間通過這個函數(shù)而產(chǎn)生意外的耦合,從而互相干擾。例如,有一個任務(wù)A和任務(wù)B都要調(diào)用的函數(shù)Swap(),而該函數(shù)又使用了全局變量temp。Inttemp;voidSwap(int*x,int*y){temp=*x;*x=*y,*y=temp;}于是,如果當(dāng)任務(wù)A調(diào)用Swap()期間,系統(tǒng)發(fā)生了任務(wù)切換而使任務(wù)B也調(diào)用了函數(shù)Swap(),那么任務(wù)B將要改變?nèi)肿兞縯emp的值,使任務(wù)A傳遞給全局變量temp的值丟失而出現(xiàn)錯誤。顯然,是不允許出現(xiàn)上述現(xiàn)象的,所以在多任務(wù)操作系統(tǒng)中,系統(tǒng)提供的函數(shù)應(yīng)該能允許同時被多個任務(wù)所調(diào)用,而不會通過函數(shù)中變量的耦合引起任務(wù)之間的相互干擾。這樣的函數(shù)叫做可重入函數(shù)。一般來說,一個可重入函數(shù)應(yīng)該在函數(shù)中只使用局部變量,因為函數(shù)的局部變量存儲在任務(wù)的堆棧中,所以可保證不同的任務(wù)在調(diào)用同一個函數(shù)時不會發(fā)生沖突。如果函數(shù)一定要使用全局變量,則需要對使用的全局變量做必要的保護(hù)。為了能夠產(chǎn)生可重入函數(shù),用戶使用的處理器的C編譯器應(yīng)該具有產(chǎn)生可重入代碼的能力7.1.2時鐘節(jié)拍的產(chǎn)生μc/os-II是通過硬件中斷來實(shí)現(xiàn)系統(tǒng)時鐘,并在時鐘中斷服務(wù)程序中來處理與時間相關(guān)的問題的。因此,用戶所選用的處理器必須具有響應(yīng)中斷的能力,并同時應(yīng)該具有開中斷與關(guān)中斷指令。一般情況下應(yīng)該使用硬件定時器來作為時鐘中斷源,這個定時器可以是與微處理器集成在一個芯片上的,也可以是分立的。定時中斷的頻率以10~100Hz為宜。7.1.3任務(wù)堆棧的設(shè)計要使μc/os-II能夠正常運(yùn)行,用戶選用的處理器必須可支持一定數(shù)量的硬件堆棧,并且應(yīng)該有對堆棧指針進(jìn)行讀/寫操作的指令。1、堆棧的格式眾所周知,不同的處理器支持堆棧的增長方向也不同,因此在對μc/os-II的移植時,一定要正確地定義堆棧的格式。2、系統(tǒng)堆棧與任務(wù)堆棧的關(guān)系有些處理器對于堆棧的設(shè)置有特殊的要求,即要求堆棧必須設(shè)置在一個特定的區(qū)域。例如,51系列單片機(jī)要求堆棧必須設(shè)置在片內(nèi)RAM中。由于這種處理器芯片內(nèi)的RAM極其有限,不可能把應(yīng)用程序中所有任務(wù)的任務(wù)堆棧都設(shè)置在片內(nèi)RAM中,所以就只能把應(yīng)用程序中各個任務(wù)堆棧的內(nèi)容存放在片外RAM中,而只在片內(nèi)RAM中設(shè)置一個公用的堆棧。如果把在片外RAM中用來存放任務(wù)堆棧內(nèi)容的區(qū)域叫做任務(wù)堆棧映像,而片內(nèi)RAM中的公用堆棧叫做系統(tǒng)堆棧,那么,當(dāng)系統(tǒng)運(yùn)行某個任務(wù)時,就要把該任務(wù)的堆棧映像復(fù)制到系統(tǒng)堆棧中;而在中止這個任務(wù)時,再把系統(tǒng)堆棧中的內(nèi)容復(fù)制回任務(wù)堆棧映像中。系統(tǒng)與任務(wù)堆棧映像之間的關(guān)系如圖7-1所示…被中止運(yùn)行的任務(wù)堆棧映像…被運(yùn)行的任務(wù)堆棧映像…系統(tǒng)堆棧CPUSP圖7-1系統(tǒng)堆棧與任務(wù)堆棧映像之間的關(guān)系7.2在51系列單片機(jī)上移植μc/os-II為了提高可移植性,μc/os-II的絕大部分代碼都是用C語言編寫的。在一般情況下,這部分代碼不需要修改就可以使用,因此它的移植工作主要與4個文件相關(guān):匯編文件(OS_CPU_A.ASM)、處理器相關(guān)C語言文件(OS_CPU.H、OS_CPU_C.C)和配置文件(OS_CFG.H)。7.2.1改寫文件OS_CPU.H1、堆棧的增長方向51單片機(jī)的堆棧是從低地址向高地址增長(由下往上增長)的,所以定義堆棧增長方向的常數(shù)OS_STK_GROWTH應(yīng)該為1,即#defineOS_STK_GROWTH12、定義臨界段的宏設(shè)置臨界區(qū)的兩個宏分別直接使用51單片機(jī)的開中斷和關(guān)中斷指令來實(shí)現(xiàn)。#defineOS_ENTER_CRITICAL()EA=0#defineOS_EXIT_CRITICAL()EA=13、定義任務(wù)切換宏任務(wù)切換是由匯編語言編寫的函數(shù)OSCtxSw()實(shí)現(xiàn)的。任務(wù)切換宏OS_TASK_SW()封裝了對任務(wù)切換函數(shù)OSCtxSw()的調(diào)用。#defineOS_TASK_SW()OSCtxSw4、定義數(shù)據(jù)類型typedefunsignedcharBOOLEAN;//不要bit定義typedefunsignedcharINT8U;//無符號8位數(shù)typedefsignedcharINT8S;//有符號8位數(shù)typedefunsignedintINT16U;//無符號16位數(shù)typedefsignedintINT16S;//有符號16位數(shù)typedefunsignedlongINT32U;//無符號32位數(shù)typedefsignedlongINT32S;//有符號32位數(shù)typedeffloatFP32;//單精度浮點(diǎn)數(shù)typedefdoubleFP64;//雙精度浮點(diǎn)數(shù)typedefunsignedcharOS_STK;//棧單元寬度為8位#defineBYTEINT8S//兼容以前版本的數(shù)據(jù)類型#defineUBYTEINT8U//μc/os-II可以不用這些數(shù)據(jù)類型#defineWORDINT16S#defineUWORDINT16U#defineLONGINT32S#defineULONGINT32U7.2.2任務(wù)堆棧的設(shè)計51單片機(jī)的外部RAM中設(shè)置任務(wù)堆棧映像,任務(wù)堆棧映像的最低地址空間用來存放用戶堆棧的長度,并使該任務(wù)的TCB中的OSTCBStkPtr指針變量指向該地址。51單片機(jī)的堆棧指針SP總是先加1再存數(shù)據(jù),因此,SP初始值指向系統(tǒng)堆棧起始地址(OSStack)減1處(OSStkStart)。很明顯,系統(tǒng)堆棧長度為SP-OSStkStart。在任務(wù)切換時,應(yīng)先把當(dāng)前任務(wù)在系統(tǒng)堆棧的內(nèi)容復(fù)制保存到該任務(wù)堆棧映像中。也就是計算SP-OSStkStart,得出堆棧長度,并將其寫入任務(wù)堆棧映像最低地址空間中;然后以其為長度,以任務(wù)堆棧映像最低地址為目標(biāo)起址,以O(shè)SStkStart為源地址,由系統(tǒng)堆棧向任務(wù)堆棧映像復(fù)制數(shù)據(jù)。然后把就緒最高優(yōu)先級任務(wù)堆棧映像中的內(nèi)容復(fù)制到系統(tǒng)堆棧。方法是,自任務(wù)控制塊中獲得該任務(wù)堆棧映像的最低地址,從中取出堆棧長度,以最高優(yōu)先級任務(wù)堆棧映像最低地址為源地址,以系統(tǒng)堆棧起址OSStkStart為目標(biāo)起址,由任務(wù)堆棧映像向系統(tǒng)堆棧復(fù)制數(shù)據(jù)。堆棧長度OSTCBStkPtr外部RAM任務(wù)堆棧映像堆棧長度系統(tǒng)堆棧CPUSP51單片機(jī)OSStkStart系統(tǒng)堆棧起始地址OSStack高地址低地址圖7-2在51單片機(jī)上移植μc/os-II時,系統(tǒng)堆棧與任務(wù)堆棧映像之間的關(guān)系任務(wù)切換函數(shù)OSCtxSw()及在任務(wù)切換時對系統(tǒng)堆棧和任務(wù)堆棧映像的操作都是用匯編語言編寫的,其代碼如下(注意,函數(shù)OSCtxSw()的入口在標(biāo)號OSCtxSw處):;------------------------------------------------------------------------------------------------------RSEG?PR?OSStartHighRdy?OS_CPU_AOSStartHighRdy:USING0LCALL_?OSTaskSwHookOSCtxSw_in:;OSTCBCur=>DPTR獲得當(dāng)前TCB指針MOVR0,#LOW(OSTCBCur)INCR0MOVDPH,@R0INCR0MOVDPL,@R0;任務(wù)堆棧映像指針=>DPTRINCDPTRMOVXA,@DPTRMOVR0,AINCDPTRMOVXA,@DPTRMOVR1,AMOVDPH,R0MOVDPL,R1;任務(wù)堆棧映像長度*UserStkPtr=>R5MOVXA,@DPTRMOVR5,A;R5=任務(wù)堆棧映像長度;把待運(yùn)行任務(wù)堆棧映像的內(nèi)容復(fù)制到系統(tǒng)堆棧MOVR0,#OSStkStartrestore_stack:INCDPTRINCR0MOVXA,@DPTRMOV@R0,ADJNZR5,restore_stack;恢復(fù)系統(tǒng)堆棧指針SPMOVSP,RO;恢復(fù)任務(wù)堆棧映像指針?C_XBPINCDPTRMOVXA,@DPTRMOV?C_XBP,AINCDPTRMOVXA,@DPTRMOV?C_XBP+1,A;OSRunning=TRUEMOVRO,#LOW(OSRunning)MOV@R0,#01POPALL;把系統(tǒng)堆棧內(nèi)容彈入CPUSETBEA;開中斷RETI;利用中斷返回指令,使系統(tǒng)切換至運(yùn)行任務(wù);------------------------------------------------------------------------------------------------------RSEG?PR?OSCtxSw?OS_CPU_A;任務(wù)切換函數(shù)入口OSCtxSw:PUSHALL;把被中止運(yùn)行任務(wù)的CPU內(nèi)容壓棧OSIntCtxSw_in:;獲得堆棧長度和起址MOVA,SPCLRCSUBBA,#OSStkStartMOVR5,A;獲得堆棧長度;OSTCBCur=>DPTR;獲得當(dāng)前任務(wù)TCB指針MOVR0,#LOW(OSTCBCur);INTR0MOVDPH,@ROINCR0MOVDPL,@R0;獲得任務(wù)堆棧映像指針I(yè)NCDPTRMOVXA,@DPTRMOVRO,AINCDPTRMOVXA,@DPTRMOVR1,AMOVDPH,R0MOVDPL,R1;保存堆棧長度MOVA,R5MOVX@DPTR,AMOV@DPTR,A;把系統(tǒng)堆棧內(nèi)容復(fù)制到任務(wù)堆棧映像save_stack:INCDPTRINCR0MOVA,@R0MOVX@DPTR,ADJNZR5,save_stack;保存任務(wù)堆棧映像指針?C_XBPINCDPTRMOVA,?C_XBPMOVX@DPTR,AINCDPTRMOVA,?C_XBP+1MOVX@DPTR,A;調(diào)用用戶程序LCALL_?OSTaskSwHook;獲得最高級就緒任務(wù)的TCBMOVR0,#OSTCBCurMOVR1,#OSTCBHighRdyMOVA,@R1MOV@R0,AINCR0INCR1MOVA,@R1MOV@R0,AINCR0INCR1MOVA,@R1MOV@R0,AMOVR0,#OSPrioCurMOVR1,#OSPrioHighRdyMOVA,@R1MOV@R0,ALJMPOSCtxSw_in;--------------------------------------------------------------------------------------------------------RSEG?PR?OSIntCtxSw?OS_CPU_AOSIntCtxSw:;調(diào)整SP指針去掉在調(diào)用OSIntExit(),OSIntCtxSw();過程中壓入堆棧的多余內(nèi)容SP=SP-4MOVA,SPCLRCSUBBA,#4MOVSP,ALJMPOSIntCtxSw_in其中壓棧和出棧代碼段如下:;定義壓棧出棧宏---------------------------------------------------------------------------------PUSHALLMACROPUSHPSWPUSHACCPUSHBPUSHDPLPUSHDPHMOVA,R0;R0~R7入棧PUSHACCMOVA,R1PUSHACCMOVA,R2PUSHACCMOVA,R3PUSHACCMOVA,R4PUSHACCMOVA,R5PUSHACCMOVA,R6PUSHACCMOVA,R7PUSHACC;PUSHSP;不必保存SP,任務(wù)切換時由相應(yīng)程序調(diào)整ENDM;定義出棧宏-----------------------------------------------------------------------------------------POPALLMACRO;POPACC;不必保存SP,任務(wù)切換時由相應(yīng)程序調(diào)整POPACC;R0~R7出棧MOVR7,APOPACCMOVR6,APOPACCMOVR5,APOPACCMOVR4,APOPACCMOVR3,APOPACCMOVR2,APOPACCMOVR1,APOPACCMOVR0,APOPACCPOPDPHPOPDPLPOPBPOPACCPOPPSWENDM;--------------------------------------------------------------------------------------------------------7.2.3文件OS_CPU_C.C的改寫在文件OS_CPU_C.C中主要應(yīng)改寫任務(wù)堆棧初始化函數(shù)OSTaskStkInit()。由于要使用單片機(jī)上的定時器為系統(tǒng)設(shè)置時鐘中斷,因此還添加對51單片機(jī)定時器的初始化程序。1、改寫任務(wù)堆棧初始化函數(shù)void*OSTaskStkInit(void(*task)(void*pd),void*ppdata,void*ptos,INT16Uopt)reentrant{OS_STK*stk;pdata=ppdata;opt=opt;//opt沒被用到,保留次語句防止告警產(chǎn)生stk=(OS_STK*)ptos;//用戶堆棧最低有效地址*stk++=15;//用戶堆棧長度*stk++=(INT16U)task&oxFF;//任務(wù)地址低8位*stk++=(INT16U)task>>8;//任務(wù)地址高8位*stk++=0x00;//PSW*stk++=0x0A;//ACC*stk++=0x0B;//B*stk++=0x00;//DPL*stk++=0x00;//DPH*stk++=0x00;//R0/*R3、R2、R1用于傳遞任務(wù)參數(shù)ppdata,其中R3代表存儲器類型,R2為高字節(jié)偏移,R1為低字節(jié)位移通過分析KEIL匯編,了解到任務(wù)的voidppdata參數(shù)恰好是用R3、R2、R1傳遞,不是通過虛擬堆棧*/*stk++=(INT16U)ppdata&0xFF;//R1*stk++=(INT16U)ppdata&>>8;//R2*stk++=0x01;//R3*stk++=0x04;//R4*stk++

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論