《嵌入式操作系統(tǒng)教程-第九章》由會員分享,可在線閱讀,更多相關(guān)《嵌入式操作系統(tǒng)教程-第九章(38頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、第一章 操作系統(tǒng)的基本概念,*,*,*,嵌入式操作系統(tǒng)基礎(chǔ) 第九章 任務(wù)的同步與通信,第九章 任務(wù)的同步與通信,任務(wù)間的同步和事件控制塊,信號量及其操作,任務(wù)優(yōu)先級反轉(zhuǎn)和互斥型信號量,消息郵箱及其操作,消息隊列及其操作,1,第九章 任務(wù)的同步與通信,一、任務(wù)間的同步,鑒于任務(wù)間直接制約或間接制約性的關(guān)系,這種制約性的合作運行機(jī)制叫做任務(wù)的,同步,。,二、事件,用于,uC,/OS-II,任務(wù)間通信媒介的,信號量,、,郵箱,和,消息隊列,等數(shù)據(jù)結(jié)構(gòu)會影響到任務(wù)的程序流程,這些通信媒介又被稱為事件(,Events,)。,9.1,任務(wù)間的同步和事件控制塊,2,1.,信號量,互斥型信號量:,通常表現(xiàn)為一
2、個二值型信號,用一位二進(jìn)制位來表示(,1/0,),可以實現(xiàn)共享資源的獨占式占用。,信號量:,通常表現(xiàn)為一個遞減的計數(shù)器信號,可以實現(xiàn)若干個同類資源的共享,提高資源使用效率。,3,2.,消息郵箱,指向保存任務(wù)間傳遞信息的存儲空間,(,緩存區(qū),),的指針結(jié)構(gòu)稱為,消息郵箱,。,4,3.,消息隊列,若消息郵箱被定義成擁有若干個元素的數(shù)組,用來傳遞多個消息的地址指針,這樣消息的數(shù)據(jù)結(jié)構(gòu)稱為,消息隊列,。,4.,事件的等待任務(wù)隊列,兩個功能:,對等待事件的所有記錄進(jìn)行登記并排序,允許任務(wù)有一定的等待時間,5,6,三,、事件控制塊,事件控制塊的結(jié)構(gòu),OSEventPtr,指針,只有在所定義的事件是郵箱或者
3、消息隊列時才使用。當(dāng)所定義的事件是郵箱時,它指向一個消息,而當(dāng)所定義的事件是消息隊列時,它指向一個數(shù)據(jù)結(jié)構(gòu)。,typedef,struct,void *,OSEventPtr,;/*,指向消息或者消息隊列的指針*,/,INT8U,OSEventTblOS_EVENT_TBL_SIZE,;/*,等待任務(wù)列表 *,/,INT16U,OSEventCnt,;/*,計數(shù)器,(,當(dāng)事件是信號量時,)*/,INT8U,OSEventType,;/*,事件類型 *,/,INT8U,OSEventGrp,;/*,等待任務(wù)所在的組 *,/,OS_EVENT;,7,.,OSEventTbl,/,.,OSEvent
4、Grp,與前面提過的,OSRdyTbl,和,OSRdyGrp,非常相像,,只不過前兩者包含的是等待某事件的任務(wù),而后兩者包含的是系統(tǒng)中處于就緒狀態(tài)的任務(wù)。,.,OSEventCnt,:,當(dāng)事件是一個信號量時,,.,OSEventCnt,是用于信號量的計數(shù)器。,.,OSEventType,:,定義了事件的具體類型。它可以是信號量,(,OS_EVENT_SEM,),、郵箱,(,OS_EVENT_TYPE_MBOX,),或消息隊列,(,OS_EVENT_TYPE_Q,),中的一種。用戶要根據(jù)該域的具體值來調(diào)用相應(yīng)的系統(tǒng)函數(shù),以保證對其進(jìn)行的操作的正確性。,8,四,、事件控制塊,的基本操作函數(shù),1.,
5、事件控制塊的初始話函數(shù),函數(shù)作用:,把變量,OSEventGrp,及任務(wù)等待表中的每一位都清,0,,即令事件的任務(wù)等代表中不含有任何等待任務(wù)。,void,OSEventWaitListInit,(OS_EVENT*,pevent,),INT8U i;,pevent,-,OSEventGrp,=0 x00;,for(i=0;i,OSEventTbli,=0 x00;,9,2.,使一個任務(wù)進(jìn)入等待狀態(tài)的函數(shù),當(dāng)一個任務(wù)在請求一個事件而不能獲得時,應(yīng)把次任務(wù)登記在時間的等待任務(wù)列表中,并把任務(wù)控制塊中的任務(wù)狀態(tài)置為等待狀態(tài)和吧任務(wù)置為非就緒任務(wù),void,OSEventTaskWait,(OS_EV
6、ENT*,pevent,),OSTCBCur,-,OSTCBEventPtr,=,pevent,;(1),if(,OSRdyTblOSTCBCur,-OSTCBY&=,OSTCBCur,-,OSTCBBitX,)=0)(2),OSRdyGrp,&=,OSTCBCur,-,OSTCBBitY,;,pevent,-,OSEventTblOSTCBCur,-OSTCBY|=,OSTCBCur,-,OSTCBBitX,;(3),pevent,-,OSEventGrp,|=,OSTCBCur,-,OSTCBBitY,;,10,3.,正在等待的任務(wù)進(jìn)入就緒狀態(tài),當(dāng)一個正在等待的任務(wù)具備了可以運行的條件,這
7、時需調(diào)用此函數(shù)來使它進(jìn)入就緒狀態(tài)。該函數(shù)的作用就是把調(diào)用這個函數(shù)的任務(wù)在任務(wù)等待表中的位置清,O,后,再把任務(wù)子啊任務(wù)就緒表中的對應(yīng)位置,1,,然后引起一次任務(wù)調(diào)度。,void,OSEventTaskRdy,(OS_EVENT*,pevent,void*,msg,INT8U,msk,),OS_TCB*,ptcb,;,INT8U x;,INT8U y;,INT8U,bitx,;,INT8U,bity,;,INT8U,prio,;,11,4.,等待超時的任務(wù)轉(zhuǎn)為就緒態(tài),正在等待事件的任務(wù)在預(yù)先指定的時間內(nèi)仍然沒有獲取事件,這時需調(diào)用此函數(shù)來轉(zhuǎn)換的它的狀態(tài)。,void,OSEventTO,(OS_E
8、VENT*,pevent,),if(,pevent,-,OSEventTblOSTCBCur,-OSTCBY&=,OSTCBCur,-,OSTCBBitX,)=0)(1),pevent,-,OSEventGrp,&=,OSTCBCur,-,OSTCBBitY,;,OSTCBCur,-,OSTCBStat,=OS_STAT_RDY;(2),OSTCBCur,-,OSTCBEventPtr,=(OS_EVENT*)0;(3),12,五,、空事件控制塊,的的組織,和任務(wù)控制塊的組織結(jié)構(gòu)類似:所有的事件控制塊也被組織成兩個鏈表,當(dāng)系統(tǒng)初始化時,通過控制塊指針,OSEventPtr,把所有的空時間控制塊
9、鏈接成一個空事件控制塊鏈表。,13,9.1,信號量及其操作,一,、信號量,由,16,位的無符號整數(shù)(,0,到,65,535,之間)構(gòu)成的信號量計數(shù)器和任務(wù)等待表兩部分組成。計數(shù)器決定共享資源的任務(wù)數(shù)。,14,二、信號量的操作,1.,信號量的創(chuàng)建,:,信號量一旦,建立就不能刪,除了,因此也,就不可能將一,個已分配的任,務(wù)控制塊再放,回到空閑,ECB,鏈表中。,OS_EVENT*,OSSemCreate,(INT16U,cnt,),OS_EVENT*,pevent,;,OS_ENTER_CRITICAL();,pevent,=,OSEventFreeList,;(1),if(,OSEventFre
10、eList,!=(OS_EVENT*)0)(2),OSEventFreeList,=(OS_EVENT*),OSEventFreeList,-,OSEventPtr,;,OS_EXIT_CRITICAL();,if(,pevent,!=(OS_EVENT*)0)(3),pevent,-,OSEventType,=OS_EVENT_TYPE_SEM;(4),pevent,-,OSEventCnt,=,cnt,;(5),OSEventWaitListInit(pevent,);(6),return(,pevent,);(7),信號量創(chuàng)建,15,2.,等待一個信號量,OSSemPend()/OSSe
11、mAccept,(),void OSSemPend(OS_EVENT*pevent,/信號量指針,INT16U timeout,/等待時限,INT8U*err);/錯誤信息,INT16U OSSEMAccept(,OS_EVENT*PEVENT/信號量指針,),3.,發(fā)送一個信號量,OSSemPost,(),任務(wù)獲得信號量,并在訪問共享資源結(jié)束以后,必須釋放信號量,此過程需調(diào)用函數(shù),OSSemPost,(),完成。,16,INT8U,OSSemPost,(OS_EVENT*,pevent,),OS_ENTER_CRITICAL();,if(,pevent,-,OSEventType,!=OS_
12、EVENT_TYPE_SEM)(1),OS_EXIT_CRITICAL();,return(OS_ERR_EVENT_TYPE);,if(,pevent,-,OSEventGrp,)(2),OSEventTaskRdy(pevent,(void*)0,OS_STAT_SEM);(3),OS_EXIT_CRITICAL();,OSSched,();(4),return(OS_NO_ERR);,else,if(,pevent,-,OSEventCnt,OSEventCnt,+;(5),OS_EXIT_CRITICAL();,return(OS_NO_ERR);,else,OS_EXIT_CRITI
13、CAL();,return(OS_SEM_OVF);,17,3.,發(fā)送一個信號量,OSSemPost,(),OS_EVENT*,OSSemDel,(,OS_EVENT*,pevent,INT8U opt,INT8U*err,);,3.,信號量狀態(tài)查詢,OSSemQuery,(),INT8U,OSSemQuery,(,OS_EVENT*,pevent,OS_SEM_DATA*,pdata,);,Typedef,struct,INT16U,OSCnt,;,INTU8U OSEventb1OS_EVENT_SIZE;,INT8U,OSEventGrp,;,OS_SEM_DATA;,18,9.3,任務(wù)
14、優(yōu)先級反轉(zhuǎn)和互斥型信號量,一、任務(wù)優(yōu)先級的反轉(zhuǎn)現(xiàn)象,在可剝奪型內(nèi)核中,當(dāng)任務(wù)以獨占方式使用共享資源時,會出現(xiàn)低優(yōu)先級任務(wù)先于高優(yōu)先級任務(wù)而被運行的現(xiàn)象,這種現(xiàn)象就成為任務(wù)優(yōu)先級反轉(zhuǎn)。,19,void,TaskA(void,),SetTaskPriority(RES_X_PRIO,);,/,訪問共享資源,X,SetTaskPriority(TASK_A_PRIO,);,形成原因:,使用信號量的任務(wù)是否能夠運行時受任務(wù)的優(yōu)先級別以及是否占用信號量兩個條件約束的,而信號量的約束高于優(yōu)先級別的約束。,解決方案:,一旦獲取信號量的任務(wù)投入運行,其將暫用最高優(yōu)先級別,直至任務(wù)執(zhí)行完成。,20,二、,互斥型
15、信號量,實現(xiàn)對共享資源的獨占式處理。,解決任務(wù)的優(yōu)先級反轉(zhuǎn):變量,OSEventPtr,占,16,位,低,8,位作為信號量有效性的判斷位;高,8,位則存放任務(wù)運行后臨時暫用的優(yōu)先級別。,21,1.,互斥型信號量的創(chuàng)建,OS_EVENT*,OSMutexCreate,(,INT8U,prio,INT8U*err,);,2.,請求互斥型信號量:,OSMutexPend()/OSMutexAccept,(),OS_EVENT*,OSMutexPend,(,OS_EVENT*,pevent,INT16U Timeout,INT8U*err,);,22,3.,發(fā)送互斥型信號量,INT8U,OSMutex
16、Query,(,OS_EVENT*,pevent,);,4.,查詢互斥型信號量的當(dāng)前狀態(tài),OS_EVENT*,OSMutexPend,(,OS_EVENT*,pevent,OS_MUTEX_DATA*,pdata,);,Typedef,struct,INT8U,OSValue,;,INTU8U OSEvenTb1OS_EVENT_SIZE;,INT8U,OSEventGrp,;,INT8U,OSOwnerPrio,;,INT8U,OSMutexPIP,;,OS_MUTEX_DATA;,23,5.,刪除,互斥型信號量,OS_EVENT*,OSMutexPend,(,OS_EVENT*,pevent,INT8U opt,INT8U*err,);,24,9.4,消息郵箱及其操作,一、,消息郵箱,任務(wù)與任務(wù)間要傳遞一個數(shù)據(jù),為了適應(yīng)不同數(shù)據(jù)的需要,最好在存儲中建立一個數(shù)據(jù)緩沖區(qū),把要傳遞的數(shù)據(jù)放在該緩沖區(qū)中,從而實現(xiàn)任務(wù)間的數(shù)據(jù)通信。,25,二、,消息郵箱的操作,OS_EVENT*,OSMboxCreate,(void*,msg,),OS_EVENT*,pevent,;,OS_ENTER_CR