ucos中文書-第3章內核結構_第1頁
ucos中文書-第3章內核結構_第2頁
ucos中文書-第3章內核結構_第3頁
ucos中文書-第3章內核結構_第4頁
ucos中文書-第3章內核結構_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第3章內核結 臨界段(Critical 任 任務狀 任務控制塊(TaskControlBlocks, 就緒表(Ready 給調度器上鎖和開鎖(LockingandUnLockingthe 空閑任務(Idle 統(tǒng)計任 μC/OS中的中斷處 時鐘節(jié) 第3章OS_ENTER_CRITICAL(OSIntEnter(OSSchedLock(OSSchedUnlock(),臨界段(Critical時內核開發(fā)商應提供的最重要的指標之一,因為這個指標影響用戶系統(tǒng)對實件的響應CCCCCCμC/OS-Ⅱ中的這兩個宏調用分別是:OS_ENTER_CRITICALOS_EXIT_CRITICAL()。因為這兩個宏的定義取決于所用的微處理器,故在文件OS_CPU.H中可以找到相應宏定義。每種微處理器都有自己的OS_CPU.H任其它C的函數(shù)一樣,有函數(shù)返回類型,有形式參數(shù)變量,但是任務是絕不會返回的。故返回void[L3.1(1)]。voidvoidYourTask(void{for(;;)/*/*}}程L3.1μC/OSOSTaskDel(),這個任務絕不會返回什么。程序L3.2.任務完成后自我刪voidvoidYourTask(void{/*用戶代碼*/}口的參數(shù)(波特率、I/O。用了。作者保留了優(yōu)先級為0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRI0-2為定義的常數(shù)在OS_CFG.H文件中用定義常數(shù)語句#defineconstant定義的。因此用戶可以有多達56個應用任務。必須給每個任務賦以不同的優(yōu)先級,優(yōu)先級可以從0到(ID(或任務的ID號也被一些內核服務函數(shù)調如改變優(yōu)先級函數(shù)OSTaskChangePrio(),OSTaskDel()。址與其它參數(shù)一起傳給下面兩個函數(shù)中的一個:OSTastCreatOSTaskCreatExtOSTaskCreateExt()OSTaskCreate()任務狀(L3.2立即得到CPU的控制權。一個任務可以通過調用OSTaskDel()返回到睡眠態(tài),或通過調用該3.1正在運行的任務可以通過調用兩個函數(shù)之一將自身延遲一段時間,這兩個函數(shù)是OSTimeDly(OSTimeDlyHMSMCPUOSTimeTick()使延遲了的任務進入就緒態(tài)(3.10。正在運行的任務期待某 的發(fā)生時也要等待 是調用以下3個函數(shù)之一。(WAITING(Pend,件發(fā)生了,被掛起的任務進入就緒態(tài)發(fā)生的報告可能來自另一個任務,也可能來自中。(ISR務子程序控制了CPU的使用權。中斷服務子程序可能會報告一個或多個的發(fā)生,而使taskOSTaskIdle()函數(shù)。任務控制塊(TaskControlBlocks,一旦任務建立了,任務控制塊OS_TCBs將被賦值(程序3.3。任務控制塊是一個數(shù)據(jù)結構,當任務的CPU使用權被時,μC/OS-Ⅱ用它來保存該任務的狀態(tài)。當任務重CPUOS_TCBsRAM的邏輯分組。任務建立的時候,OS_TCBs(見第四章任務管理。程序L μC/OS-II任務控制塊typedefstructos_tcb{typedefstructos_tcb{ #if structos_tcb*OSTCBNext;structos_tcb#if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN||OS_SEM_EN #if(OS_Q_EN&&(OS_MAX_QS>=2))||OS_MBOX_EN #if }中唯一的一個能用匯編語言來處置的變量(Context-switchingcode).OSTCBExtPtr指向用戶定義的任務控制塊擴展。用戶可以擴展任務控制塊而不必修改μC/OS-Ⅱ的源代碼。.OSTCBExtPtr只在函數(shù)OstaskCreateExt()中使用,故使用時要將OS_TASK_CREAT_EN1,以允許建立任務函數(shù)的擴展。例如用戶可以建立一個數(shù)據(jù)結構,3OSTaskCreateExt()OS_TASK_CREATE_EXT_EN1,以便允許該功能。4,000字節(jié)同樣是1,000個地址如果每個地址寬度是16位的則總棧容量只有2,000字節(jié)。在函數(shù)OSStakChk()中要調用OSTCBStkSize。同理,若使用該函數(shù)的話,要將OS_TASK_CREAT_EXT_EN1。.OSTCBOpt把“選擇項”傳給OSTaskCreateExt(),只有在用戶將OS_TASK_CREATE_EXT_EN設為1時,這個變量才有效。μC/OS-Ⅱ目前只支持3個選擇項(見uCOS_II.H 初始化時,已將RAM清過零,則OS_TASK_OPT_STK_CLR不需要再定義,這可以節(jié)約程序執(zhí)行時間。傳遞了OS_TASK_OPT_STK_CLR將增加TaskCreateExt()函數(shù)的執(zhí)行時間,因為要將??臻g。棧容量越大,花的時間越長。最后一個選擇項OS_TASK_OPT_SAVE_FP通知.OSTCBId用于任務的識別碼。這個變量現(xiàn)在沒有使用,留給將來擴展用.OSTCBNext和.OSTCBPrev用于任務控制塊OS_TCBs的雙重,該鏈表在時鐘節(jié)拍函數(shù).OSTCBMsg是指向傳給任務的消息的指針。用法將在后面的章節(jié)中提到(見第6章任務間通.OSTCBStat是任務的狀態(tài)字。當.OSTCBStat為0,任務進入就緒態(tài)。可以給.OSTCBStat賦uCOS_II.H.OSTCBX,.OSTCBY,.OSTCBBitX.OSTCBBitY用于加速任務進入就緒態(tài)的過程或進入等者是在改變任務優(yōu)先級時算出的。這些值的算法見程序L3.4。=priority>>=OSMapTbl[priority>>=priority&=OSMapTbl[priority&程L3.4任務控制塊OS_TCB(4應用程序中可以有的最多任務數(shù)(OS_MAX_TASKS)OS_CFG.H最多任務數(shù)也是μC/OS-Ⅱ分配給用戶程序的最多任務控制塊OS_TCBs的數(shù)目。將OS_MAX_TASKSRAMOS_N_SYS_TASKSμC/OS-Ⅱ.H,供其目前,一個用于空閑任務,另一個用于任務統(tǒng)計(如果OS_TASK_STAT_EN是設為1的。在μC/OS-Ⅱ初始化的時候,如圖3.2所示,所有任務控制塊OS_TCBs被成單向空任務鏈表。當任務一旦建立,空任務控制塊指針OSTCBList指向的任務控制塊便賦給了該任務,然后OSTCBList的值調整為指向下鏈表中下一個空的任務控制塊。一旦任務被刪3.2就緒表(Ready每個任務被賦予不同的優(yōu)先級等級,從0級到最低優(yōu)先級OS_LOWEST_PR1O,包括0和OS_LOWEST_PR1O在內(見文件OS_CFG.H。當μC/OS-Ⅱ初始化的時候,最低優(yōu)先級OS_LOWEST_PR1O總是被賦給空閑任務idletask。注意,最多任務數(shù)目OS_MAX_TASKS和最每個任務的就緒態(tài)標志都放入就緒表中的,就緒表中有兩個變量OSRedyGrp和OSRdyTbl[]。在OSRdyGrp中,任務按優(yōu)先級分組,8個任務為一組。OSRdyGrp中的每一位表示8組任務中每一組中是否有進入就緒態(tài)的任務進入就緒態(tài)時就緒表OSRdyTbl[]OSRdyTbl[]OS_LOWEST_PR1O(見文件OS_CFG.H)。當用戶的應用程序中任務數(shù)目比較少時,減少OS_LOWEST_PR1O的值可以降低μC/OSRAM(數(shù)據(jù)空間)的需求量。中相應字節(jié)的相應位置1。OSRdyGrp和OSRdyTbl[]之間的關系見圖3.3,是按以下規(guī)則給出OSRdyTbl[0]中的任何一1時,OSRdyGrp的第0位置1,OSRdyTbl[1]中的任何一位是1時,OSRdyGrp的第1位置1,當OSRdyTbl[2]中的任何一1時,OSRdyGrp的第2位置1,當OSRdyTbl[3]中的任何一1時,OSRdyGrp的第3位置1,當OSRdyTbl[4]中的任何一1時,OSRdyGrp的第4位置1,當OSRdyTbl[5]中的任何一位是1時,OSRdyGrp的第5位置1,當OSRdyTbl[6]中的任何一1時,OSRdyGrp的第6位置1,程 |=OSMapTbl[prio>>OSRdyTbl[prio>>3]|=OSMapTbl[prio&程L3.5表T3.1OSMapTbl BitMask001224345667接下去的三位用于確定是在OSRdyTbl[]數(shù)組的第幾個元素。OSMapTbl[]是在ROM中的(見文件OS_CORE.C) 字,用于限制OSRdyTbl[]數(shù)組的元素下標在0到7之間,見表3.1程序L3.6從就緒表中刪除一個任ifif((OSRdyTbl[prio>>3]&=~OSMapTbl[prio&0x07])==OSRdyGrp&=~OSMapTbl[prio>>字節(jié)的8位代表這一組的8個任務哪些進入就緒態(tài)了,低位的優(yōu)先級高于。利用這個字那個任務所在的位置這個返回值在0到7之間。確定進入就緒態(tài)的優(yōu)先級最高的任務是用以下代碼完成的,如程序L3.7所示。程序L3.7找出進入就緒態(tài)的優(yōu)先級最高的任 = =prio=(y<<3)+ OSRdyGrpOSUnMapTbl[OSRdyGrp]得到的值是3,它相應于OSRdyGrp中的第3bit3,這里假設最右邊的一位是第0bit0。類似地,OSRdyTbl[3]的值是二進制OSUnMapTbl[OSRdyTbc[3]22位。于是任務的優(yōu)先級Prio就等于2(3*8+2。利用這個優(yōu)先級的值。查任務控制塊優(yōu)先OSTCBPrioTbl[OS_TCB任務調度(TaskOSSched()完成的。OSIntExt()完成的,這個函數(shù)將在以后描述。OSSched()的代碼如程序L3.8所示。程序L3.8任務調度器(theTaskvoidOSSched{INT8Uif((OSLockNesting|OSIntNesting)==0) =OSPrioHighRdy=(INT8U)((y<<3)+if(OSPrioHighRdy!=OSPrioCur)OSTCBHighRdy=}}}中[L3.8(1)]條件語句的條件不滿足,任務調度函數(shù)OSSched()將退出,不做任務調度。這OSSched()OSIntNesting>0,OSSchedLockOSLockNesting>0。OSSched(),并且任務調度是允許的,即沒有上鎖,則任務μC/OSOSTCBHighRdyOSTCBCur816μC/OS-Ⅱ中是兩個整數(shù)的比較。并且,除非用戶實際需要做任務切換,在查任務控制塊優(yōu)先級表OSTCBPrioTbl[]OSTCBHighRdy。綜合這兩項改進,即用整數(shù)比較代替指針的比較和當需要任務切換時再查表,使得μC/OS-Ⅱ比μC/OS816通過將以OSPrioHighRdy為下標的OSTCBPrioTbl[]數(shù)組中的那個元素賦給OSTCBHighRdy來OS_TASK_SW()來完成實際上的任務切換[L3.8(6)]。μC/OS總是看起來跟剛剛發(fā)生過中斷一樣,所有微處理器的寄存器都保存在棧中。換句話說,μC/OSCPUOS_ASK_SW(RAP(TrphadlereptionhandlerSCtxSw(OSCtxw()OS_TCBighRyOSCBCr指向8μC/OSOSCtSw()OSSched()OSSched()()是用C寫的。給調度器上鎖和開鎖(LockingandUnLockingthe(L3.10的任務保持對CPU的控制權,盡管有個優(yōu)先級更高的任務進入了就緒態(tài)。然而,此時中斷是OSLockNesting減到零的時候,OSSchedUnlock()調用OSSched[L3.10(2)]也就是說,用戶程序不得調用OSMboxPend()OSQPend()OSSemPend()OSTaskSuspend(OS_PR1O_SELF)、OSTimeDly()OSTimeDlyHMSM(OSLockNesting當?shù)蛢?yōu)先級的任務要發(fā)消息給多任務的郵箱、消息隊列、信號量時(6了CPU的控制權,此時,用戶可以使用調度器函數(shù)。程序L3.9給調度器上voidOSSchedLock {{if(OSRunning==TRUE){}}voidvoidOSSchedUnlock{if(OSRunning==TRUE){if(OSLockNesting>0){if((OSLockNesting|OSIntNesting)==0){}else}}else}}}程L3.10給調度器開鎖空閑任務(Idle這個空閑任務[OSTaskIdle()]設為最低優(yōu)先級,即OS_LOWEST_PRI0??臻e任務計任(見3.08計任務使用這個計數(shù)器以確定現(xiàn)行應用軟件實際消耗的CPU時間。程序L3.11是空閑任務的代碼。在計數(shù)器加1前后,中斷是先關掉再開啟的,因為8位程序L3.11μC/OS-Ⅱ的空閑任務voidvoidOSTaskIdle(void{pdata=pdata;for(;;){}}統(tǒng)計任μC/OSOSTaskStat(),如果用戶將系統(tǒng)定義常數(shù)OS_TASK_STAT_EN(見文件OS_CFG.H)設為1,這個任務就會建立。一旦得到OS_CORE.C8OSCPUsage1個任務中調用OSStatInit((見文件OS_CORE.C話說在調用系統(tǒng)啟動函數(shù)OSStart()之前,用戶初始代碼必須先建立一個任務,在這個任務中調用系統(tǒng)統(tǒng)計初始化函數(shù)程序L3.12初始化統(tǒng)計任務voidmain{ /*初始化uC/OS- /*創(chuàng)建用戶起始任務(為了方便討論,這里以TaskStart()作為起始任務) /*開始多任務調 }voidTaskStart(void{ /*/*創(chuàng)建用戶應用程序任for(;;)}}系統(tǒng)啟動函數(shù)t()的時候,μC/OS-Ⅱ只有3個要管理的任務:TaskStart的優(yōu)先級設為次低,OS_LOWEST_PR10-1。啟動任務TaskStart()總是優(yōu)先級最高的任務。F3.4μC/OS始化函數(shù)OSInit(),該函數(shù)初始化μC/OS-Ⅱ[圖F3.4(2)]。有的處理器(例如Motorola的MC68HC11),不需要“設置”中斷向量,中斷向量已經在ROM中有了。用戶必須調用TaskStartF3.4(4)]]。TaskStart(F3.4(5)]。在這里啟動時鐘節(jié)拍是必要的,因OSStatInitOSTimeDly()2Ⅱ然后選下一個優(yōu)先級最高的進入就緒態(tài)的任務運行,這恰好是統(tǒng)計任務OSTaskStat()。讀者會在后面讀到OSTaskStat()的代碼,但粗看一下,OSTaskStat()所要做的第一件事就一定會是這樣,因為標志OSStatRdyOSInit()函數(shù)初始化為“假”,所以實際上OTaskIdl中,直到TaskStart()的延遲兩個時鐘節(jié)拍完成[圖3.4(10)]。兩個時鐘節(jié)拍之后,TaskStart(F3.4(11)]。在執(zhí)行OSStartInitOSIdleCtr其它進入就緒態(tài)的任務,OSTaskIdle()又獲得了CPU的控制權[圖F3.4(14秒鐘以后,TaskStart()繼續(xù)運行,還是在OSStatInit()中,空閑計數(shù)器將1秒鐘內計數(shù)的值存入空閑OSIdleCtrMaxF3.4(15)]。OSStarInit()將統(tǒng)計任務就緒標志OSStatRdy設為“真”[圖F3.4(16)],以此來允許兩個OSTaskStat()CPU程序L3.13統(tǒng)計任務的初始化voidvoidOSStatInit{ =0L;OSIdleCtrMax=OSIdleCtr; =TRUE;}統(tǒng)計任務OSStat()的代碼程序L3.14所示。面一段中,已經討論了為什么要等待的任務消耗了多少CPU時間。當用戶的應用程序代碼加入以后,運行空閑任務的CPU時間就最大計數(shù)值是OSStatInit()在初始化時保存在計數(shù)器最大值OSIdleCtrMax中的。CPU利用率(表達式[3.1])OSCPUsage[L3.14(2)]中的:[3.1]表達式[3.1]表達式Needtotypesetthe一旦上述計算完成,OSTaskStat()調用任務統(tǒng)計外界接入函數(shù)OSTaskStatHook()3程序L3.14統(tǒng)計任voidvoidOSTaskStat(void{INT32Urun;INT8Susage;pdatapdata=while(OSStatRdy==FALSE){OSTimeDly(2*OS_TICKS_PER_SEC);}for(;;)OSIdleCtrRun= =OSIdleCtr; =0L;if(OSIdleCtrMax>0L)usage=(INT8S)(100L-100L*run/OSIdleCtrMax);if(usage>100){OSCPUUsage=}elseif(usage<0){OSCPUUsage=0;}elseOSCPUUsage=}}elseOSCPUUsage=}}}μC/OS中的中斷處務子程序的示意碼如程序L3.15程L3.15μC/OS-II中的中斷服務子程序Motorola68020(68020再將寄存器加1,然后再寫回到變量OSIatNesting中去,就不如調用OSIatEnter()。證處理OSIntNesting時的排它性直接給OSIntNesting1比調用OSIntEnter()快得多,可能時,直接加1更好。要當心的是,在有些情況下,從OSIntEnter()返回時,會把中斷開用戶應用程序就會?。⊿IntNestin>0μCOS-F3.5[F35(1)]PUμC/SCPUCPU[F3.(2)],CPU()跳轉到中斷服務子程序[F35(3)]。如上所述,中斷服務子程序保存CPU寄存器(也叫做CPUcontext)[F.5(4)],μC/OSOSIntnter()OSntNestig直接加1[F35(5)]3.5(6)]去做。中斷服務子程序通知某任務去做事的是調用以下函數(shù)之一:OMboxPos(),OSQPost()SQPostFont(SSemPos要調用OSInExit()F3.5(7)OSIntExit(CPU[35(8[3.(9OInExi間,因為這時要做任務切換[3.5(1)]。新任務的寄存器內容要恢復并執(zhí)行中斷返回指令[3.5(1)]。3.5進入中斷函數(shù)OSIntEnter()的代碼如程序L3.16所示,從中斷服務中退出函程序L3.16通知μC/OS-Ⅱ,中斷服務子程序開始了voidvoidOSIntEnter{}voidvoidOSIntExit{if((--OSIntNesting|OSLockNesting)==0){ =OSUnMapTbl[OSRdyGrp];程L3.17通知μC/OSOSPrioHighRdyOSPrioHighRdy=(INT8U)((OSIntExitY<<3)if(OSPrioHighRdy!=OSPrioCur){OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];}}}Y是保存在全程變量OSIntExitY中的[L3.17(3)]是為了避免在任務棧中安排局部變量。這個變量在哪兒和中斷任務切換函數(shù)OSIntCtxSw(見9.04.03節(jié),中斷任務切換函OS_TASK_SW(OSSched()函數(shù)中那樣。首先是,如程序中L3.5(1)和圖F3.6(1)所示,一半的工作,即CPU寄存器入棧的工作移植μC/OS-Ⅱ。最后,調用OSIntCtxSw()時的返回地址又被推入了堆棧[L3.17(4)和有的微處理器,像Motorola68HC11中斷發(fā)生時CPU寄存器是自動入棧的,且要想允許務期間開中斷,也不需要調用OSIntEnter()或OSIntNesting加1。程序L3。18中的示/*程L3.18Motorola68HC11時鐘節(jié)μC/OS10次到100次之間,或者說10到100Hz。時鐘節(jié)拍率越高,系統(tǒng)的額外負荷就越重。時鐘50/60Hz將允許時鐘節(jié)拍器中斷放在系統(tǒng)初始化函數(shù)voidvoid{..../*/*初始化uC/OS-/*通過調用OSTaskCreate()創(chuàng)建至少一個任..;.. /*開始多任務調 }程L3.19啟動時鐘就節(jié)拍器的不正確做法這里潛在地是,時鐘節(jié)拍中斷有可能在μC/OS-Ⅱ啟動第一個任務之前發(fā)生,此時程序L3.20時鐘節(jié)拍中斷服務子程序的示意代voidvoid{}時鐘節(jié)拍函數(shù)OSTimeTick()的代碼如程序3.21所示。OSTimtick()以調用可由用戶定義的時鐘節(jié)拍外連函數(shù)OSTimTickHook()開始,這個外連函數(shù)可以將時鐘節(jié)拍函數(shù)工作要做。OSTimtick()中量大的工作是給每個用戶任務控制塊OS_TCB中的時間延時項OSTCBDly減1(如果該項不為零的話。OSTimTick()從OSTCBList開始,沿著OS_TCB鏈表voidvoidOSTimeTick{OS_TCBptcb=while(ptcb->OSTCBPrio!=OS_IDLE_PRIO){if(ptcb->OSTCBDly!=0)if(--ptcb->OSTCBDly==0)if(!(ptcb->OSTCBStat&OS_STAT_SUSPEND)) |=ptcb-OSRdyTbl[ptcb->OSTCBY]|=ptcb-}elseptcb->OSTCBDly=}}}ptcb=ptcb->OSTCBNext;} }程L3.21時鐘節(jié)拍函數(shù)OSTimtick()OSTimeTick(OSTime()[L3.21(7)]累加從開機以來的時間,用的是一個無任務級調用OSTimeTick(),如程序L3.22所示。要想這么做,得建立一個高于應用程程序L3.22時鐘節(jié)拍任務TickTask()作時鐘節(jié)拍服務voidTickTask(void {{pdata=pdata;for(;;){ /**/}}用戶當然需要先建立一個郵箱(NULL)用于發(fā)信號給上述任何告知時鐘節(jié)拍中斷已經發(fā)生了(程序L3.23程序L3.23時鐘節(jié)拍中斷服務函數(shù)OSTickISR()做節(jié)拍服務voidvoid{發(fā)送一個‘空’消息((void*)1)到時鐘節(jié)拍的郵箱}μC/OS在調用μC/OS-Ⅱ的任何其它服務之前,μC/OSOS_CORE.C緒態(tài)。OSTaskStatOS_LOW

溫馨提示

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

評論

0/150

提交評論