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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

評論

0/150

提交評論