ucosII經(jīng)典入門3_第1頁(yè)
ucosII經(jīng)典入門3_第2頁(yè)
ucosII經(jīng)典入門3_第3頁(yè)
ucosII經(jīng)典入門3_第4頁(yè)
ucosII經(jīng)典入門3_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第4章 任務(wù)的同步與通信系統(tǒng)中的多個(gè)任務(wù)在運(yùn)行時(shí),經(jīng)常需要互相無(wú)沖突地訪問(wèn)同一個(gè)共享資源,或者需要互相支持和依賴,甚至有時(shí)還要互相加以必要的限制和制約,才保證任務(wù)的順利運(yùn)行。因此,操作系統(tǒng)必須具有對(duì)任務(wù)的運(yùn)行進(jìn)行協(xié)調(diào)的能力,從而使任務(wù)之間可以無(wú)沖突、流暢地同步運(yùn)行,而不致導(dǎo)致災(zāi)難性的后果。與人們依靠通信來(lái)互相溝通,從而使人際關(guān)系和諧、工作順利的做法一樣,計(jì)算機(jī)系統(tǒng)是依靠任務(wù)之間的良好通信來(lái)保證任務(wù)與任務(wù)的同步的。 例如,兩個(gè)任務(wù):任務(wù)A和任務(wù)B,它們需要通過(guò)訪問(wèn)同一個(gè)數(shù)據(jù)緩沖區(qū)合作完成一項(xiàng)工作,任務(wù)A負(fù)責(zé)向緩沖區(qū)寫入數(shù)據(jù),任務(wù)B負(fù)責(zé)從緩沖區(qū)讀取該數(shù)據(jù)。顯然,當(dāng)任務(wù)A還未向緩沖區(qū)寫入數(shù)據(jù)時(shí)(緩沖

2、區(qū)為空時(shí)),任務(wù)B因不能從緩沖區(qū)得到有效數(shù)據(jù)而應(yīng)該處于等待狀態(tài),只有等任務(wù)A向緩沖區(qū)寫入了數(shù)據(jù)之后,才應(yīng)該通知任務(wù)B去取數(shù)據(jù)。例如,任務(wù)A和任務(wù)B共享一臺(tái)打印機(jī),如果系統(tǒng)已經(jīng)把打印機(jī)分配給了任務(wù)A,則任務(wù)B因不能獲得打印機(jī)的使用權(quán)而應(yīng)該處于等待狀態(tài),只有當(dāng)任務(wù)A把打印機(jī)釋放后,系統(tǒng)才能喚醒任務(wù)B使其獲得打印機(jī)的使用權(quán)。如果這兩個(gè)任務(wù)不這樣做,那么也會(huì)造成極大的混亂 。總之,多個(gè)任務(wù)共享同一資源或有工作順序要求時(shí),在正式工作之前要互相打招呼 。黃宏:別走??!宋丹丹:我自己的腿,我愛(ài)走就走,你管不著!黃宏:腿是你自己的,但手是咱倆的呀! 事件 任務(wù)間的同步依賴于任務(wù)間的通信。在C/OS-II中,是

3、使用信號(hào)量、郵箱(消息郵箱)和消息隊(duì)列這些被稱作事件的中間環(huán)節(jié)來(lái)實(shí)現(xiàn)任務(wù)之間的通信的。 宋丹丹黃宏一個(gè)簡(jiǎn)單的信號(hào)量1/0收信方發(fā)信方共享資源事件控制塊為了把描述事件的數(shù)據(jù)結(jié)構(gòu)統(tǒng)一起來(lái),C/OS-II使用叫做事件控制塊ECB的數(shù)據(jù)結(jié)構(gòu)來(lái)描述諸如信號(hào)量、郵箱(消息郵箱)和消息隊(duì)列這些事件。事件控制塊中包含包括等待任務(wù)表在內(nèi)的所有有關(guān)事件的數(shù)據(jù) typedef struct INT8U OSEventType;/事件的類型事件的類型 INT16U OSEventCnt;/信號(hào)量計(jì)數(shù)器信號(hào)量計(jì)數(shù)器 void *OSEventPtr;/消息或消息隊(duì)列的指針消息或消息隊(duì)列的指針 INT8U OSEvent

4、Grp;/等待事件的任務(wù)組等待事件的任務(wù)組 INT8U OSEventTblOS_EVENT_TBL_SIZE;/任務(wù)等待表任務(wù)等待表 OS_EVENT;把 一 個(gè) 任 務(wù) 置 于 等 待 狀 態(tài) 要 調(diào) 用OS_EventTaskWait( )函數(shù)。該函數(shù)的原型為: void OS_EventTaskWait (OS_EVENT *pevent /事件控制塊的指針);函數(shù)OS_EventTaskWait ( ),將在任務(wù)調(diào)用函數(shù)OSPend( ) 請(qǐng)求一個(gè)事件時(shí),被OSPend( )所調(diào)用。 如果一個(gè)正在等待的任務(wù)具備了可以運(yùn)行的條件,那么就要使它進(jìn)入就緒狀態(tài)。這時(shí)要調(diào)用OS_EventTa

5、skRdy( )函數(shù)。該函數(shù)的作用就是把調(diào)用這個(gè)函數(shù)的任務(wù)在任務(wù)等待表中的位置清0(解除等待狀態(tài))后,再把任務(wù)在任務(wù)就緒表中對(duì)應(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ù)OSPost ( ) 發(fā)送一個(gè)事件時(shí),被函數(shù)OSPost ( )所調(diào)用。 如果一個(gè)正在等待事件的任務(wù)已經(jīng)超過(guò)了等待的時(shí)間,卻仍因?yàn)闆](méi)有獲取事件等原因而

6、未具備可以運(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)用OSPend( ) 請(qǐng)求一個(gè)事件時(shí),被函數(shù)OSPend( )所調(diào)用。 空事件控制塊鏈表 在C/OS-II初始化時(shí),系統(tǒng)會(huì)在初始化函數(shù)OSInit( )中按應(yīng)用程序使用事件的總數(shù)OS_MAX_EVENTS(在文件OS_CFG.H中定義),創(chuàng)建OS_MAX_EVENTS個(gè)空事件控制塊并借用成員OSEventPtr作為鏈接指針,把這些空事

7、件控制塊鏈接成一個(gè)單向鏈表。由于鏈表中的所有控制塊尚未與具體事件相關(guān)聯(lián),故該鏈表叫做空事件控制塊鏈表。以后,每當(dāng)應(yīng)用程序創(chuàng)建一個(gè)事件時(shí),系統(tǒng)就會(huì)從鏈表中取出一個(gè)空事件控制塊,并對(duì)它進(jìn)行初始化以描述該事件。而當(dāng)應(yīng)用程序刪除一個(gè)事件時(shí),就會(huì)將該事件的控制塊歸還給空事件控制塊鏈表 信號(hào)量及其操作 在使用信號(hào)量之前,應(yīng)用程序必須調(diào)用函數(shù)OSSemCreate( )來(lái)創(chuàng)建一個(gè)信號(hào)量,OSSemCreate( )的原型為: OS_EVENT *OSSemCreate (INT16U cnt/信號(hào)量計(jì)數(shù)器初值); 函數(shù)的返回值為已創(chuàng)建的信號(hào)量的指針。 任務(wù)通過(guò)調(diào)用函數(shù)OSSemPend( )請(qǐng)求信號(hào)量,函數(shù)

8、OSSemPend( )的原型如下: void OSSemPend ( OS_EVENT *pevent,/信號(hào)量的指針 INT16U timeout, /等待時(shí)限INT8U *err);/錯(cuò)誤信息 參數(shù)pevent是被請(qǐng)求信號(hào)量的指針。為防止任務(wù)因得不到信號(hào)量而處于長(zhǎng)期的等待狀態(tài),函數(shù)OSSemPend允許用參數(shù)timeout設(shè)置一個(gè)等待時(shí)間的限制,當(dāng)任務(wù)等待的時(shí)間超過(guò)timeout時(shí)可以結(jié)束等待狀態(tài)而進(jìn)入就緒狀態(tài)。如果參數(shù)timeout被設(shè)置為0,則表明任務(wù)的等待時(shí)間為無(wú)限長(zhǎng)。任務(wù)獲得信號(hào)量,并在訪問(wèn)共享資源結(jié)束以后,必須要釋放信號(hào)量,釋放信號(hào)量也叫做發(fā)送信號(hào)量,發(fā)送信號(hào)量需調(diào)用函數(shù)OSS

9、emPost ( )。OSSemPost ( )函數(shù)在對(duì)信號(hào)量的計(jì)數(shù)器操作之前,首先要檢查是否還有等待該信號(hào)量的任務(wù)。如果沒(méi)有,就把信號(hào)量計(jì)數(shù)器OSEventCnt加一;如果有,則調(diào)用調(diào)度器OS_Sched( )去運(yùn)行等待任務(wù)中優(yōu)先級(jí)別最高的任務(wù)。函數(shù)OSSemPost ( )的原型為: INT8U OSSemPost (OS_EVENT *pevent /信號(hào)量的指針); 調(diào)用函數(shù)成功后,函數(shù)返回值為OS_ON_ERR,否則會(huì)根據(jù)具體錯(cuò)誤返回OS_ERR_EVENT_TYPE、OS_SEM_OVF。 應(yīng)用程序如果不需要某個(gè)信號(hào)量了,那么可以調(diào)用函數(shù)OSSemDel( )來(lái)刪除該信號(hào)量,這個(gè)函

10、數(shù)的原型為: OS_EVENT *OSSemDel (OS_EVENT *pevent, /信號(hào)量的指針I(yè)NT8U opt, /刪除條件選項(xiàng)INT8U *err/錯(cuò)誤信息); 互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)在可剝奪型內(nèi)核中,當(dāng)任務(wù)以獨(dú)占方式使用共享資源時(shí),會(huì)出現(xiàn)低優(yōu)先級(jí)任務(wù)先于高優(yōu)先級(jí)任務(wù)而被運(yùn)行的現(xiàn)象,這種現(xiàn)象叫做任務(wù)優(yōu)先級(jí)反轉(zhuǎn)。在一般情況下是不允許出現(xiàn)這種任務(wù)優(yōu)先級(jí)反轉(zhuǎn)現(xiàn)象的,下面就對(duì)優(yōu)先級(jí)的反轉(zhuǎn)現(xiàn)象做一個(gè)詳細(xì)的分析,以期找出原因及解決方法。 圖4-15描述了A、B、C三個(gè)任務(wù)的運(yùn)行情況。其中,任務(wù)A的優(yōu)先級(jí)別高于任務(wù)B,任務(wù)B的優(yōu)先級(jí)別高于任務(wù)C。任務(wù)A和任務(wù)C都要使用同一個(gè)共享資源S,而

11、用于保護(hù)該資源的信號(hào)量在同一時(shí)間只能允許一個(gè)任務(wù)以獨(dú)占的方式對(duì)該資源進(jìn)行訪問(wèn),即這個(gè)信號(hào)量是一個(gè)互斥型信號(hào)量。 通過(guò)例子可以發(fā)現(xiàn),使用信號(hào)量的任務(wù)是否能夠運(yùn)行是受任務(wù)的優(yōu)先級(jí)別和是否占用信號(hào)量?jī)蓚€(gè)條件約束的,而信號(hào)量的約束高于優(yōu)先級(jí)別的約束。于是當(dāng)出現(xiàn)低優(yōu)先級(jí)別的任務(wù)與高優(yōu)先級(jí)別的任務(wù)使用同一個(gè)信號(hào)量,而系統(tǒng)中還存有別的中等優(yōu)先級(jí)別的任務(wù)時(shí),如果低優(yōu)先級(jí)別的任務(wù)先獲得了信號(hào)量,就會(huì)使高級(jí)別的任務(wù)處于等待狀態(tài),而那些不使用該信號(hào)量的中等級(jí)別的任務(wù)卻可以剝奪低優(yōu)先級(jí)別的任務(wù)的CPU使用權(quán)而先于高優(yōu)先級(jí)別的任務(wù)而運(yùn)行了。 解決問(wèn)題的辦法之一,是使獲得信號(hào)量任務(wù)的優(yōu)先級(jí)別在使用共享資源期間暫時(shí)提升到所

12、有任務(wù)最高優(yōu)先級(jí)的高一個(gè)級(jí)別上,以使該任務(wù)不被其他的任務(wù)所打斷,從而能盡快地使用完共享資源并釋放信號(hào)量,然后在釋放了信號(hào)量之后再恢復(fù)該任務(wù)原來(lái)的優(yōu)先級(jí)別。 互斥型信號(hào)量 在描述互斥型信號(hào)量的事件控制塊中,除了成員OSEventType要賦以常數(shù)OS_EVENT_TYPE_MUTEX以表明這是一個(gè)互斥型信號(hào)量和仍然沒(méi)有使用成員OSEventPtr之外,成員OSEventCnt被分成了低位和高位兩部分:低位用來(lái)存放信號(hào)值(該值為0 xFF時(shí),信號(hào)為有效,否則信號(hào)為無(wú)效),高位用來(lái)存放為了避免出現(xiàn)優(yōu)先級(jí)反轉(zhuǎn)現(xiàn)象而要提升的優(yōu)先級(jí)別prio。 創(chuàng)建互斥型信號(hào)量需要調(diào)用函數(shù)OSMutexCreate( )

13、。函數(shù)OSMutexCreate( )的原型如下: OS_EVENT *OSMutexCreate (INT8U prio,/優(yōu)先級(jí)別INT8U *err/錯(cuò)誤信息); 函數(shù)OSMutexCreate( )從空事件控制塊鏈表獲取一個(gè)事件控制塊,把成員OSEventType賦以常數(shù)OS_EVENT_TYPE_MUTEX以表明這是一個(gè)互斥型信號(hào)量,然后再把成員OSEventCnt的高8位賦以prio(欲提升的優(yōu)先級(jí)別),低8位賦以常數(shù)OS_MUTEX_AVAILABLE(該常數(shù)值為0 xFFFF)的低8位(0 xFF)以表明信號(hào)量尚未被任何任務(wù)所占用,處于有效狀態(tài)。 當(dāng)任務(wù)需要訪問(wèn)一個(gè)獨(dú)占式共享資

14、源時(shí),就要調(diào)用函數(shù)OSMutexPend( )來(lái)請(qǐng)求管理這個(gè)資源的互斥型信號(hào)量,如果信號(hào)量有信號(hào)(OSEventCnt的低8位為0 xFF),則意味著目前尚無(wú)任務(wù)占用資源,于是任務(wù)可以繼續(xù)運(yùn)行并對(duì)該資源進(jìn)行訪問(wèn),否則就進(jìn)入等待狀態(tài),直至占用這個(gè)資源的其他任務(wù)釋放了該信號(hào)量。 函數(shù)OSMutexPend( )的原型為: void OSMutexPend (OS_EVENT *pevent, /互斥型信號(hào)量指針I(yè)NT16U timeout, /等待時(shí)限INT8U *err/錯(cuò)誤信息); 任務(wù)可以通過(guò)調(diào)用函數(shù)OSMutexPost( )發(fā)送一個(gè)互斥型信號(hào)量,這個(gè)函數(shù)的原型為: INT8U OSMut

15、exPost (OS_EVENT *pevent /互斥型信號(hào)量指針); 消息郵箱及其操作如果把數(shù)據(jù)緩沖區(qū)的指針賦給一個(gè)事件控制塊的成員OSEventPrt,同時(shí)使事件控制塊的成員OSEventType為常數(shù)OS_EVENT_TYPE_MBOX,則該事件控制塊就叫做消息郵箱,消息郵箱是在兩個(gè)需要通信的任務(wù)之間通過(guò)傳遞數(shù)據(jù)緩沖區(qū)指針的方法來(lái)通信的。 創(chuàng)建郵箱需要調(diào)用函數(shù)OSMboxCreate ( ),這個(gè)函數(shù)的原型為: OS_EVENT *OSMboxCreate (void *msg/消息指針); 函數(shù)中的參數(shù)msg為消息的指針,函數(shù)的返回值為消息郵箱的指針。調(diào)用函數(shù)OSMboxCreate

16、 ( )需先定義msg的初始值。在一般的情況下,這個(gè)初始值為NULL;但也可以事先定義一個(gè)郵箱,然后把這個(gè)郵箱的指針作為參數(shù)傳遞到函數(shù)OSMboxCreate ( )中,使之一開(kāi)始就指向一個(gè)郵箱。 任務(wù)可以通過(guò)調(diào)用函數(shù)OSMboxPost ( )向消息郵箱發(fā)送消息,這個(gè)函數(shù)的原型為: INT8U OSMboxPost (OS_EVENT *pevent, /消息郵箱指針void *msg/消息指針);當(dāng)一個(gè)任務(wù)請(qǐng)求郵箱時(shí)需要調(diào)用函數(shù)OSMboxPend( ),這個(gè)函數(shù)的主要作用就是查看郵箱指針OSEventPtr是否為NULL,如果不是NULL就把郵箱中的消息指針?lè)祷亟o調(diào)用函數(shù)的任務(wù),同時(shí)用O

17、S_NO_ERR通過(guò)函數(shù)的參數(shù)err通知任務(wù)獲取消息成功;如果郵箱指針OSEventPtr是NULL,則使任務(wù)進(jìn)入等待狀態(tài),并引發(fā)一次任務(wù)調(diào)度。函數(shù)OSMboxPend( )的原型為: void *OSMboxPend (OS_EVENT *pevent, /請(qǐng)求消息郵箱指針I(yè)NT16U timeout, /等待時(shí)限INT8U *err/錯(cuò)誤信息); 消息隊(duì)列及其操作使用消息隊(duì)列可以在任務(wù)之間傳遞多條消息。消息隊(duì)列由三個(gè)部分組成:事件控制塊、消息隊(duì)列和消息。當(dāng)把事件控制塊成員OSEventType的值置為OS_EVENT_TYPE_Q時(shí),該事件控制塊描述的就是一個(gè)消息隊(duì)列。消息隊(duì)列的數(shù)據(jù)結(jié)構(gòu)如

18、圖4-21所示。從圖中可以看到,消息隊(duì)列相當(dāng)于一個(gè)共用一個(gè)任務(wù)等待列表的消息郵箱數(shù)組,事件控制塊成員OSEventPtr指向了一個(gè)叫做隊(duì)列控制塊(OS_Q)的結(jié)構(gòu),該結(jié)構(gòu)管理了一個(gè)數(shù)組MsgTbl ,該數(shù)組中的元素都是一些指向消息的指針。 其中,可以移動(dòng)的指針為OSQIn和OSQOut,而指針OSQStart和OSQEnd只是一個(gè)標(biāo)志(常指針)。當(dāng)可移動(dòng)的指針OSQIn或OSQOut移動(dòng)到數(shù)組末尾,也就是與OSQEnd相等時(shí),可移動(dòng)的指針將會(huì)被調(diào)整到數(shù)組的起始位置OSQStart。也就是說(shuō),從效果上來(lái)看,指針OSQEnd與OSQStart等值。于是,這個(gè)由消息指針構(gòu)成的數(shù)組就頭尾銜接起來(lái)形成了

19、一個(gè)如圖所示的循環(huán)的隊(duì)列。 為了對(duì)圖所示的消息指針數(shù)組進(jìn)行有效的管理,C/OS-II把消息指針數(shù)組的基本參數(shù)都記錄在一個(gè)叫做隊(duì)列控制塊的結(jié)構(gòu)中,隊(duì)列控制塊的結(jié)構(gòu)如下: typedef struct os_q struct os_q *OSQPtr; void *OSQStart; void *OSQEnd; void *OSQIn; void *OSQOut; INT16U OSQSize; INT16U OSQEntries; OS_Q;在C/OS-II初始化時(shí),系統(tǒng)將按文件OS_CFG.H中的配置常數(shù)OS_MAX_QS定義OS_MAX_QS個(gè)隊(duì)列控制塊,并用隊(duì)列控制塊中的指針OSQPtr將

20、所有隊(duì)列控制塊鏈接為鏈表。由于這時(shí)還沒(méi)有使用它們,故這個(gè)鏈表叫做空隊(duì)列控制塊鏈表 創(chuàng)建一個(gè)消息隊(duì)列首先需要定義一指針數(shù)組,然后把各個(gè)消息數(shù)據(jù)緩沖區(qū)的首地址存入這個(gè)數(shù)組中,然后再調(diào)用函數(shù)OSQCreate( )來(lái)創(chuàng)建消息隊(duì)列。創(chuàng)建消息隊(duì)列函數(shù)OSQCreate( )的原型為: OS_EVENT OSQCreate(void*start,/指針數(shù)組的地址INT16U size/數(shù)組長(zhǎng)度); 請(qǐng)求消息隊(duì)列的目的是為了從消息隊(duì)列中獲取消息。任務(wù)請(qǐng)求消息隊(duì)列需要調(diào)用函數(shù)OSQPend( ),該函數(shù)的原型為: void*OSQPend(OS_EVENT*pevent, /所請(qǐng)求的消息隊(duì)列的指針I(yè)NT16U

21、 timeout,/等待時(shí)限INT8U*err/錯(cuò)誤信息);任務(wù)需要通過(guò)調(diào)用函數(shù)OSQPost( )或OSQPostFront( )來(lái)向消息隊(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 OSQPost(OS_EVENT*pevent, /消息隊(duì)列的指針void*msg/消息指針); 函數(shù)中的參數(shù)msg為待發(fā)消息的指針。 信號(hào)量集在實(shí)際應(yīng)

22、用中,任務(wù)常常需要與多個(gè)事件同步,即要根據(jù)多個(gè)信號(hào)量組合作用的結(jié)果來(lái)決定任務(wù)的運(yùn)行方式。C/OS-II為了實(shí)現(xiàn)多個(gè)信號(hào)量組合的功能定義了一種特殊的數(shù)據(jù)結(jié)構(gòu)信號(hào)量集。信號(hào)量集所能管理的信號(hào)量都是一些二值信號(hào),所有信號(hào)量集實(shí)質(zhì)上是一種可以對(duì)多個(gè)輸入的邏輯信號(hào)進(jìn)行基本邏輯運(yùn)算的組合邏輯,其示意圖如圖5-1所示 信號(hào)量集的標(biāo)志組不同于信號(hào)量、消息郵箱、消息隊(duì)列等事件,C/OS-II不使用事件控制塊來(lái)描述信號(hào)量集,而使用了一個(gè)叫做標(biāo)志組的結(jié)構(gòu)OS_FLAG_GRP。OS_FLAG_GRP結(jié)構(gòu)如下: typedef structINT8U OSFlagType; /識(shí)別是否為信號(hào)量集的標(biāo)志void*OSF

23、lagWaitList;/指向等待任務(wù)鏈表的指針OS_FLAGSOSFlagFlags; /所有信號(hào)列表OS_FLAG_GRP;成員OSFlagWaitList是一個(gè)指針,當(dāng)一個(gè)信號(hào)量集被創(chuàng)建后,這個(gè)指針指向了這個(gè)信號(hào)量集的等待任務(wù)鏈表。 等待任務(wù)鏈表 與其他前面介紹過(guò)的事件不同,信號(hào)量集用一個(gè)雙向鏈表來(lái)組織等待任務(wù),每一個(gè)等待任務(wù)都是該鏈表中的一個(gè)節(jié)點(diǎn)(Node)。標(biāo)志組OS_FLAG_GRP的成員OSFlagWaitList就指向了信號(hào)量集的這個(gè)等待任務(wù)鏈表。等待任務(wù)鏈表節(jié)點(diǎn)OS_FLAG_NODE的結(jié)構(gòu)如下: typedef struct void *OSFlagNodeNext; /指

24、向下一個(gè)節(jié)點(diǎn)的指針 void *OSFlagNodePrev; /指向前一個(gè)節(jié)點(diǎn)的指針 void *OSFlagNodeTCB; /指向?qū)?yīng)任務(wù)控制塊的指針 void *OSFlagNodeFlagGrp; /反向指向信號(hào)量集的指針 OS_FLAGS OSFlagNodeFlags; /信號(hào)過(guò)濾器 INT8U OSFlagNodeWaitType;/定義邏輯運(yùn)算關(guān)系的數(shù)據(jù) OS_FLAG_NODE;給等待任務(wù)鏈表添加節(jié)點(diǎn)的函數(shù)為OS_FlagBlock( ),這個(gè)函數(shù)的原型為: static void OS_FlagBlock (OS_FLAG_GRP *pgrp, /信號(hào)量集指針OS_FLA

25、G_NODE *pnode, /待添加的等待任務(wù)節(jié)點(diǎn)指針OS_FLAGS flags, /指定等待信號(hào)的數(shù)據(jù)INT8U wait_type, /信號(hào)與等待任務(wù)之間的邏輯INT16U timeout/等待時(shí)限); 這個(gè)函數(shù)將在請(qǐng)求信號(hào)量集函數(shù)OSFlagPend ( )中被調(diào)用。 從 等 待 任 務(wù) 鏈 表 中 刪 除 一 個(gè) 節(jié) 點(diǎn) 的 函 數(shù) 為OS_FlagUnlink( ),這個(gè)函數(shù)的原型為: void OS_FlagUnlink (OS_FLAG_NODE *pnode); 這個(gè)函數(shù)將在發(fā)送信號(hào)量集函數(shù)OSFlagPost( )中被調(diào)用。 信號(hào)量集的操作任務(wù)可以通過(guò)調(diào)用函數(shù)OSFlag

26、Create ( )來(lái)創(chuàng)建一個(gè)信號(hào)量集。OSFlagCreate ( )的函數(shù)原型為: OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags,/信號(hào)的初始值INT8U *err/錯(cuò)誤信息); 任務(wù)可以通過(guò)調(diào)用函數(shù)OSFlagPend( )請(qǐng)求一個(gè)信號(hào)量集,OSFlagPend( )函數(shù)的原型為: OS_FLAGS OSFlagPend (OS_FLAG_GRP *pgrp, /所請(qǐng)求的信號(hào)量集指針OS_FLAGS flags, /濾波器INT8U wait_type, /邏輯運(yùn)算類型INT16U timeout, /等待時(shí)限INT8U *err/錯(cuò)誤信息); 任務(wù)

27、可以通過(guò)調(diào)用函數(shù)OSFlagPost ( )向信號(hào)量集發(fā)信號(hào),OSFlagPost ( )函數(shù)的原型為: OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, /信號(hào)量集指針OS_FLAGS flags, /選擇所要發(fā)送的信號(hào)INT8U opt, /信號(hào)有效的選項(xiàng)INT8U *err/錯(cuò)誤信息); 所謂任務(wù)向信號(hào)量集發(fā)信號(hào),就是對(duì)信號(hào)量集標(biāo)志組中的信號(hào)進(jìn)行置“1”(置位)或置“0”(復(fù)位)的操作。至于對(duì)信號(hào)量集中的哪些信號(hào)進(jìn)行操作,用函數(shù)中的參數(shù)flags來(lái)指定;對(duì)指定的信號(hào)是置“1”還是置“0”,用函數(shù)中的參數(shù)opt來(lái)指定(opt = OS_FLAG_SET為置“1

28、”操作;opt = OS_FLAG_CLR為置“0”操作)。 第6章 內(nèi)存的動(dòng)態(tài)分配應(yīng)用程序在運(yùn)行中為了某種特殊需要,經(jīng)常需要臨時(shí)獲得一些內(nèi)存空間,因此作為一個(gè)比較完善的操作系統(tǒng)必須具有動(dòng)態(tài)分配內(nèi)存的能力。能否合理、有效地對(duì)內(nèi)存儲(chǔ)器進(jìn)行分配和管理,是衡量一個(gè)操作系統(tǒng)品質(zhì)的指標(biāo)之一。特別地對(duì)于實(shí)時(shí)操作系統(tǒng)來(lái)說(shuō),還應(yīng)該保證系統(tǒng)在動(dòng)態(tài)分配內(nèi)存時(shí),它的執(zhí)行時(shí)間必須是可確定的。C/OS-II改進(jìn)了ANSI C用來(lái)動(dòng)態(tài)分配和釋放內(nèi)存的malloc( )和free( )函數(shù),使它們可以對(duì)大小固定的內(nèi)存塊進(jìn)行操作,從而使 malloc( )和free( )函數(shù)的執(zhí)行時(shí)間成為可確定的,滿足了實(shí)時(shí)操作系統(tǒng)的要求。

29、 內(nèi)存控制塊C/OS-II對(duì)內(nèi)存進(jìn)行兩級(jí)管理,即把一個(gè)大片連續(xù)的內(nèi)存空間分成了若干個(gè)分區(qū),每個(gè)分區(qū)又分成了若干個(gè)大小相等的內(nèi)存塊來(lái)進(jìn)行管理。操作系統(tǒng)以分區(qū)為單位來(lái)管理動(dòng)態(tài)內(nèi)存,而任務(wù)以內(nèi)存塊為單位來(lái)獲得和釋放動(dòng)態(tài)內(nèi)存。內(nèi)存分區(qū)及內(nèi)存塊的使用情況則由表內(nèi)存控制塊來(lái)記錄。本節(jié)首先介紹內(nèi)存分區(qū)和分區(qū)中的內(nèi)存塊,然后再介紹內(nèi)存控制塊。 可動(dòng)態(tài)分配內(nèi)存的劃分 應(yīng)用程序如果要使用動(dòng)態(tài)內(nèi)存的話,則要首先在內(nèi)存中劃分出可以進(jìn)行動(dòng)態(tài)分配的區(qū)域,這個(gè)劃分出來(lái)區(qū)域叫做內(nèi)存分區(qū),每個(gè)分區(qū)要包含若干個(gè)內(nèi)存塊。C/OS-II要求同一個(gè)分區(qū)中的內(nèi)存塊的字節(jié)數(shù)必須相等,而且每個(gè)分區(qū)與該分區(qū)的內(nèi)存塊的數(shù)據(jù)類型必須相同。在內(nèi)存中

30、劃分一個(gè)內(nèi)存分區(qū)與內(nèi)存塊的方法非常簡(jiǎn)單,只要定義一個(gè)二維數(shù)組就可以了,其中的每個(gè)一維數(shù)組就是一個(gè)內(nèi)存塊。例如,定義一個(gè)用來(lái)存儲(chǔ)INT16U類型數(shù)據(jù),有10個(gè)內(nèi)存塊,每個(gè)內(nèi)存塊長(zhǎng)度為10的內(nèi)存分區(qū)的代碼如下: INT16U IntMemBuf1010; 需要注意的是,上面這個(gè)定義只是在內(nèi)存中劃分出了分區(qū)及內(nèi)存塊的區(qū)域,還不是一個(gè)真正的可以動(dòng)態(tài)分配的內(nèi)存區(qū),如圖6-1(a)所示。只有當(dāng)把內(nèi)存控制塊與分區(qū)關(guān)聯(lián)起來(lái)之后,系統(tǒng)才能對(duì)其進(jìn)行相應(yīng)的管理和控制,它才能是一個(gè)真正的動(dòng)態(tài)內(nèi)存區(qū) 為了使系統(tǒng)能夠感知和有效地管理內(nèi)存分區(qū),C/OS-II給每個(gè)內(nèi)存分區(qū)定義了一個(gè)叫做內(nèi)存控制塊(OS_MEM)的數(shù)據(jù)結(jié)構(gòu)。系統(tǒng)就用這個(gè)內(nèi)存控制塊來(lái)記錄和跟蹤每一個(gè)內(nèi)存分區(qū)的狀態(tài)。內(nèi)存控制塊的結(jié)構(gòu)如下: typedef struct void *OSMemAddr;/內(nèi)存分區(qū)的指針 void *OSMemF

溫馨提示

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

評(píng)論

0/150

提交評(píng)論