




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第10講 同步互斥與通信,授課教師: 電郵地址:,2020/7/30,2,主要內(nèi)容,信號(hào)量 郵箱和消息隊(duì)列 事件 異步信號(hào)*,2020/7/30,3,概述,多任務(wù)系統(tǒng)中任務(wù)之間的關(guān)系 相互獨(dú)立 僅競(jìng)爭(zhēng)CPU資源 競(jìng)爭(zhēng)除CPU外的其他資源(互斥) 同步 協(xié)調(diào)彼此運(yùn)行的步調(diào) 通信 彼此間傳遞數(shù)據(jù)或信息,以協(xié)同完成某項(xiàng)工作,2020/7/30,4,任務(wù)能以以下方式與中斷處理程序或其他任務(wù)進(jìn)行同步或通信: 單向同步或通信:一個(gè)任務(wù)與另一個(gè)任務(wù)或一個(gè)ISR同步或通信。 雙向同步或通信:兩個(gè)任務(wù)相互同步或通信。雙向同步不能在任務(wù)與ISR之間進(jìn)行,因?yàn)镮SR不能等待。,概述,2020/7/30,5,任務(wù)與任
2、務(wù)之間的同步(單向),任務(wù)與ISR之間的同步(單向),任務(wù)與任務(wù)之間的同步(雙向),2020/7/30,6,在嵌入式多任務(wù)系統(tǒng)中,任務(wù)間的耦合程度是不一樣的: 耦合程度較高:任務(wù)之間需要進(jìn)行大量的通信,相應(yīng)的系統(tǒng)開(kāi)銷(xiāo)較大; 耦合程度較低:任務(wù)之間不存在通信需求,其間的同步關(guān)系很弱甚至不需要同步或互斥,系統(tǒng)開(kāi)銷(xiāo)較小。 研究任務(wù)間耦合程度的高低對(duì)于合理地設(shè)計(jì)應(yīng)用系統(tǒng)、劃分任務(wù)有很重要的作用。,概述,2020/7/30,7,在單處理器平臺(tái)上,嵌入式操作系統(tǒng)內(nèi)核提供的同步、互斥與通信機(jī)制主要包括: 信號(hào)量(semaphore),用于互斥與同步 事件(組)(event group),用于同步 異步信號(hào)(
3、asynchronous signal),用于同步 郵箱(mailbox)、消息隊(duì)列(message queue)或管道(pipe),用于消息通信,概述,2020/7/30,8,以下一些機(jī)制也可用于同步與通信(在單處理器或多處理器系統(tǒng)中): 全局變量 共享內(nèi)存 Sockets 遠(yuǎn)程過(guò)程調(diào)用(Remote Procedure Call),概述,2020/7/30,9,1.信號(hào)量,信號(hào)量的種類(lèi)及用途 互斥信號(hào)量 二值信號(hào)量 計(jì)數(shù)信號(hào)量 信號(hào)量機(jī)制的主要數(shù)據(jù)結(jié)構(gòu) 信號(hào)量的主要功能,2020/7/30,10,信號(hào)量用于實(shí)現(xiàn)任務(wù)與任務(wù)之間、任務(wù)與中斷處理程序之間的同步與互斥。 信號(hào)量一般分為三種: 用于
4、解決互斥問(wèn)題的互斥信號(hào)量。它比較特殊,可能會(huì)引起優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題。 用于解決同步問(wèn)題的二值信號(hào)量。 用于解決資源計(jì)數(shù)問(wèn)題的計(jì)數(shù)信號(hào)量。 將信號(hào)量進(jìn)行種類(lèi)細(xì)分,可以根據(jù)其用途,在具體實(shí)現(xiàn)時(shí)做專(zhuān)門(mén)處理,提高執(zhí)行效率和可靠性。,信號(hào)量的種類(lèi)及用途,2020/7/30,11,用互斥信號(hào)量保護(hù)的代碼區(qū)稱(chēng)作“臨界區(qū)”,臨界區(qū)代碼通常用于對(duì)共享資源的訪問(wèn)。 互斥信號(hào)量的值被初始化成1,表明目前沒(méi)有任務(wù)進(jìn)入“臨界區(qū)”,但最多只有一個(gè)任務(wù)可以進(jìn)入“臨界區(qū)”。 第一個(gè)試圖進(jìn)入“臨界區(qū)”的任務(wù)將成功獲得互斥信號(hào)量,而隨后試圖進(jìn)入用同一信號(hào)量保護(hù)的臨界區(qū)的所有其他任務(wù)就必須等待。 當(dāng)任務(wù)離開(kāi)“臨界區(qū)”時(shí),它將釋放信號(hào)量
5、并允許正在等待該信號(hào)量的任務(wù)進(jìn)入“臨界區(qū)”。,互斥信號(hào)量,2020/7/30,12,各種互斥機(jī)制比較,2020/7/30,13,二值信號(hào)量,二值信號(hào)量主要用于任務(wù)與任務(wù)之間、任務(wù)與中斷服務(wù)程序之間的同步 用于同步的二值信號(hào)量初始值為0,表示同步事件尚未產(chǎn)生; 任務(wù)申請(qǐng)信號(hào)量以等待該同步事件的發(fā)生; 另一個(gè)任務(wù)或ISR到達(dá)同步點(diǎn)時(shí),釋放信號(hào)量(將其值設(shè)置為1)表示同步事件已發(fā)生,以喚醒等待的任務(wù)。,2020/7/30,14,二值信號(hào)量,available,unavailable,acquire (value=0),release (value=1),Initial value=0,二值信號(hào)量狀態(tài)
6、圖,2020/7/30,15,Task1() 執(zhí)行一些操作; 將信號(hào)量sem1置1; 申請(qǐng)信號(hào)量sem2; ,Task2() 申請(qǐng)信號(hào)量sem1; 執(zhí)行一些操作; 將信號(hào)量sem2置1; ,Task2申請(qǐng)信號(hào)量sem1失敗,系統(tǒng)切換到Task1,sem1被置1后,Task2得到sem1并搶占Task1,Task2運(yùn)行到某處時(shí)因某種原因被阻塞,系統(tǒng)切換到Task1,用二值信號(hào)量實(shí)現(xiàn)兩個(gè)任務(wù)之間的雙向同步 Task2優(yōu)先級(jí)高于Task1 sem1和sem2的初始值均為0,2020/7/30,16,計(jì)數(shù)信號(hào)量,計(jì)數(shù)信號(hào)量用于控制系統(tǒng)中共享資源的多個(gè)實(shí)例的使用,允許多個(gè)任務(wù)同時(shí)訪問(wèn)同一種資源的多個(gè)實(shí)例
7、 計(jì)數(shù)信號(hào)量被初始化為n(非負(fù)整數(shù)),n為該種共享資源的數(shù)目。,2020/7/30,17,計(jì)數(shù)信號(hào)量,2020/7/30,18,計(jì)數(shù)信號(hào)量,計(jì)數(shù)信號(hào)量使用實(shí)例:有界緩沖問(wèn)題,2020/7/30,19,生產(chǎn)者任務(wù) do 產(chǎn)生一個(gè)數(shù)據(jù)項(xiàng) 申請(qǐng)empty 申請(qǐng)mutex 將新生成的數(shù)據(jù)項(xiàng)添加到緩沖中 釋放mutex 釋放full while (1);,消費(fèi)者任務(wù) do 申請(qǐng)full 申請(qǐng)mutex 從緩沖中移出一個(gè)數(shù)據(jù)項(xiàng)的內(nèi)容 釋放mutex 釋放empty 消費(fèi)新獲得的數(shù)據(jù)項(xiàng)內(nèi)容 while (1);,計(jì)數(shù)信號(hào)量full:已被填充的數(shù)據(jù)項(xiàng)數(shù)目,取值范圍0n,初始值為0 計(jì)數(shù)信號(hào)量empty:空閑數(shù)
8、據(jù)項(xiàng)數(shù)目,取值范圍為0n,初始值為n; 互斥信號(hào)量mutex:控制生產(chǎn)者任務(wù)和消費(fèi)者任務(wù)對(duì)有界緩沖的訪問(wèn),初始值為1。,2020/7/30,20,信號(hào)量機(jī)制的主要數(shù)據(jù)結(jié)構(gòu),信號(hào)量控制塊:管理所有創(chuàng)建的信號(hào)量,內(nèi)核在系統(tǒng)運(yùn)行時(shí)動(dòng)態(tài)分配和回收信號(hào)量控制塊 互斥和二值信號(hào)量控制塊結(jié)構(gòu):Binary_Semaphore_Control_Block,wait_queue任務(wù)等待隊(duì)列 attributes信號(hào)量屬性 wait_discipline任務(wù)等待信號(hào)量的方式 priority_ceiling優(yōu)先級(jí)天花板值 lock是否被占有 holder擁有者 count當(dāng)前計(jì)數(shù)值,2020/7/30,21,信號(hào)
9、量?jī)?nèi)部實(shí)現(xiàn)機(jī)制實(shí)例說(shuō)明C/OS-II,事件控制塊ECB同步與通信機(jī)制的基本數(shù)據(jù)結(jié)構(gòu) typedef struct INT8UOSEventType;/事件類(lèi)型 INT8UOSEventGrp;/等待任務(wù)所在的組 INT16UOSEventCnt;/計(jì)數(shù)器(信號(hào)量) void*OSEventPtr;/指向消息或消息隊(duì)列的指針 INT8UOSEventTblOS_EVENT_TBL_SIZE;/等待任務(wù)列表 OS_EVENT;,2020/7/30,22,信號(hào)量?jī)?nèi)部實(shí)現(xiàn)機(jī)制實(shí)例說(shuō)明C/OS-II,當(dāng)一個(gè)事件發(fā)生后,等待事件列表中優(yōu)先級(jí)最高的任務(wù)(即在.OSEventTbl pevent-OSEven
10、tTblprio 3 |= OSMapTblprio 與將一個(gè)任務(wù)插入到就緒列表中的操作類(lèi)似!,Index Bit mask (Binary) 0 00000001 1 00000010 2 00000100 3 00001000 4 00010000 5 00100000 6 01000000 7 10000000,2020/7/30,25,信號(hào)量?jī)?nèi)部實(shí)現(xiàn)機(jī)制實(shí)例說(shuō)明C/OS-II,從等待事件的任務(wù)列表中使任務(wù)脫離等待狀態(tài) if (pevent-OSEventTblprio 3 與將任務(wù)從就緒列表中清除的操作類(lèi)似!,2020/7/30,26,信號(hào)量?jī)?nèi)部實(shí)現(xiàn)機(jī)制實(shí)例說(shuō)明C/OS-II,在等待事
11、件的任務(wù)列表中查找優(yōu)先級(jí)最高的任務(wù) y = OSUnMapTblpevent-OSEventGrp; x = OSUnMapTblpevent-OSEventTbly; prio = (y 3) + x; 與查找優(yōu)先級(jí)最高的就緒任務(wù)的操作類(lèi)似!,2020/7/30,27,信號(hào)量?jī)?nèi)部實(shí)現(xiàn)機(jī)制實(shí)例說(shuō)明C/OS-II,空閑事件控制塊鏈表,2020/7/30,28,信號(hào)量的主要功能,創(chuàng)建信號(hào)量 獲?。ㄉ暾?qǐng))信號(hào)量 釋放信號(hào)量 刪除信號(hào)量 獲取有關(guān)信號(hào)量的各種信息,2020/7/30,29,創(chuàng)建信號(hào)量,功能:根據(jù)應(yīng)用傳遞的參數(shù)創(chuàng)建一個(gè)信號(hào)量 參數(shù):信號(hào)量的名字、屬性和初始值等。 內(nèi)核動(dòng)作: 從空閑信號(hào)量
12、控制塊鏈中分配一個(gè)信號(hào)量控制塊,并初始化信號(hào)量屬性。 創(chuàng)建成功時(shí),為其分配唯一的ID號(hào)返回給應(yīng)用。 如果已創(chuàng)建信號(hào)量數(shù)量已達(dá)到用戶(hù)配置的最大數(shù)量,就返回錯(cuò)誤。,2020/7/30,30,創(chuàng)建信號(hào)量,信號(hào)量的屬性包括其類(lèi)型、任務(wù)等待信號(hào)量的方式(即排列的順序)、解決優(yōu)先級(jí)反轉(zhuǎn)的策略。 信號(hào)量的類(lèi)型 互斥信號(hào)量(MUTEX_SEMAPHORE) 計(jì)數(shù)信號(hào)量(COUNTING_SEMAPHORE) 二值信號(hào)量(BINARY_SEMAPHORE),2020/7/30,31,創(chuàng)建信號(hào)量,任務(wù)等待信號(hào)量的方式 先進(jìn)先出(FIFO)順序 優(yōu)先級(jí)(PRIORITY)順序 優(yōu)先級(jí)反轉(zhuǎn)問(wèn)題的解決方法(只適用于互斥
13、信號(hào)量) 優(yōu)先級(jí)繼承算法(INHERIT_PRIORITY) 優(yōu)先級(jí)天花板算法(PRIORITY_CEILING) ,需給出所有可能獲得此信號(hào)量的任務(wù)中優(yōu)先級(jí)最高的任務(wù)的優(yōu)先級(jí)。,2020/7/30,32,創(chuàng)建一個(gè)信號(hào)量OSSemCreate(),OS_EVENT *OSSemCreate (INT16U cnt) OS_EVENT *pevent; pevent = OSEventFreeList;/從空閑事件控制塊鏈中取得一個(gè)ECB if (OSEventFreeList != (OS_EVENT *)0) OSEventFreeList = (OS_EVENT *)OSEventFree
14、List-OSEventPtr; if (pevent != (OS_EVENT *)0) /初始化ECB的各個(gè)域 pevent-OSEventType = OS_EVENT_TYPE_SEM; /事件類(lèi)型為信號(hào)量 pevent-OSEventCnt = cnt; /信號(hào)量的初始計(jì)數(shù)值 pevent-OSEventPtr = (void *)0; OS_EventWaitListInit(pevent); /初始化等待任務(wù)列表 return (pevent); /調(diào)用者需檢查返回值,如果為NULL則表示建立失敗 ,2020/7/30,33,獲?。ㄉ暾?qǐng))信號(hào)量,功能:試圖獲得應(yīng)用指定的信號(hào)量。
15、if 信號(hào)量的值大于0 then 將信號(hào)量的值減1 else 根據(jù)接收信號(hào)量的選項(xiàng),將任務(wù)放到等待隊(duì)列中,或是直接返回,2020/7/30,34,獲?。ㄉ暾?qǐng))信號(hào)量,當(dāng)所申請(qǐng)的信號(hào)量不能被立即獲得時(shí),可以有以下幾種選擇: 永遠(yuǎn)等待 不等待,立即返回,并返回一個(gè)錯(cuò)誤狀態(tài)碼 指定等待時(shí)限(可有效避免死鎖) 注意: 不允許在ISR中選擇等待 當(dāng)任務(wù)選擇等待時(shí),將被按FIFO或優(yōu)先級(jí)順序放置在等待隊(duì)列中,2020/7/30,35,獲取(申請(qǐng))信號(hào)量,如果任務(wù)等待一個(gè)使用優(yōu)先級(jí)繼承算法的互斥信號(hào)量,且它的優(yōu)先級(jí)高于當(dāng)前正占有此信號(hào)量的任務(wù)的優(yōu)先級(jí),那么占有信號(hào)量的任務(wù)將繼承這個(gè)被阻塞的任務(wù)的優(yōu)先級(jí)。 如
16、果任務(wù)成功地獲得一個(gè)采用優(yōu)先級(jí)天花板算法的互斥信號(hào)量,它的優(yōu)先級(jí)又低于優(yōu)先級(jí)天花板,那么它的優(yōu)先級(jí)將被抬升至天花板。,2020/7/30,36,獲?。ǖ却┮粋€(gè)信號(hào)量OSSemPend(),void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) if (pevent-OSEventCnt 0) /信號(hào)量值大于0,成功獲得信號(hào)量并返回 pevent-OSEventCnt-; *err = OS_NO_ERR; return; OSTCBCur-OSTCBStat |= OS_STAT_SEM; /設(shè)置任務(wù)狀態(tài)為等待信號(hào)量 OST
17、CBCur-OSTCBDly = timeout; /設(shè)置等待時(shí)限 OS_EventTaskWait(pevent);/將任務(wù)放置到信號(hào)量的等待列表中 OS_Sched(); /內(nèi)核實(shí)施任務(wù)調(diào)度,系統(tǒng)切換到另一就緒任務(wù)執(zhí)行 if (OSTCBCur-OSTCBStat /任務(wù)由于獲得信號(hào)量而恢復(fù)執(zhí)行,本調(diào)用成功返回 ,2020/7/30,37,獲?。o(wú)等待地請(qǐng)求)一個(gè)信號(hào)量OSSemAccept(),INT16U OSSemAccept (OS_EVENT *pevent) INT16U cnt; cnt = pevent-OSEventCnt; if (cnt 0) pevent-OSEve
18、ntCnt-; return (cnt); ,注意:即使不能成功獲得信號(hào)量(返回值為0),調(diào)用者也不會(huì)被阻塞。此函數(shù)可以在中斷處理程序中使用。,2020/7/30,38,釋放信號(hào)量,功能:釋放一個(gè)應(yīng)用指定的信號(hào)量。 if 沒(méi)有任務(wù)等待這個(gè)信號(hào)量 then 信號(hào)量的值加1 else 將信號(hào)量分配給一個(gè)等待任務(wù)(將相應(yīng)的任務(wù)移出等待隊(duì)列,使其就緒) 如果使用了優(yōu)先級(jí)繼承或優(yōu)先級(jí)天花板算法,那么執(zhí)行該功能(系統(tǒng)調(diào)用)的任務(wù)的優(yōu)先級(jí)將恢復(fù)到原來(lái)的高度。,2020/7/30,39,釋放一個(gè)信號(hào)量OSSemPost(),INT8U OSSemPost (OS_EVENT *pevent) if (peve
19、nt-OSEventGrp!=0 x00) /如果有任務(wù)在等待該信號(hào)量 OS_EventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /使等待任務(wù)列表中優(yōu)先級(jí)最高的任務(wù)就緒 OS_Sched(); /內(nèi)核實(shí)施任務(wù)調(diào)度 return (OS_NO_ERR);/成功返回 if (pevent-OSEventCnt OSEventCnt+; /信號(hào)量的值加1 return (OS_NO_ERR);/成功返回 return (OS_SEM_OVF);/信號(hào)量溢出 ,2020/7/30,40,刪除信號(hào)量,功能:從系統(tǒng)中刪除應(yīng)用指定的一個(gè)信號(hào)量 內(nèi)核動(dòng)作:將信號(hào)量控制塊
20、返還給系統(tǒng) 刪除信號(hào)量的不一定是創(chuàng)建信號(hào)量的任務(wù) 如果有任務(wù)正在等待獲得該信號(hào)量,執(zhí)行此功能將使所有等待這個(gè)信號(hào)量的任務(wù)回到就緒隊(duì)列中,且返回一個(gè)狀態(tài)碼指示該信號(hào)量已被刪除,2020/7/30,41,刪除一個(gè)信號(hào)量OSSemDel(),OS_EVENT *OSSemDel(OS_EVENT *pevent, INT8U opt, INT8U *err) BOOLEAN tasks_waiting; if(pevent-OSEventGrp!=0 x00/根據(jù)是否有任務(wù)在等待信號(hào)量設(shè)置等待標(biāo)志 tasks_waiting=TRUE; else tasks_waiting=FALSE; switc
21、h(opt) case OS_DEL_NO_PEND:/如果有任務(wù)等待信號(hào)量則不刪除信號(hào)量 if(task_waiting=FALSE/沒(méi)有任務(wù)等待,釋放ECB回空閑鏈 pevent-OSEventType=OS_EVENT_TYPE_UNUSED; pevent-OSEventPtr=OSEventFreeList; OSEventFreeList=pevent;/調(diào)整空閑ECB鏈頭指針 *err=OS_NO_ERR; return(OS_EVENT)0); else*err=OS_ERR_TASK_WAITING;/有任務(wù)等待,刪除信號(hào)量失敗 return(pevent); ,2020/7
22、/30,42,刪除一個(gè)信號(hào)量OSSemDel(),case OS_DEL_ALWAYS:/無(wú)論有無(wú)任務(wù)等待都刪除信號(hào)量 /將等待列表中的每個(gè)任務(wù)都設(shè)置成就緒 while(pevent-OSEventGrp!=0 x00) OS_EventTaskRdy(pevent,(void *)0, OS_STAT_SEM); /釋放該信號(hào)量的ECB回空閑控制塊鏈 pevent-OSEventType=OS_EVENT_TYPE_UNUSED; pevent-OSEventFreeList; OSEventFreeList=pevent; /如果之前有任務(wù)等待信號(hào)量,內(nèi)核實(shí)施任務(wù)調(diào)度 if(tasks_w
23、aiting=TRUE)OS_Sched(); *err=OS_NO_ERR; return(OS_EVENT *)0); default: *err=OS_ERR_INVALID_OPT; return(pevent); ,2020/7/30,43,2.郵箱和消息隊(duì)列,概述 消息隊(duì)列機(jī)制的主要數(shù)據(jù)結(jié)構(gòu) 消息隊(duì)列的主要功能,2020/7/30,44,任務(wù)間的通信方式 直接通信。在通信過(guò)程中雙方必須明確地知道(命名)彼此: Send (P,message) 發(fā)送一個(gè)消息到任務(wù)P Receive(Q,message) 從任務(wù)Q接收一個(gè)消息 間接通信。通信雙方不需要指出消息的來(lái)源或去向,而通過(guò)中間機(jī)
24、制來(lái)通信。如: send(A,message) 發(fā)送一個(gè)消息給郵箱A receive(A,message) 從郵箱A接收一個(gè)消息,概述,2020/7/30,45,消息隊(duì)列:屬于間接通信方式 消息:內(nèi)存空間中一段長(zhǎng)度可變的緩沖區(qū),其長(zhǎng)度和內(nèi)容均可以由用戶(hù)定義,其內(nèi)容可以是實(shí)際的數(shù)據(jù)、數(shù)據(jù)塊的指針或空。 對(duì)消息內(nèi)容的解釋由應(yīng)用完成。 從操作系統(tǒng)觀點(diǎn)看,消息沒(méi)有定義的格式,所有的消息都是字節(jié)流,沒(méi)有特定的含義。 從應(yīng)用觀點(diǎn)看,根據(jù)應(yīng)用定義的消息格式,消息被解釋成特定的含義。 應(yīng)用可以只把消息當(dāng)成一個(gè)標(biāo)志,這時(shí)消息機(jī)制用于實(shí)現(xiàn)同步,概述,2020/7/30,46,一些操作系統(tǒng)內(nèi)核把消息進(jìn)一步分為:郵箱
25、和消息隊(duì)列 郵箱僅能存放單條消息,它提供了一種低開(kāi)銷(xiāo)的機(jī)制來(lái)傳送信息。每個(gè)郵箱可以保存一條大小為若干個(gè)字節(jié)的消息。 消息隊(duì)列可存放若干消息,提供了一種任務(wù)間緩沖通信的方法。 消息機(jī)制可支持定長(zhǎng)與可變長(zhǎng)度兩種模式的消息,可變長(zhǎng)度的消息隊(duì)列需要對(duì)隊(duì)列中的每一條消息增加額外的存儲(chǔ)開(kāi)銷(xiāo)。,概述,2020/7/30,47,消息隊(duì)列機(jī)制的主要數(shù)據(jù)結(jié)構(gòu),消息隊(duì)列控制塊 管理所有創(chuàng)建的消息隊(duì)列,系統(tǒng)運(yùn)行時(shí)動(dòng)態(tài)分配和回收消息隊(duì)列控制塊 消息隊(duì)列緩沖區(qū) 存放發(fā)送到該隊(duì)列的消息,接收者從緩沖區(qū)中取出消息。 消息的發(fā)送或接收有兩種方法(影響消息緩沖區(qū)結(jié)構(gòu)): 將數(shù)據(jù)從發(fā)送任務(wù)的空間完全拷貝到接收任務(wù)的空間中(效率較低
26、,執(zhí)行時(shí)間與消息大小有關(guān)) 只傳遞指向數(shù)據(jù)存儲(chǔ)空間的指針(提高系統(tǒng)性能),2020/7/30,48,發(fā)送和接收消息的消息拷貝和內(nèi)存使用 這種消息傳遞方法效率低、占用空間大 一種效率更高的方式是傳遞消息指針,2020/7/30,49,number_of_message,max_message_count,消息隊(duì)列控制塊,消息隊(duì)列緩沖區(qū),消息隊(duì)列機(jī)制的主要數(shù)據(jù)結(jié)構(gòu),2020/7/30,50,消息隊(duì)列的環(huán)形緩沖,消息隊(duì)列機(jī)制的主要數(shù)據(jù)結(jié)構(gòu),2020/7/30,51,消息隊(duì)列的主要功能,創(chuàng)建消息隊(duì)列 發(fā)送普通消息 發(fā)送緊急消息 發(fā)送廣播消息 接收消息 刪除消息隊(duì)列 獲取有關(guān)消息隊(duì)列的各種信息,2020
27、/7/30,52,消息隊(duì)列的主要功能,隨著任務(wù)(或ISR)不斷地向(從)消息隊(duì)列發(fā)送(接收)消息,消息隊(duì)列的狀態(tài)不斷轉(zhuǎn)換,可以有如下幾種狀態(tài): 消息隊(duì)列為空 消息隊(duì)列為空且有任務(wù)等待接收消息 消息隊(duì)列中有消息,但未滿(mǎn) 消息隊(duì)列滿(mǎn) 消息隊(duì)列滿(mǎn),且有任務(wù)等待向它發(fā)送消息,2020/7/30,53,創(chuàng)建消息隊(duì)列,創(chuàng)建消息隊(duì)列時(shí),調(diào)用者可以指定如下參數(shù): 消息的最大長(zhǎng)度 每個(gè)消息隊(duì)列中最多的消息數(shù) 消息隊(duì)列的屬性 任務(wù)等待消息時(shí)的排隊(duì)方式:FIFO或PRIORITY 系統(tǒng)為新創(chuàng)建的消息隊(duì)列分配唯一的ID,2020/7/30,54,發(fā)送消息,根據(jù)緊急程度的不同,消息通??煞譃槠胀ㄏ⑴c緊急消息。 如果有
28、任務(wù)正在等待消息(即消息隊(duì)列為空),則普通消息發(fā)送和緊急消息發(fā)送的執(zhí)行效果是一樣的。任務(wù)從等待隊(duì)列移到就緒隊(duì)列中,消息被拷貝到任務(wù)提供的緩沖區(qū)中(或者由接收任務(wù)得到指向消息的指針)。 如果沒(méi)有任務(wù)等待,發(fā)送普通消息將消息放在隊(duì)列尾,而發(fā)送緊急消息將消息放在隊(duì)列頭。,2020/7/30,55,發(fā)送消息,2020/7/30,56,發(fā)送消息,如果發(fā)送消息時(shí)隊(duì)列已被填滿(mǎn),則不同的操作系統(tǒng)可能采取不同的處理辦法: 掛起試圖向已滿(mǎn)的消息隊(duì)列中發(fā)送消息的任務(wù)(不適用于中斷服務(wù)程序) 簡(jiǎn)單地丟棄該條消息并向調(diào)用者返回錯(cuò)誤信息 廣播消息。在此之前所有試圖從隊(duì)列中接收消息的任務(wù)此時(shí)都將獲得相同的消息。該功能拷貝消
29、息到各任務(wù)的消息緩沖中(或者讓所有的等待任務(wù)得到指向消息的指針),并喚醒所有的等待任務(wù)。,2020/7/30,57,接收消息,如果指定的消息隊(duì)列中有消息,則將其中的第一條消息拷貝到調(diào)用者的緩沖區(qū)(或者將第一條消息指針傳遞給調(diào)用者),并從消息隊(duì)列中刪除它。 如果此時(shí)消息隊(duì)列中沒(méi)有消息,則可能出現(xiàn)以下幾種情況: 永遠(yuǎn)等待消息的到達(dá):等待消息的任務(wù)按FIFO或優(yōu)先級(jí)高低順序排列在等待隊(duì)列中 等待消息且指定等待時(shí)限:等待消息的任務(wù)按FIFO或優(yōu)先級(jí)高低順序排列在等待隊(duì)列中 不等待,強(qiáng)制立即返回,2020/7/30,58,接收消息,限時(shí)等待可有效預(yù)防死鎖 中斷服務(wù)程序接收消息時(shí)必須選擇不等待,因?yàn)橹袛喾?/p>
30、務(wù)程序是不能被阻塞的。 如果消息隊(duì)列被應(yīng)用刪除,則所有等待該消息隊(duì)列的任務(wù)都被返回一個(gè)錯(cuò)誤信息,并回復(fù)到就緒狀態(tài)。,2020/7/30,59,接收消息,2020/7/30,60,刪除消息隊(duì)列,從系統(tǒng)中刪除指定的消息隊(duì)列,釋放消息隊(duì)列控制塊及消息隊(duì)列緩沖區(qū)。 任何知道此消息隊(duì)列ID號(hào)的代碼都可以刪除它。 消息隊(duì)列被刪除后,所有等待從這個(gè)消息隊(duì)列接收消息的任務(wù)都回到就緒態(tài),并得到一個(gè)錯(cuò)誤信息表明消息隊(duì)列已被刪除。,2020/7/30,61,3.事 件,概述 事件機(jī)制的主要數(shù)據(jù)結(jié)構(gòu) 事件的主要功能,2020/7/30,62,在嵌入式實(shí)時(shí)內(nèi)核中,事件是指一種表明預(yù)先定義的系統(tǒng)事件已經(jīng)發(fā)生的機(jī)制。 事件
31、機(jī)制用于任務(wù)與任務(wù)之間、任務(wù)與ISR之間的同步。其主要的特點(diǎn)是可實(shí)現(xiàn)一對(duì)多的同步。 一個(gè)事件就是一個(gè)標(biāo)志,不具備其它信息。 一個(gè)或多個(gè)事件構(gòu)成一個(gè)事件集。事件集可以用一個(gè)指定長(zhǎng)度的變量(比如一個(gè)32位的無(wú)符號(hào)整型變量,不同的操作系統(tǒng)其具體實(shí)現(xiàn)不一樣)來(lái)表示,而每個(gè)事件由在事件集變量中的某一位來(lái)代表。,概述,2020/7/30,63,事件及事件集有以下特點(diǎn): 事件間相互獨(dú)立 事件僅用于同步,不提供數(shù)據(jù)傳輸功能 事件無(wú)隊(duì)列,即多次發(fā)送同一事件,在未經(jīng)過(guò)任何處理的情況下,其效果等同于只發(fā)送一次。 提供事件機(jī)制的意義在于: 當(dāng)某任務(wù)要與多個(gè)任務(wù)或中斷服務(wù)同步時(shí),就需要使用事件機(jī)制。 若任務(wù)需要與一組事
32、件中的任意一個(gè)發(fā)生同步,可稱(chēng)為獨(dú)立型同步(邏輯“或”關(guān)系)。 任務(wù)也可以等待若干事件都發(fā)生時(shí)才同步,稱(chēng)為關(guān)聯(lián)型同步(邏輯“與”關(guān)系)。,概述,2020/7/30,64,“或”同步和“與”同步,概述,2020/7/30,65,用多個(gè)事件的組合發(fā)信號(hào)給多個(gè)任務(wù),概述,2020/7/30,66,術(shù)語(yǔ): 發(fā)送事件集 。指在一次發(fā)送過(guò)程中發(fā)往接收者(比如任務(wù))的一個(gè)或多個(gè)事件的組合。 待處理事件集。指已被發(fā)送到一個(gè)接收者但還沒(méi)有被接收(即正在等待處理)的所有事件的集合。 事件條件。指事件接收者在一次接收過(guò)程中期待接收的一個(gè)或多個(gè)事件的集合。 “或”同步:待處理事件集只要包括事件條件中的任一事件即可滿(mǎn)足要
33、求; “與”同步:其二是待處理事件集必須包括事件條件中的全部事件方可滿(mǎn)足要求。,概述,2020/7/30,67,事件機(jī)制的主要數(shù)據(jù)結(jié)構(gòu),事件集控制塊:管理所有創(chuàng)建的事件集 或者 事件集附屬于任務(wù),不需創(chuàng)建,其相關(guān)參數(shù)成為任務(wù)控制塊的一部分,2020/7/30,68,事件的內(nèi)部實(shí)現(xiàn)機(jī)制實(shí)例說(shuō)明C/OS-II,事件標(biāo)志組數(shù)據(jù)結(jié)構(gòu) typedef struct INT8UOSFlagType;/指示本數(shù)據(jù)結(jié)構(gòu)的類(lèi)型 void*OSFlagWaitList;/等待事件標(biāo)志的任務(wù)鏈表 OS_FLAGSOSFlagFlags;/各事件標(biāo)志的當(dāng)前狀態(tài) OS_FLAG_GRP; 事件標(biāo)志節(jié)點(diǎn)數(shù)據(jù)結(jié)構(gòu) type
34、def struct void*OSFlagNodeNext;/后驅(qū)指針 void*OSFlagNodePrev;/前驅(qū)指針 void*OSFlagNodeTCB;/任務(wù)控制塊指針 void*OSFlagNodeFlagGrp;/指回OS_FLAG_GRP結(jié)構(gòu) OS_FLAGSOSFlagNodeFlags;/所等待的事件標(biāo)志組合 INT8UOSFlagNodeWaitType;/等待類(lèi)型(與、或) OS_FLAG_NODE;,2020/7/30,69,事件標(biāo)志組、事件標(biāo)志節(jié)點(diǎn)及任務(wù)控制塊之間的關(guān)系,2020/7/30,70,事件的主要功能,創(chuàng)建事件集 刪除事件集 發(fā)送事件(集) 接收事件(集
35、) 獲取有關(guān)事件集的各種信息,2020/7/30,71,創(chuàng)建事件集,申請(qǐng)空閑事件集控制塊,設(shè)置事件集屬性,初始化控制塊中的域,分配ID號(hào),2020/7/30,72,創(chuàng)建一個(gè)事件標(biāo)志組OSFlagCreate(),OS_FLAG_GRP *OSFlagCreate(OS_FLAGS flags, INT8U *err) OS_FLAG_GRP *pgrp; pgrp=OSFlagFreeList;/獲取一個(gè)空閑事件標(biāo)志組結(jié)構(gòu) if(pgrp!=(OS_FLAG_GRP *)0)/獲取成功,初始化該結(jié)構(gòu)中的域 OSFlagFreeList=(OS_FLAG_GRP *)OSFlagFreeList
36、-OSFlagWaitList;/調(diào)整空閑結(jié)構(gòu)鏈頭指針 pgrp-OSFlagType=OS_EVENT_TYPE_FLAG; pgrp-OSFlagFlags=flags;/初始化當(dāng)前各事件標(biāo)志的狀態(tài) pgrp-OSFlagWaitList=(void *)0;/尚無(wú)任務(wù)等待事件標(biāo)志 *err=OS_NO_ERR; else*err=OS_FLAG_GRP_DEPLETED; return(pgrp); ,2020/7/30,73,接收事件(集),在接收事件(集)時(shí)可以有如下選項(xiàng),每一類(lèi)只能選擇其一: 接收事件(集)時(shí)可等待(WAIT) 接收者永遠(yuǎn)等待,直到事件條件被滿(mǎn)足后成功返回; 接收者
37、根據(jù)指定的時(shí)限等待。 接收事件(集)時(shí)不等待(NO_WAIT) 待處理事件集必須包含事件條件中的全部事件方可滿(mǎn)足要求(EVENT_ALL),即按照“與”條件接收事件 待處理事件集只要包含事件條件中的任一事件即可滿(mǎn)足要求(EVENT_ANY),即按照“或”條件接收事件,2020/7/30,74,接收(等待)事件標(biāo)志組的事件標(biāo)志位OSFlagPend(),OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT16U timeout, INT8U *err) OS_FLAG_NODE node;/ OS_
38、FLAG_NODE作為局部變量存在于調(diào)用該函數(shù)的任務(wù)堆棧中 OS_FLAGS flags_cur; OS_FLAGS flags_rdy; switch(wait_type) case OS_FLAG_WAIT_SET_ALL:/任務(wù)以“與”方式等待事件標(biāo)志 flags_rdy=pgrp-OSFlagFlags,2020/7/30,75,接收(等待)事件標(biāo)志組的事件標(biāo)志位OSFlagPend(),case OS_FLAG_WAIT_SET_ANY: /任務(wù)以“或”方式等待事件標(biāo)志 flags_rdy=pgrp-OSFlagFlags ,2020/7/30,76,OS_Sched();/當(dāng)前任務(wù)
39、被放到事件標(biāo)志等待鏈后,內(nèi)核實(shí)施任務(wù)調(diào)度 if(OSTCBCur-OSTCBStat ,接收(等待)事件標(biāo)志組的事件標(biāo)志位OSFlagPend(),2020/7/30,77,添加一個(gè)任務(wù)到事件標(biāo)志組等待任務(wù)鏈表中OS_FlagBlock(),2020/7/30,78,接收(無(wú)等待地獲?。┦录?biāo)志OSFlagAccept(),OS_FLAGS OSFlagAccept (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U wait_type, INT8U *err) OS_FLAGS flags_cur, flags_rdy; *err = OS_NO_ERR; s
40、witch (wait_type) /判斷等待事件標(biāo)志的方式 case OS_FLAG_WAIT_SET_ALL:/”與”方式等待 flags_rdy = pgrp-OSFlagFlags ,2020/7/30,79,接收(無(wú)等待地獲?。┦录?biāo)志OSFlagAccept(),case OS_FLAG_WAIT_SET_ANY:/”或”方式等待 flags_rdy = pgrp-OSFlagFlags ,2020/7/30,80,發(fā)送事件(集),調(diào)用者(任務(wù)或中斷)構(gòu)造一個(gè)事件(集),將其發(fā)往接收者(比如目標(biāo)任務(wù))??赡軙?huì)出現(xiàn)以下幾種情況之一: 目標(biāo)任務(wù)正在等待的事件條件得到滿(mǎn)足,任務(wù)就緒; 目
41、標(biāo)任務(wù)正在等待的事件條件沒(méi)有得到滿(mǎn)足,該事件(集)被按“或”操作,保存到目標(biāo)任務(wù)的待處理事件集中,目標(biāo)任務(wù)繼續(xù)等待; 目標(biāo)任務(wù)未等待事件(集),該事件(集)被按“或”操作,保存到目標(biāo)任務(wù)的待處理事件集中。,2020/7/30,81,發(fā)送(置位)事件標(biāo)志組中的事件標(biāo)志OSFlagPost(),OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U *err) OS_FLAG_NODE *pnode; BOOLEAN sched= FALSE;/初始化調(diào)度標(biāo)志 OS_FLAGS flags_cur, flags_rdy; pgrp
42、-OSFlagFlags |= flags;/置位事件標(biāo)志 pnode = (OS_FLAG_NODE *)pgrp-OSFlagWaitList;/獲取任務(wù)等待鏈頭節(jié)點(diǎn) while (pnode != (OS_FLAG_NODE *)0) /如果有任務(wù)等待,遍歷等待鏈 switch (pnode-OSFlagNodeWaitType) case OS_FLAG_WAIT_SET_ALL:/”與”方式等待 flags_rdy = pgrp-OSFlagFlags ,2020/7/30,82,case OS_FLAG_WAIT_SET_ANY:/”或”方式等待 flags_rdy = pgrp-
43、OSFlagFlags ,發(fā)送(置位)事件標(biāo)志組中的事件標(biāo)志OSFlagPost(),2020/7/30,83,刪除事件集,回收事件集控制塊到空閑鏈中,等待接收該事件集的任務(wù)被恢復(fù)就緒,2020/7/30,84,刪除事件標(biāo)志組OSFlagDel(),OS_FLAG_GRP *OSFlagDel (OS_FLAG_GRP *pgrp, INT8U opt, INT8U *err) BOOLEAN tasks_waiting; OS_FLAG_NODE *pnode; if (pgrp-OSFlagWaitList != (void *)0) tasks_waiting = TRUE;/有任務(wù)等待
44、 else tasks_waiting = FALSE;/無(wú)任務(wù)等待 switch (opt) case OS_DEL_NO_PEND:/在無(wú)任務(wù)等待時(shí)才刪除事件標(biāo)志組 if (tasks_waiting = FALSE) /無(wú)任務(wù)等待,釋放控制塊到空閑鏈中 pgrp-OSFlagType = OS_EVENT_TYPE_UNUSED; pgrp-OSFlagWaitList = (void *)OSFlagFreeList; OSFlagFreeList = pgrp; *err = OS_NO_ERR; return (OS_FLAG_GRP *)0); else /有任務(wù)等待,刪除失敗
45、*err = OS_ERR_TASK_WAITING; return (pgrp); ,2020/7/30,85,刪除事件標(biāo)志組OSFlagDel(),case OS_DEL_ALWAYS:/無(wú)論是否有任務(wù)等待,都刪除事件標(biāo)志組 pnode = (OS_FLAG_NODE *)pgrp-OSFlagWaitList;/獲取等待頭節(jié)點(diǎn) while (pnode != (OS_FLAG_NODE *)0) /遍歷整個(gè)等待任務(wù)鏈,使每個(gè)等待任務(wù)就緒 OS_FlagTaskRdy(pnode, (OS_FLAGS)0); pnode = (OS_FLAG_NODE *)pnode-OSFlagNode
46、Next; pgrp-OSFlagType = OS_EVENT_TYPE_UNUSED; pgrp-OSFlagWaitList = (void *)OSFlagFreeList; OSFlagFreeList = pgrp;/釋放控制塊回空閑鏈 if (tasks_waiting = TRUE) OS_Sched();/如果之前有任務(wù)等待, *err = OS_NO_ERR;內(nèi)核實(shí)施調(diào)度 return (OS_FLAG_GRP *)0); default: *err = OS_ERR_INVALID_OPT; return (pgrp); ,2020/7/30,86,事件與其它同步通信機(jī)制
47、的綜合應(yīng)用,解決復(fù)雜的應(yīng)用設(shè)計(jì)問(wèn)題,發(fā)送方通過(guò)適當(dāng)?shù)臋C(jī)制向接收方發(fā)送信息 發(fā)送方設(shè)置相應(yīng)的事件標(biāo)志 接收方收到事件標(biāo)志 接收方根據(jù)事件標(biāo)志的指示定向接收信息,達(dá)到和不同發(fā)送方同步或通信的目的,2020/7/30,87,4.異步信號(hào),概述 異步信號(hào)機(jī)制與中斷機(jī)制的比較 異步信號(hào)機(jī)制與事件機(jī)制的比較 異步信號(hào)機(jī)制的主要數(shù)據(jù)結(jié)構(gòu) 異步信號(hào)的主要功能,2020/7/30,88,異步信號(hào)機(jī)制用于任務(wù)與任務(wù)之間、任務(wù)與ISR之間的異步操作,它被任務(wù)(或ISR)用來(lái)通知其它任務(wù)某個(gè)事件的出現(xiàn)。 異步信號(hào)標(biāo)志可以依附于任務(wù)。需要處理異步信號(hào)的任務(wù)由兩部分組成,一個(gè)是與異步信號(hào)無(wú)關(guān)的任務(wù)主體,另一個(gè)是ASR(異步信號(hào)服務(wù)例程)。 一個(gè)ASR對(duì)應(yīng)于一個(gè)任務(wù)。當(dāng)向任務(wù)發(fā)送一個(gè)異步信號(hào),如果該任務(wù)正在運(yùn)行則中止其自身代碼的運(yùn)行,轉(zhuǎn)而運(yùn)行與該異步信號(hào)相關(guān)的服務(wù)例程;或者當(dāng)該任務(wù)被激活時(shí),在投入運(yùn)行前執(zhí)行ASR。 異步信號(hào)機(jī)制也可以稱(chēng)作軟中斷機(jī)制,異步信號(hào)又被稱(chēng)為軟中斷信號(hào)。,概述,2020/7/30,89,異步信號(hào)機(jī)制與中斷機(jī)制的比較,相同點(diǎn) 具有中斷性。對(duì)中斷的處理和對(duì)異步信號(hào)的處理都要先暫時(shí)地中斷當(dāng)前任務(wù)的運(yùn)行。 有相應(yīng)的服務(wù)程序 根據(jù)中斷向量,有一段與中斷信號(hào)對(duì)應(yīng)的服務(wù)程序,稱(chēng)為ISR(Interrupt Service Routine) 根據(jù)異步
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 班級(jí)敬老活動(dòng)方案
- 物流公司祭車(chē)活動(dòng)方案
- 班組創(chuàng)客大賽活動(dòng)方案
- 生活部部長(zhǎng)策劃活動(dòng)方案
- 豬后腿肉活動(dòng)方案
- 班級(jí)舊書(shū)循環(huán)活動(dòng)方案
- 物業(yè)小年活動(dòng)方案
- 王者業(yè)務(wù)活動(dòng)方案
- 愛(ài)國(guó)教育活動(dòng)活動(dòng)方案
- 愛(ài)國(guó)活動(dòng)進(jìn)禮堂活動(dòng)方案
- 期末試卷(含答案)2024-2025學(xué)年四年級(jí)下冊(cè)數(shù)學(xué)北師大版
- 《客艙安全與應(yīng)急處置》-課件:火災(zāi)的基礎(chǔ)知識(shí)
- 自然資源執(zhí)法監(jiān)察工作規(guī)范培訓(xùn)課件
- GB 2707-2016食品安全國(guó)家標(biāo)準(zhǔn)鮮(凍)畜、禽產(chǎn)品
- 建設(shè)工程施工合同司法解釋課件
- 做好新形勢(shì)下群眾工作培訓(xùn)課件
- NB∕T 10731-2021 煤礦井下防水密閉墻設(shè)計(jì)施工及驗(yàn)收規(guī)范
- 《干部履歷表》(1999版電子版)
- 大學(xué)生創(chuàng)新創(chuàng)業(yè)訓(xùn)練計(jì)劃項(xiàng)目(模板)
- 巨量引擎O-5A人群資產(chǎn)經(jīng)營(yíng)方法論
- 置信度-可靠度-存活率
評(píng)論
0/150
提交評(píng)論