版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、 關(guān)于對C/OS-嵌入式實(shí)時(shí)操作系統(tǒng)內(nèi)核分析一、C/OS-概述1、C/OS-的基本概念C/OS是源碼公開的實(shí)時(shí)嵌入式操作系統(tǒng),具有源代碼開放、內(nèi)核小、實(shí)時(shí)性好的突出優(yōu)點(diǎn),能夠被移植到各種微處理器和微控制器上。我們今天所分析的C/OS-實(shí)時(shí)操作系統(tǒng)內(nèi)核正是建立在C/OS的基礎(chǔ)之上的。C/OS-是典型的微內(nèi)核實(shí)時(shí)操作系統(tǒng)。它提供了任務(wù)調(diào)度、任務(wù)管理、時(shí)間管理和任務(wù)間的通信等基本功能。與一般通用的操作系統(tǒng)相比,嵌入式實(shí)時(shí)操作系統(tǒng)既具有通用操作系統(tǒng)的基本特點(diǎn),又具有系統(tǒng)實(shí)時(shí)性、硬件的相關(guān)依賴性、軟件固態(tài)化以及應(yīng)用的專用性等特點(diǎn)。嵌入式實(shí)時(shí)操作系統(tǒng)通常包括與硬件相關(guān)的底層驅(qū)動(dòng)軟件、系統(tǒng)內(nèi)核、設(shè)備驅(qū)動(dòng)接口
2、、通信協(xié)議、圖形界面、標(biāo)準(zhǔn)化瀏覽器Browser等。評價(jià)嵌入式操作系統(tǒng)的重要指標(biāo)有實(shí)時(shí)性、可裁剪性、可擴(kuò)展性。2、C/OS-的基本性能特點(diǎn)公開源代碼、可移植性好、可固化、可裁剪、搶占式實(shí)時(shí)內(nèi)核、多任務(wù)管理、函數(shù)調(diào)用和系統(tǒng)服務(wù)的執(zhí)行時(shí)間是確定的、每個(gè)任務(wù)有自己單獨(dú)的棧、提供多系統(tǒng)服務(wù)和中斷請求可使正執(zhí)行任務(wù)暫時(shí)掛起等多個(gè)優(yōu)點(diǎn)。二、任務(wù)管理1、任務(wù)的工作狀態(tài) 任務(wù)是C/OS-中最重要的概念之一。它也被稱作為一個(gè)線程為一個(gè)簡單的程序,該程序可以認(rèn)為CPU完全只屬于該程序。每個(gè)任務(wù)都被賦予一定的優(yōu)先級,有著自己的一套CPU寄存器和??臻g。如下圖:一個(gè)任務(wù)通常是一個(gè)無限的循環(huán)。TASK()任務(wù)代碼任務(wù)初
3、始化C/OS-可以管理多達(dá)64個(gè)任務(wù),但由于其兩個(gè)任務(wù)被系統(tǒng)占用,并保留了優(yōu)先級為0、1、2、3、OS_LOWEST_PRIO-3、OS_LOWEST_PRIO-2、OS_LOWEST_PRIO-1以及OS_LOWEST_PRIO這八個(gè)任務(wù)供將來使用。因此用戶可以使用的有56個(gè)應(yīng)用任務(wù)。每個(gè)任務(wù)都有不同的優(yōu)先級,一般來說,任務(wù)的優(yōu)先級號越低,任務(wù)的優(yōu)先級越高。C/OS-總是先運(yùn)行進(jìn)入就緒態(tài)的優(yōu)先級最高的任務(wù)。下圖所示為任務(wù)所處的可能的5種狀態(tài)。在任一時(shí)刻,任務(wù)的狀態(tài)一定是這5種狀態(tài)之一。如下圖:等待或掛起收到消息等待消息掛起掛起時(shí)間到任務(wù)調(diào)度創(chuàng)建任務(wù) 中斷就緒中斷服務(wù)運(yùn)行休眠任務(wù)被占先刪除任務(wù)
4、中斷結(jié)束 2、任務(wù)調(diào)度 任務(wù)調(diào)度是實(shí)時(shí)內(nèi)核最重要的工作之一,C/OS-是搶占式實(shí)時(shí)多任務(wù)內(nèi)核,采用基于優(yōu)先級的任務(wù)調(diào)度。C/OS-的任務(wù)調(diào)度包括任務(wù)級的任務(wù)調(diào)度和中斷級的任務(wù)調(diào)度,所采用的調(diào)度算法是相同的。任務(wù)級的調(diào)度是函數(shù)OSSched()完成的,中斷級的任務(wù)調(diào)度則由函數(shù)OSIntExt()完成。其中函數(shù)OSSched()的內(nèi)容如下: Void OSSched (void) INT8U y; OS_ENTER_CRITICAL(); if (OSLockNesting|OSIntNesting)=0) y=OSUnMapTblOSRdyGrp; OSPrioHighRdy=(INT8U)(y
5、<<3)+OSUnMapTblOSRdyTbly; if(OSPrioHighRdy!=OSPrioCur) OSTCBHighRdy=OSTCBPrioTblOSPrioHighRdy; OSCtxSwCtr+; OS_TASK_SW();OS_EXET_CRITICAL(); 從上面的程序中可以了解到為了避免在調(diào)度過程中被中斷,在OSSched()開始時(shí),首先調(diào)用了OS_ENTER_CRITICAL()關(guān)中斷,然后判斷任務(wù)調(diào)度器是否上鎖或調(diào)用是否來自中斷服務(wù)子程序,如果不是,則開始任務(wù)調(diào)度。如下圖所示:為一個(gè)任務(wù)就緒表。下圖便是一個(gè)相關(guān)例子,把prio為29的任務(wù)設(shè)置在任務(wù)就緒
6、狀態(tài): 從任務(wù)就緒表中獲取優(yōu)先級別最高的就緒任務(wù)可用如下類似的代碼: y = OSUnMapTalOSRdyGrp; /D5、D4、D3位x = OSUnMapTalOSRdyTbly; /D2、D1、D0位prio = (y<<3)+x;/優(yōu)先級別 或y = OSUnMapTblOSRdyGrp;prio = (INT8U)(y << 3) + OSUnMapTblOSRdyTbly);3、 C/OS-的初始化 C/OS-要求用戶首先調(diào)用系統(tǒng)初始化函數(shù)OSIint(),對C/OS-所有的變量和數(shù)據(jù)結(jié)構(gòu)進(jìn)行初始化,然后調(diào)用函數(shù)OSTaskCreate
7、()或OSTaskCreateExt()建立用戶任務(wù),最后通過調(diào)用OSStart()函數(shù)啟動(dòng)多任務(wù)。Void main (void) OSInit(); . . 通過調(diào)用函數(shù)OSTaskCreate()或OSTaskCreateExt()創(chuàng)建至少一個(gè)任務(wù); OSStart();/*開始調(diào)用調(diào)度!OSStart()永遠(yuǎn)不會(huì)返回*/當(dāng)調(diào)用OSStart()函數(shù)時(shí),OSStart()函數(shù)從任務(wù)就緒表中找出用戶建立的優(yōu)先級最高任務(wù)的控制塊。然后,OSStart()函數(shù)調(diào)用高優(yōu)先級就緒任務(wù)啟動(dòng)函數(shù)OSStartHighRdy()。這個(gè)函數(shù)的任務(wù)是把任務(wù)棧中的任務(wù)狀態(tài)參數(shù)值恢復(fù)到CPU寄存器中,然后執(zhí)行一
8、條中斷返回指令,中斷返回指令強(qiáng)制執(zhí)行該任務(wù)代碼。其代碼如下:void OSStart (void) INT8U y; INT8U x; if (OSRunning = FALSE) y = OSUnMapTblOSRdyGrp; x = OSUnMapTblOSRdyTbly; OSPrioHighRdy = (INT8U)(y << 3) + x); OSPrioCur = OSPrioHighRdy; OSTCBHighRdy = OSTCBPrioTblOSPrioHighRdy; OSTCBCur = OSTCBHighRdy; OSStartHighRdy(); 4、任務(wù)
9、的創(chuàng)建應(yīng)用程序通過調(diào)用OSTaskCreate( ) 函數(shù)來創(chuàng)建一個(gè)任務(wù),OSTaskCreate( )函數(shù)的原型如下: INT8U OSTaskCreate void (*task)(void *pd),/指向任務(wù)的指針 void *pdata,/傳遞給任務(wù)的參數(shù) OS_STK *ptos,/指向任務(wù)堆棧棧頂?shù)闹羔?INT8U prio/任務(wù)的優(yōu)先級INT8U OSTaskCreate (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT8U prio) OS_STK *psp; /初始化任務(wù)堆棧指針變量,返回新的棧頂指針I(yè)
10、NT8U err; /定義(獲得并定義初始化任務(wù)控制塊)是否成功#if OS_ARG_CHK_EN > 0 /所有參數(shù)必須在指定的參數(shù)內(nèi)if (prio > OS_LOWEST_PRIO) /檢查任務(wù)優(yōu)先級是否合法return (OS_PRIO_INVALID); /參數(shù)指定的優(yōu)先級大于OS_LOWEST_PRIO#endifOS_ENTER_CRITICAL(); /關(guān)閉中斷if (OSTCBPrioTblprio = (OS_TCB *)0) /確認(rèn)優(yōu)先級未被使用,即就緒態(tài)為0 OSTCBPrioTblprio = (OS_TCB *)1; /保留這個(gè)優(yōu)先級,將就緒態(tài)設(shè)為1OS
11、_EXIT_CRITICAL(); /打開中斷psp = (OS_STK *)OSTaskStkInit(task, pdata, ptos, 0); /初始化任務(wù)堆棧err = OS_TCBInit(prio, psp, (OS_STK *)0, 0, 0, (void *)0, 0); /獲得并初始化任務(wù)控制塊if (err = OS_NO_ERR) /任務(wù)控制初始化成功 OS_ENTER_CRITICAL(); /關(guān)閉中斷OSTaskCtr+; /任務(wù)計(jì)數(shù)器加1OS_EXIT_CRITICAL(); /打開中斷if (OSRunning = TRUE) /檢查是否有(某個(gè))任務(wù)在運(yùn)行 O
12、S_Sched();/任務(wù)調(diào)度,最高任務(wù)優(yōu)先級運(yùn)行 else /否則,任務(wù)初始化失敗OS_ENTER_CRITICAL(); /關(guān)閉中斷OSTCBPrioTblprio = (OS_TCB *)0; /放棄任務(wù),設(shè)此任務(wù)就緒態(tài)為0OS_EXIT_CRITICAL();/打開中斷 return (err); /返回(獲得并定義初始化任務(wù)控制塊是否成功) OS_EXIT_CRITICAL(); /打開中斷return (OS_PRIO_EXIST); /返回(具有該優(yōu)先級的任務(wù)已經(jīng)存在)三、中斷和時(shí)間管理1、中斷處理C/OS-II系統(tǒng)響應(yīng)中斷的過程為:系統(tǒng)接收到中斷請求后,這時(shí)如果CPU處于中斷允
13、許狀態(tài)(即中斷是開放的),系統(tǒng)就會(huì)中止正在運(yùn)行的當(dāng)前任務(wù),而按照中斷向量的指向轉(zhuǎn)而去運(yùn)行中斷服務(wù)子程序,當(dāng)中斷服務(wù)子程序的運(yùn)行結(jié)束后,系統(tǒng)將會(huì)根據(jù)情況返回到被中止的任務(wù)繼續(xù)運(yùn)行或者轉(zhuǎn)向運(yùn)行另一個(gè)具有更高優(yōu)先級別的就緒任務(wù)。中斷服務(wù)子程序運(yùn)行結(jié)束之后,系統(tǒng)將會(huì)根據(jù)情況進(jìn)行一次任務(wù)調(diào)度去運(yùn)行優(yōu)先級別最高的就緒任務(wù),而并不是一定要接續(xù)運(yùn)行被中斷的任務(wù)的。 中斷嵌套層數(shù)計(jì)數(shù)器和鎖定嵌套計(jì)數(shù)器OSLockNesting二者都必須是零,OSRdyTbl所需的檢索值Y是保存在全程變量OSIntExitY中檢查具有最高優(yōu)先級別的就緒任務(wù)的優(yōu)先級是否是正在運(yùn)行的任務(wù)的優(yōu)先級,將任務(wù)控制塊優(yōu)先級表保存到指向最高級
14、優(yōu)先級就緒任務(wù)控制塊的指針,上下文切換的次數(shù)統(tǒng)計(jì)任務(wù)計(jì)數(shù)器。做中斷任務(wù)切換:void OSIntEnter (void) if (OSRunning = TRUE) if (OSIntNesting < 255) OSIntNesting+; /中斷嵌套層數(shù)計(jì)數(shù)器加一 2、時(shí)間管理C/OS-II需要用戶提供周期性信號源,用于實(shí)現(xiàn)時(shí)間延時(shí)和確認(rèn)超時(shí)。節(jié)拍率應(yīng)在每秒10-100次之間。時(shí)鐘節(jié)拍率越高,系統(tǒng)的額外負(fù)荷就越重。 時(shí)鐘節(jié)拍是一種特殊的中斷,C/OS-II中的時(shí)鐘節(jié)拍服務(wù)是在通過在中斷服務(wù)子程序中調(diào)用OSTimeTick()函數(shù)實(shí)現(xiàn)的。時(shí)鐘節(jié)拍的中斷服務(wù)子程序如下所示: Void O
15、STickISR(void)保存處理器寄存器的值;調(diào)用OSIntEnter()或?qū)SIntNesting加1;調(diào)用OSTimeTick();/*檢查每個(gè)任務(wù)的時(shí)間延時(shí)*/調(diào)用OSIntExit();恢復(fù)處理器寄存器的值;執(zhí)行中斷返回指令;其中時(shí)鐘節(jié)拍函數(shù)OSTimeTick()的主要工作是給每個(gè)任務(wù)控制塊OS_TCB中的時(shí)間延時(shí)項(xiàng)OSTCBDly減1。當(dāng)某任務(wù)的任務(wù)模塊中的延時(shí)項(xiàng)OSTCBDly減為0,則該任務(wù)將進(jìn)入就緒任務(wù)表。因此,OSTimeTick()的執(zhí)行時(shí)間與應(yīng)用程序中建立了多少任務(wù)有關(guān)。四、任務(wù)之間的通信與同步1、任務(wù)互斥和同步 系統(tǒng)中的多個(gè)任務(wù)在運(yùn)行時(shí),經(jīng)常需要互相無沖突地訪問
16、同一個(gè)共享資源,或者需要互相支持和依賴,甚至有時(shí)還要互相加以必要的限制和制約,才保證任務(wù)的順利運(yùn)行。因此,操作系統(tǒng)必須具有對任務(wù)的運(yùn)行進(jìn)行協(xié)調(diào)的能力,從而使任務(wù)之間可以無沖突、流暢地同步運(yùn)行,而不致導(dǎo)致災(zāi)難性的后果。與人們依靠通信來互相溝通,從而使人際關(guān)系和諧、工作順利的做法一樣,計(jì)算機(jī)系統(tǒng)是依靠任務(wù)之間的良好通信來保證任務(wù)與任務(wù)的同步的。有以下3種方法可以解決任務(wù)的互斥。(1) 關(guān)閉中斷法當(dāng)一個(gè)任務(wù)進(jìn)入臨界區(qū)后,首先關(guān)中斷,然后就可以去訪問共享資源。當(dāng)它從臨界區(qū)推出后,再把中斷打開。關(guān)閉中斷法雖然簡單有效,但也有明顯的缺點(diǎn)。首先,中斷關(guān)閉后,如果后面由于種種原因不能再及時(shí)打開,那么整個(gè)系統(tǒng)就
17、有可能崩潰。其次,關(guān)閉中斷后,所有的任務(wù)將被阻止,無法獲得運(yùn)行的機(jī)會(huì)。因此,關(guān)閉中斷法不能作為一種普遍使用的互斥實(shí)現(xiàn)方法。(2) 繁忙等待法當(dāng)一個(gè)任務(wù)進(jìn)入臨界區(qū)時(shí),首先檢查一下是否允許進(jìn)入,若允許,就直接進(jìn)入;若不允許,就在那里循環(huán)地等待。繁忙等待法的缺點(diǎn)是要不斷地執(zhí)行測試指令,會(huì)浪費(fèi)大量的CPU時(shí)間。(3) 信號量法 信號量是一種約定機(jī)制,在多任務(wù)內(nèi)核中將信號量用于:控制共享資源的使用權(quán),標(biāo)志某事件的發(fā)生,使兩個(gè)任務(wù)的行為同步。 信號量是由操作系統(tǒng)維護(hù),任務(wù)不能直接修改它的值,只能通過初始化和兩個(gè)標(biāo)準(zhǔn)原語來對它進(jìn)行訪問。2、任務(wù)間的通信任務(wù)間的同步依賴于任務(wù)間的通信。在C/OS-II中,是使
18、用信號量、郵箱(消息郵箱)和消息隊(duì)列這些被稱作事件的中間環(huán)節(jié)來實(shí)現(xiàn)任務(wù)之間的通信的。把一個(gè)任務(wù)置于等待狀態(tài)要調(diào)用OS_EventTaskWait( )函數(shù)。該函數(shù)的原型為:void OS_EventTaskWait (OS_EVENT *pevent/事件控制塊的指針);函數(shù)OS_EventTaskWait ( ),將在任務(wù)調(diào)用函數(shù)OS×××Pend( ) 請求一個(gè)事件時(shí),被OS×××Pend( )所調(diào)用。如果一個(gè)正在等待的任務(wù)具備了可以運(yùn)行的條件,那么就要使它進(jìn)入就緒狀態(tài)。這時(shí)要調(diào)用OS_EventTaskRdy( )函數(shù)。該函數(shù)的
19、作用就是把調(diào)用這個(gè)函數(shù)的任務(wù)在任務(wù)等待表中的位置清0(解除等待狀態(tài))后,再把任務(wù)在任務(wù)就緒表中對應(yīng)的位置1,然后引發(fā)一次任務(wù)調(diào)度。OS_EventTaskRdy( )函數(shù)的原型為:INT8U OS_EventTaskRdy (OS_EVENT *pevent, /事件控制塊的指針void *msg, /未使用INT8U msk/清除TCB狀態(tài)標(biāo)志掩碼); 函數(shù)OS_EventTaskRdy ( )將在任務(wù)調(diào)用函數(shù)OS×××Post ( ) 發(fā)送一個(gè)事件時(shí),被函數(shù)OS×××Post ( )所調(diào)用。如果一個(gè)正在等待事件的任務(wù)已經(jīng)
20、超過了等待的時(shí)間,卻仍因?yàn)闆]有獲取事件等原因而未具備可以運(yùn)行的條件,卻又要使它進(jìn)入就緒狀態(tài),這時(shí)要調(diào)用OS_EventTO( )函數(shù)。OS_EventTO( )函數(shù)的原型為:void OS_EventTO (OS_EVENT *pevent /事件控制塊的指針); 函數(shù)OS_EventTO ( )將在任務(wù)調(diào)用OS×××Pend( ) 請求一個(gè)事件時(shí),被函數(shù)OS×××Pend( )所調(diào)用。3、信號量實(shí)例如下為一個(gè)信號量法控制任務(wù)之間調(diào)用的例子:在使用信號量之前,應(yīng)用程序必須調(diào)用函數(shù)OSSemCreate( )來創(chuàng)建一個(gè)信號量,
21、OSSemCreate( )的原型為:OS_EVENT *OSSemCreate (INT16U cnt/信號量計(jì)數(shù)器初值);函數(shù)的返回值為已創(chuàng)建的信號量的指針。任務(wù)通過調(diào)用函數(shù)OSSemPend( )請求信號量,函數(shù)OSSemPend( )的原型如下:void OSSemPend ( OS_EVENT *pevent,/信號量的指針I(yè)NT16U timeout, /等待時(shí)限INT8U *err);/錯(cuò)誤信息參數(shù)pevent是被請求信號量的指針。為防止任務(wù)因得不到信號量而處于長期的等待狀態(tài),函數(shù)OSSemPend允許用參數(shù)timeout設(shè)置一個(gè)等待時(shí)間的限制,當(dāng)任務(wù)等待的時(shí)間超過timeout
22、時(shí)可以結(jié)束等待狀態(tài)而進(jìn)入就緒狀態(tài)。如果參數(shù)timeout被設(shè)置為0,則表明任務(wù)的等待時(shí)間為無限長。任務(wù)獲得信號量,并在訪問共享資源結(jié)束以后,必須要釋放信號量,釋放信號量也叫做發(fā)送信號量,發(fā)送信號量需調(diào)用函數(shù)OSSemPost ( )。OSSemPost ( )函數(shù)在對信號量的計(jì)數(shù)器操作之前,首先要檢查是否還有等待該信號量的任務(wù)。如果沒有,就把信號量計(jì)數(shù)器OSEventCnt加一;如果有,則調(diào)用調(diào)度器OS_Sched( )去運(yùn)行等待任務(wù)中優(yōu)先級別最高的任務(wù)。函數(shù)OSSemPost ( )的原型為:INT8U OSSemPost (OS_EVENT *pevent/信號量的指針);調(diào)用函數(shù)成功后,
23、函數(shù)返回值為OS_ON_ERR,否則會(huì)根據(jù)具體錯(cuò)誤返回OS_ERR_EVENT_TYPE、OS_SEM_OVF。應(yīng)用程序如果不需要某個(gè)信號量了,那么可以調(diào)用函數(shù)OSSemDel( )來刪除該信號量,這個(gè)函數(shù)的原型為:OS_EVENT *OSSemDel (OS_EVENT *pevent, /信號量的指針I(yè)NT8U opt, /刪除條件選項(xiàng)INT8U *err/錯(cuò)誤信息);通過例子可以發(fā)現(xiàn),使用信號量的任務(wù)是否能夠運(yùn)行是受任務(wù)的優(yōu)先級別和是否占用信號量兩個(gè)條件約束的,而信號量的約束高于優(yōu)先級別的約束。于是當(dāng)出現(xiàn)低優(yōu)先級別的任務(wù)與高優(yōu)先級別的任務(wù)使用同一個(gè)信號量,而系統(tǒng)中還存有別的中等優(yōu)先級別的
24、任務(wù)時(shí),如果低優(yōu)先級別的任務(wù)先獲得了信號量,就會(huì)使高級別的任務(wù)處于等待狀態(tài),而那些不使用該信號量的中等級別的任務(wù)卻可以剝奪低優(yōu)先級別的任務(wù)的CPU使用權(quán)而先于高優(yōu)先級別的任務(wù)而運(yùn)行了。我們可以使獲得信號量任務(wù)的優(yōu)先級別在使用共享資源期間暫時(shí)提升到所有任務(wù)最高優(yōu)先級的高一個(gè)級別上,以使該任務(wù)不被其他的任務(wù)所打斷,從而能盡快地使用完共享資源并釋放信號量,然后在釋放了信號量之后再恢復(fù)該任務(wù)原來的優(yōu)先級別。4、郵箱創(chuàng)建郵箱需要調(diào)用函數(shù)OSMboxCreate ( ),這個(gè)函數(shù)的原型為:OS_EVENT *OSMboxCreate (void *msg/消息指針); 函數(shù)中的參數(shù)msg為消息的指針,函數(shù)
25、的返回值為消息郵箱的指針。調(diào)用函數(shù)OSMboxCreate ( )需先定義msg的初始值。在一般的情況下,這個(gè)初始值為NULL;但也可以事先定義一個(gè)郵箱,然后把這個(gè)郵箱的指針作為參數(shù)傳遞到函數(shù)OSMboxCreate ( )中,使之一開始就指向一個(gè)郵箱。任務(wù)可以通過調(diào)用函數(shù)OSMboxPost ( )向消息郵箱發(fā)送消息,這個(gè)函數(shù)的原型為:INT8U OSMboxPost (OS_EVENT *pevent, /消息郵箱指針void *msg/消息指針);當(dāng)一個(gè)任務(wù)請求郵箱時(shí)需要調(diào)用函數(shù)OSMboxPend( ),這個(gè)函數(shù)的主要作用就是查看郵箱指針OSEventPtr是否為NULL,如果不是NU
26、LL就把郵箱中的消息指針返回給調(diào)用函數(shù)的任務(wù),同時(shí)用OS_NO_ERR通過函數(shù)的參數(shù)err通知任務(wù)獲取消息成功;如果郵箱指針OSEventPtr是NULL,則使任務(wù)進(jìn)入等待狀態(tài),并引發(fā)一次任務(wù)調(diào)度。函數(shù)OSMboxPend( )的原型為:void *OSMboxPend (OS_EVENT *pevent, /請求消息郵箱指針I(yè)NT16U timeout, /等待時(shí)限INT8U *err/錯(cuò)誤信息);5、消息隊(duì)列使用消息隊(duì)列可以在任務(wù)之間傳遞多條消息。消息隊(duì)列由三個(gè)部分組成:事件控制塊、消息隊(duì)列和消息。當(dāng)把事件控制塊成員OSEventType的值置為OS_EVENT_TYPE_Q時(shí),該事件控制
27、塊描述的就是一個(gè)消息隊(duì)列。消息隊(duì)列相當(dāng)于一個(gè)共用一個(gè)任務(wù)等待列表的消息郵箱數(shù)組,事件控制塊成員OSEventPtr指向了一個(gè)叫做隊(duì)列控制塊(OS_Q)的結(jié)構(gòu),該結(jié)構(gòu)管理了一個(gè)數(shù)組MsgTbl ,該數(shù)組中的元素都是一些指向消息的指針。創(chuàng)建一個(gè)消息隊(duì)列首先需要定義一指針數(shù)組,然后把各個(gè)消息數(shù)據(jù)緩沖區(qū)的首地址存入這個(gè)數(shù)組中,然后再調(diào)用函數(shù)OSQCreate( )來創(chuàng)建消息隊(duì)列。創(chuàng)建消息隊(duì)列函數(shù)OSQCreate( )的原型為:OS_EVENT OSQCreate(void*start,/指針數(shù)組的地址INT16U size/數(shù)組長度);請求消息隊(duì)列的目的是為了從消息隊(duì)列中獲取消息。任務(wù)請求消息隊(duì)列需
28、要調(diào)用函數(shù)OSQPend( ),該函數(shù)的原型為:void*OSQPend(OS_EVENT*pevent,/所請求的消息隊(duì)列的指針I(yè)NT16U timeout,/等待時(shí)限INT8U*err/錯(cuò)誤信息);任務(wù)需要通過調(diào)用函數(shù)OSQPost( )或OSQPostFront( )來向消息隊(duì)列發(fā)送消息。函數(shù)OSQPost( )以FIFO(先進(jìn)先出)的方式組織消息隊(duì)列,函數(shù)OSQPostFront( )以LIFO(后進(jìn)先出)的方式組織消息隊(duì)列。這兩個(gè)函數(shù)的原型分別為: INT8U OSQPost(OS_EVENT*pevent,/消息隊(duì)列的指針void*msg/消息指針);和INT8U OSQ
29、Post(OS_EVENT*pevent, /消息隊(duì)列的指針void*msg/消息指針);函數(shù)中的參數(shù)msg為待發(fā)消息的指針。五、C/OS-的移植分析 1、移植所謂移植,是指一個(gè)操作系統(tǒng)可以在某個(gè)微處理器或者微控制器上運(yùn)行。雖然C/OS-的大部分源代碼是用C語言寫成的,仍需要用C語言和匯編語言完成一些與處理器相關(guān)的代碼。2、產(chǎn)生可重入代碼可重入代碼指的是一段代碼可以被多個(gè)任務(wù)同時(shí)調(diào)用,而不必?fù)?dān)心會(huì)破壞數(shù)據(jù)。也就是說,可重入型函數(shù)在任何時(shí)刻都可以被中斷執(zhí)行,過一段時(shí)間以后又可以繼續(xù)運(yùn)行,而不會(huì)因?yàn)樵诤瘮?shù)中斷時(shí)被其它的任務(wù)重新調(diào)用,影響函數(shù)中的數(shù)據(jù)。如下為一個(gè)可重入型函數(shù) Void swap(in
30、t *x,int*y) Int temp; temp=*x; *x=*y; *y=temp;運(yùn)用局部變量temp作為變量。C編譯器把局部變量分配在棧中。多次調(diào)用同一個(gè)函數(shù),可以保證每次的temp互不影響。C/OS-中進(jìn)行任務(wù)調(diào)度時(shí),會(huì)把當(dāng)前任務(wù)的CPU寄存器存放到此任務(wù)的堆棧中,然后,再從另一個(gè)任務(wù)的堆棧中恢復(fù)原來的工作寄存器,繼續(xù)運(yùn)行另一個(gè)任務(wù)。所以寄存器的入棧和出棧是C/OS-中多任務(wù)調(diào)度的基礎(chǔ)。3、設(shè)置與處理器和編譯器相關(guān)的代碼C/OS-定義了兩個(gè)宏來禁止和允許中斷:OS_ENTER_CRITICAL()和OS_EXT_CRITICAL()。C/OS-需要先禁止中斷,在訪問代碼的臨界區(qū),
31、并在訪問完畢后重新允許中斷。如下: INTS_OFF mrs r0,cpsr; mov r1,r0; orr r1,r1,#0xc0; msr CPSR,r1; and r0,r0,#0x80; mov pc,lr; INTS_ON mrs r0,cpsr; bic r0,r0,#0xc0; msr CPSR,r1; mov pc,lr;絕大多數(shù)的微處理器和微控制器的棧堆是從上往下增長的。4、與操作系統(tǒng)相關(guān)的函數(shù)任務(wù)堆棧初始化函數(shù)OSTaskStklnit,用戶傳遞任務(wù)的地址、pdata指針、任務(wù)的堆棧棧頂指針和任務(wù)的優(yōu)先級給OSTaskCreate()函數(shù)和OSTaskCreateExt()函數(shù)。 當(dāng)OSTaskCreateHook()函數(shù)被調(diào)用時(shí),它會(huì)收到指向已建立任務(wù)的OS_TCB的指針,這樣它就可以訪問所有的結(jié)構(gòu)成員了。 當(dāng)任務(wù)被刪除時(shí)就會(huì)調(diào)用OSTaskDelHook()函數(shù), OSTaskDelHook()函數(shù)可以檢驗(yàn)TCB擴(kuò)展是否被建立并進(jìn)行一些清除操作。 當(dāng)任務(wù)切換時(shí)就會(huì)調(diào)用OSTaskSwHook()函數(shù),其期間中斷一直都是被禁止的。 OSTaskStatHook()函數(shù)每秒種都會(huì)被OSTaskStat()函數(shù)調(diào)用一次,用戶可以用OSTaskStatHook()函數(shù)來擴(kuò)展統(tǒng)計(jì)功能。OSTaskTickHook()函數(shù)在每個(gè)時(shí)鐘節(jié)拍都會(huì)被OSTa
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度智能硬件庫存質(zhì)押擔(dān)保協(xié)議3篇
- 專業(yè)化危險(xiǎn)品運(yùn)輸安全承諾協(xié)議模板版
- 2024建筑模板購銷合同范本
- 2025年度LED廣告車租賃與旅游景觀點(diǎn)亮工程合同3篇
- 2024暑期兼職項(xiàng)目人力資源派遣合同3篇
- 2025版高標(biāo)準(zhǔn)承包魚塘養(yǎng)殖基地管理合同3篇
- 2024智能音響控制系統(tǒng)設(shè)計(jì)與施工合同
- 2024某城市地鐵線路擴(kuò)建工程勘察設(shè)計(jì)合同
- ‘卓爾系’產(chǎn)品2024年度庫存管理與合作合同
- 2024版房地產(chǎn)全程策劃合同
- 2024年突發(fā)事件新聞發(fā)布與輿論引導(dǎo)合同
- 2025年中考語文復(fù)習(xí)之現(xiàn)代文閱讀:非連續(xù)性文本閱讀(10題)
- GB/T 9755-2024合成樹脂乳液墻面涂料
- 商業(yè)咨詢報(bào)告范文模板
- 2024年度軟件定制開發(fā)合同(ERP系統(tǒng))3篇
- 家族族譜模板
- 家譜修編倡議書范文
- 老干工作業(yè)務(wù)培訓(xùn)
- 2024年山東省高中自主招生數(shù)學(xué)模擬試卷試題(含答案)
- (正式版)JBT 10437-2024 電線電纜用可交聯(lián)聚乙烯絕緣料
- 教科版三年級上冊科學(xué)期末測試卷(二)【含答案】
評論
0/150
提交評論