




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
12023/7/24嵌入式操作系統(tǒng)及開(kāi)發(fā)2023/7/242第4章任務(wù)的
同步與通信32023/7/24第4章任務(wù)的同步與通信一個(gè)應(yīng)用系統(tǒng)通常是由多個(gè)任務(wù)組成,任務(wù)之間互相協(xié)作共同完成目標(biāo)功能。例如任務(wù)對(duì)共享資源競(jìng)爭(zhēng),先采集數(shù)據(jù)才能處理數(shù)據(jù)等情況。(任務(wù)的同步控制,共享資源的競(jìng)爭(zhēng),任務(wù)間的通信等問(wèn)題的解決方案---OS)任務(wù)間的同步----任務(wù)間的制約性的合作運(yùn)行機(jī)制。系統(tǒng)各任務(wù)之間通過(guò)“任務(wù)通信”的方式,實(shí)現(xiàn)任務(wù)的信息傳遞和同步控制,“任務(wù)通信”的載體就是----事件。常用的事件:信號(hào)量(計(jì)數(shù)型---SEM/互斥型---MUTEX)、消息郵箱(MBOX)、消息隊(duì)列(Q)、事件標(biāo)志組等。事件用“事件控制塊”(ECB)來(lái)描述。42023/7/24第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作52023/7/24第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作62023/7/244.1任務(wù)間的同步和事件控制塊任務(wù)間的同步---各任務(wù)運(yùn)行的先后、觸發(fā)等關(guān)系備注:數(shù)據(jù)采集任務(wù)A和數(shù)據(jù)處理任務(wù)B之間存在同步關(guān)系。72023/7/244.1任務(wù)間的同步和事件控制塊任務(wù)間的互斥
---共享資源的申請(qǐng)使用備注:數(shù)據(jù)采集任務(wù)A和數(shù)據(jù)處理任務(wù)B之間存在互斥關(guān)系。82023/7/244.1任務(wù)間的同步和事件控制塊任務(wù)之間的這種相互制約、相互合作的運(yùn)行機(jī)制稱(chēng)為“任務(wù)間的同步”系統(tǒng)中任務(wù)之間相互傳遞事件,來(lái)實(shí)現(xiàn)任務(wù)的同步、協(xié)作。備注:用戶自定義全局變量的方法,也可以編程實(shí)現(xiàn)程序間的信息傳遞。但如果想將信息傳遞的各項(xiàng)功能作完備,工作量是比較大的。況且,這類(lèi)需求在應(yīng)用系統(tǒng)設(shè)計(jì)中是很常用的。uC/OS-II中將此類(lèi)工作以系統(tǒng)功能方式提供與用戶----事件操作。92023/7/24舉例:任務(wù)間的共享資源競(jìng)爭(zhēng)問(wèn)題及處理方式。某一分布式系統(tǒng),需要主設(shè)備(M_Dev)使用同一個(gè)UART資源分別與從設(shè)備1(S_Dev1)和從設(shè)備2(S_Dev2)以不同的“串行通信模式”進(jìn)行通信。102023/7/24voidmain(void) //系統(tǒng)主函數(shù){OSInit();......;OSTaskCreate(Task_A,(void*)pdata,......);OSTaskCreate(Task_B,(void*)pdata,......);......;OSStart();}voidTask_A(void*pdata){......;//Task_A環(huán)境初始化
for(;;){......;//Task_A業(yè)務(wù)
OSTaskCreate(UART_S1_Task,(void*)US1,......);......;//Task_A業(yè)務(wù)
OSTimeDly(xxx);}}voidTask_B(void*pdata){......;//Task_B環(huán)境初始化
for(;;){......;//Task_B業(yè)務(wù)
OSTaskCreate(UART_S2_Task,(void*)US2,......);......;//Task_B業(yè)務(wù)
OSTimeDly(yyy);}}說(shuō)明:如此設(shè)計(jì)未對(duì)共享資源作任何約束,實(shí)際運(yùn)行中可能發(fā)生Task_A與Task_B沖突競(jìng)爭(zhēng)。BOOLEANuart_key;voidmain(void) //系統(tǒng)主函數(shù){OSInit();......;
uart_key=TRUE;OSTaskCreate(Task_A,(void*)pdata,......);OSTaskCreate(Task_B,(void*)pdata,......);......;OSStart();}voidTask_A(void*pdata){......;//Task_A環(huán)境初始化
for(;;){......;//Task_A業(yè)務(wù)
if(uart_key){uart_key=FALSE;OSTaskCreate(UART_S1_Task,(void*)US1,......);
uart_key=TRUE;}......;//Task_A業(yè)務(wù)
OSTimeDly(xxx);}}voidTask_B(void*pdata){......;//Task_B環(huán)境初始化
for(;;){......;//Task_B業(yè)務(wù)
if(uart_key){uart_key=FALSE;OSTaskCreate(UART_S2_Task,(void*)US2,......);
uart_key=TRUE;}......;//Task_B業(yè)務(wù)
OSTimeDly(yyy);}}(互斥型任務(wù)處理)說(shuō)明:通過(guò)用戶定義全局變量uart_key對(duì)任務(wù)使用共享資源作約束,可以避免Task_A與Task_B沖突競(jìng)爭(zhēng),但其管理性能支持較弱。void*msg_ptr;INT16UAD_Value;voidmain(void) //系統(tǒng)主函數(shù){OSInit();......;OSTaskCreate(Task_A,(void*)pdata,......);OSTaskCreate(Task_B,(void*)pdata,......);......;OSStart();}voidTask_A(void*pdata){......;//Task_A環(huán)境初始化
for(;;){......;//Task_A業(yè)務(wù)
if(msg_ptr==NULL){Signal_Capture(AD_Value);//采集數(shù)據(jù)
msg_ptr=&AD_Value;}......;//Task_A業(yè)務(wù)
OSTimeDly(xxx);}}voidTask_B(void*pdata){......;//Task_B環(huán)境初始化
INT16UAD_B;for(;;){......;//Task_B業(yè)務(wù)
if(msg_ptr!=NULL){AD_B=*msg_ptr;//數(shù)據(jù)處理
msg_ptr=NULL;}......;//Task_B業(yè)務(wù)
OSTimeDly(yyy);}}(帶數(shù)據(jù)傳遞的協(xié)作型任務(wù)處理)說(shuō)明:Task_A數(shù)據(jù)采集任務(wù),Task_B數(shù)據(jù)處理任務(wù);通過(guò)用戶定義全局指針變量msg_ptr對(duì)(采集、處理數(shù)據(jù))任務(wù)作約束,可以協(xié)調(diào)Task_A與Task_B,但其管理性能支持較弱。132023/7/244.1任務(wù)間的同步和事件控制塊事件漢語(yǔ)中所謂的“事件”,是指一個(gè)事情的發(fā)生。在uC/OS-II中將信號(hào)量、消息郵箱和消息隊(duì)列的一個(gè)存在稱(chēng)為一個(gè)事件,事件操作:創(chuàng)建、發(fā)送、請(qǐng)求和刪除等。(uC/OS的原作者將“事件---EVENT”理解為靜態(tài)的數(shù)據(jù)結(jié)構(gòu)。)發(fā)送事件----向信號(hào)量、消息郵箱和消息隊(duì)列的一次信息發(fā)送(寫(xiě)---Post)操作。請(qǐng)求事件----對(duì)信號(hào)量、消息郵箱和消息隊(duì)列的一次查詢(讀---Pend)操作。uC/OS-II中以系統(tǒng)函數(shù)的方式向任務(wù)提供事件操作。142023/7/244.1任務(wù)間的同步和事件控制塊事件(1)
----信號(hào)量(Sem/Mutex)兩類(lèi)信號(hào)量:互斥信號(hào)量---Mutex、計(jì)數(shù)型信號(hào)量---Sem;互斥信號(hào)量是一個(gè)二值信號(hào)量,主要用于“獨(dú)占式共享資源”的管理(例如:打印機(jī))。計(jì)數(shù)型信號(hào)量用以“多個(gè)同類(lèi)型資源”的管理,通常用一個(gè)計(jì)數(shù)器實(shí)現(xiàn)(例如:存儲(chǔ)塊)。BOOLEANuart_key;//互斥標(biāo)志voidmain(void) //系統(tǒng)主函數(shù){OSInit();......;
uart_key=TRUE;OSTaskCreate(Task_A,(void*)pdata,......);OSTaskCreate(Task_B,(void*)pdata,......);......;OSStart();}voidTask_A(void*pdata){......;//Task_A環(huán)境初始化
for(;;){......;//Task_A業(yè)務(wù)
if(uart_key){uart_key=FALSE;OSTaskCreate(UART_S1_Task,(void*)US1,......);
uart_key=TRUE;}......;//Task_A業(yè)務(wù)
OSTimeDly(xxx);}}voidTask_B(void*pdata){......;//Task_B環(huán)境初始化
for(;;){......;//Task_B業(yè)務(wù)
if(uart_key){uart_key=FALSE;OSTaskCreate(UART_S2_Task,(void*)US2,......);
uart_key=TRUE;}......;//Task_B業(yè)務(wù)
OSTimeDly(yyy);}}(互斥型任務(wù)處理)說(shuō)明:通過(guò)用戶定義全局變量uart_key對(duì)任務(wù)使用共享資源作約束,可以避免Task_A與Task_B沖突競(jìng)爭(zhēng),但其管理性能支持較弱。162023/7/244.1任務(wù)間的同步和事件控制塊事件(2)
----消息郵箱(Mbox)用于解決任務(wù)間的數(shù)據(jù)傳送問(wèn)題。在多任務(wù)OS中采用消息傳送的方式實(shí)現(xiàn)任務(wù)間的“單批次數(shù)據(jù)”通信,這個(gè)數(shù)據(jù)稱(chēng)為“消息”。例如:Task_A采集一個(gè)數(shù)據(jù),Task_B要使用Task_A采集的數(shù)據(jù)。原理:在內(nèi)存中創(chuàng)建數(shù)據(jù)傳送緩沖區(qū)(消息緩沖區(qū)),通過(guò)傳送該緩沖區(qū)的地址指針傳遞數(shù)據(jù)。這個(gè)緩沖區(qū)指針的數(shù)據(jù)結(jié)構(gòu)稱(chēng)為“消息郵箱”。172023/7/244.1任務(wù)間的同步和事件控制塊事件(2)
----消息郵箱(Mbox)182023/7/244.1任務(wù)間的同步和事件控制塊事件(3)
----消息隊(duì)列(Q)用于解決任務(wù)間的“多個(gè)數(shù)據(jù)”傳送問(wèn)題。在多任務(wù)OS中,采用“指針數(shù)組”的方式進(jìn)行多數(shù)據(jù)的傳送。這個(gè)指向“指針數(shù)組”的指針+“指針數(shù)組”+消息緩沖區(qū)所構(gòu)成的數(shù)據(jù)結(jié)構(gòu)稱(chēng)為“消息隊(duì)列”。192023/7/244.1任務(wù)間的同步和事件控制塊等待任務(wù)列表當(dāng)一個(gè)“事件”被占用時(shí),其它請(qǐng)求該事件的任務(wù)暫時(shí)得不到事件的服務(wù),處于等待狀態(tài)。OS使用《等待任務(wù)表》管理“事件”;即使用《等待任務(wù)表》對(duì)那些等待該事件的各個(gè)任務(wù)進(jìn)行管理(記錄等待該事件的任務(wù)并排序,任務(wù)等待事件有限時(shí)等)。每個(gè)事件都有一個(gè)“等待任務(wù)表”,用于完成事件對(duì)任務(wù)的驅(qū)動(dòng)、限時(shí)等管理,其原理類(lèi)似于任務(wù)就緒表。任務(wù)等待事件限時(shí)則記錄在TCB的OSTCBDly成員中,每個(gè)Tick都會(huì)對(duì)其進(jìn)行維護(hù),當(dāng)限時(shí)到時(shí)uC/OS-II強(qiáng)行將其轉(zhuǎn)入就緒狀態(tài)。202023/7/244.1任務(wù)間的同步和事件控制塊事件控制塊(ECB)uC/OS-II使用ECB的數(shù)據(jù)結(jié)構(gòu)統(tǒng)一描述三類(lèi)事件(信號(hào)量、消息郵箱、消息隊(duì)列)。uC/OS-II中的ECB數(shù)據(jù)結(jié)構(gòu)如下:typedefstruct{INT8UOSEventType; //事件類(lèi)型
INT16UOSEventCnt; //計(jì)數(shù)信號(hào)量的計(jì)數(shù)器
void*OSEventPtr; //消息(消息隊(duì)列)指針
INT8UOSEventGrp; //等待事件的任務(wù)組
INT8UOSEventTbl[OS_EVENT_TBL_SIZE];//任務(wù)等待表}OS_EVENT;212023/7/244.1任務(wù)間的同步和事件控制塊事件控制塊(ECB)的結(jié)構(gòu)OSEventType的值說(shuō)明OS_EVENT_TYPE_SEM信號(hào)量事件_MUTEX互斥型信號(hào)量_MBOX消息郵箱事件_Q消息隊(duì)列事件_UNUSED未用(空)ECBOSEventType取值含義OSEventTypeOSEventCntOSEventPtrOSEventGrp1/0peventOSEventTbl[]任務(wù)等待表222023/7/244.1任務(wù)間的同步和事件控制塊空事件控制塊(ECB)鏈表uC/OS-II初始化(OSInit())時(shí),按OS_CFG.H中OS_MAX_EVENTS定義的系統(tǒng)事件總數(shù)創(chuàng)建該鏈表。使用中應(yīng)用系統(tǒng)每創(chuàng)建一個(gè)事件,都會(huì)從此鏈表中申請(qǐng)一個(gè)空ECB,并填寫(xiě)相關(guān)成員初值;刪除一個(gè)事件時(shí),會(huì)將相應(yīng)事件的ECB歸還該鏈表。232023/7/244.1任務(wù)間的同步和事件控制塊事件控制塊(ECB)操作函數(shù)uC/OS-II有三類(lèi)事件(信號(hào)量---Sem/互斥信號(hào)量---Mutex、消息郵箱---Mbox、消息隊(duì)列---Q)。uC/OS-II中對(duì)每種事件提供5個(gè)基本操作函數(shù),供用戶管理事件。這些系統(tǒng)函數(shù)定義在相應(yīng)的“事件”文件中。OSxxxCreate()----創(chuàng)建事件;OSxxxPost()----發(fā)送事件;OSxxxPend()----請(qǐng)求事件;OSxxxDel()----刪除事件;OSxxxQuery()----查看事件;備注:其中xxx
為事件名(Sem、Mutex、Mbox、Q)242023/7/24第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作252023/7/244.2信號(hào)量及其操作信號(hào)量(Sem)1、信號(hào)量事件的數(shù)據(jù)成員OSEventType=OS_EVENT_TYPE_SEM,OSEventPtr=Null2、有任務(wù)申請(qǐng)某信號(hào)量時(shí),if(TheECB->OSEventCnt>0)then{OSEventCnt--;TheTaskGoon;}else{SettheTaskatWAIT_STATE;}3、有任務(wù)發(fā)送某信號(hào)量時(shí),if(noTaskWaittingtheSEM)then{TheECB->OSEventCnt++;}else{SettheH_Prio_TASkatREADY;
OS_Sched();}262023/7/244.2信號(hào)量及其操作信號(hào)量的操作----創(chuàng)建信號(hào)量信號(hào)量操作系統(tǒng)函數(shù)定義在OS_SEM.C文件。在使用信號(hào)量之前,必須創(chuàng)建信號(hào)量。創(chuàng)建信號(hào)量系統(tǒng)函數(shù)的原型:OS_EVENT*OSSemCreate( INT16Ucnt //信號(hào)量計(jì)數(shù)初值
)功能:從OSEventFreeList中申請(qǐng)一個(gè)ECB,并進(jìn)行初始化(用cnt初始化ECB(Sem)->OSEventCnt);返回一個(gè)已初始化的ECB的指針。272023/7/24……OS_EVENT*UART_Flag;//聲明事件指針變量INT8Uerr; //聲明全局狀態(tài)變量……voidmain(void){
OSInit();
UART_Flag=OSSemCreate(1);
//創(chuàng)建信號(hào)量
OSTaskCreate(Task_A,……);//創(chuàng)建任務(wù)A
OSTaskCreate(Task_B,……);//創(chuàng)建任務(wù)B
OSStart();}信號(hào)量的應(yīng)用舉例1-----主函數(shù)部分282023/7/244.2信號(hào)量及其操作信號(hào)量的操作----發(fā)送信號(hào)量發(fā)送信號(hào)量也稱(chēng)為釋放信號(hào)量。釋放信號(hào)量系統(tǒng)函數(shù)的原型:INT8UOSSemPost( OS_EVENT*pevent //信號(hào)量指針指示釋放目標(biāo)
)操作:檢查是否還有等待該信號(hào)量的任務(wù),若有則OS_Sched()調(diào)度優(yōu)先級(jí)最高的任務(wù)運(yùn)行,否則OSEventCnt++;函數(shù)返回值解釋?zhuān)孩貽S_NO_ERR釋放成功;②OS_ERR_EVENT_TYPE釋放的不是信號(hào)量事件;③OS_SEM_OVF信號(hào)量(個(gè)數(shù)<65535)溢出;292023/7/24voidTask_A(void*pdata){……;for(;;) //任務(wù)體A{OSSemPend(UART_Flag,0,&err);
//請(qǐng)求信號(hào)量UART_FlagFunction(UART); //使用信號(hào)量UART_Flag
OSSemPost(UART_Flag);
//發(fā)送信號(hào)量UART_FlagOSTimeDly(nnnn); //Task_A延時(shí)nnnn個(gè)時(shí)鐘節(jié)拍
}}信號(hào)量的應(yīng)用舉例1-----任務(wù)部分voidTask_B(void*pdata){……;for(;;) //任務(wù)體B{OSSemPend(UART_Flag,0,&err);
//請(qǐng)求信號(hào)量UART_FlagFunction(UART); //使用信號(hào)量UART_Flag
OSSemPost(UART_Flag);
//發(fā)送信號(hào)量UART_FlagOSTimeDly(mmm); //Task_B延時(shí)mmm個(gè)時(shí)鐘節(jié)拍
}}302023/7/244.2信號(hào)量及其操作信號(hào)量的操作----請(qǐng)求信號(hào)量請(qǐng)求信號(hào)量系統(tǒng)函數(shù)的原型:voidOSSemPend( OS_EVENT*pevent,//信號(hào)量指針指示申請(qǐng)目標(biāo)
INT16Utimeout, //等待限時(shí),OSTick數(shù)
INT8U*err); //函數(shù)執(zhí)行情況備注:①參數(shù)timeout用于約定本任務(wù)等待申請(qǐng)信號(hào)量的時(shí)限,單位是Tick;當(dāng)?shù)却瑫r(shí)時(shí),本任務(wù)被uC/OS-II直接轉(zhuǎn)入就續(xù)狀態(tài)。當(dāng)該參數(shù)為0時(shí),含義為無(wú)限時(shí)等待。②通過(guò)查閱*err參數(shù)可知函數(shù)的執(zhí)行情況。操作:如果信號(hào)量有效(ECB(Sem)->OSEventCnt>0),則OSEventCnt--,本任務(wù)goon;否則,將申請(qǐng)的事件的ECB->OSEventGrp及OSEventTbl[]相應(yīng)位置1,本Task轉(zhuǎn)入Wait狀態(tài)并執(zhí)行OS_Sched()。312023/7/244.2信號(hào)量及其操作信號(hào)量的操作----請(qǐng)求信號(hào)量請(qǐng)求信號(hào)量系統(tǒng)函數(shù)的原型:voidOSSemPend( OS_EVENT*pevent, //信號(hào)量指針指示申請(qǐng)目標(biāo)
INT16Utimeout, //等待限時(shí)
INT8U*err); //函數(shù)執(zhí)行情況函數(shù)返回值解釋?zhuān)孩貽S_NO_ERR信號(hào)量申請(qǐng)成功;②OS_ERR_EVENT_TYPE申請(qǐng)的不是信號(hào)量事件;③OS_ERR_EVENT_NULL申請(qǐng)的信號(hào)量不存在;④OS_ERR_PEND_ISR不能在ISR中申請(qǐng)信號(hào)量;
⑤
OS_TIMEOUT申請(qǐng)信號(hào)量超時(shí)退出;322023/7/24voidTask_A(void*pdata){……;for(;;) //任務(wù)體A{OSSemPend(UART_Flag,0,&err);//請(qǐng)求信號(hào)量UART_FlagFunction(UART); //使用信號(hào)量UART_Flag
OSSemPost(UART_Flag); //發(fā)送信號(hào)量UART_FlagOSTimeDly(nnnn); //Task_A延時(shí)nnnn個(gè)時(shí)鐘節(jié)拍
}}信號(hào)量的應(yīng)用舉例1-----任務(wù)部分voidTask_B(void*pdata){……;for(;;) //任務(wù)體B{OSSemPend(UART_Flag,0,&err);//請(qǐng)求信號(hào)量UART_FlagFunction(UART); //使用信號(hào)量UART_Flag
OSSemPost(UART_Flag); //發(fā)送信號(hào)量UART_FlagOSTimeDly(mmm); //Task_B延時(shí)mmm個(gè)時(shí)鐘節(jié)拍
}}332023/7/244.2信號(hào)量及其操作信號(hào)量的操作----無(wú)等待請(qǐng)求信號(hào)量無(wú)等待請(qǐng)求信號(hào)量系統(tǒng)函數(shù)的原型:INT16UOSSemAccept( OS_EVENT*pevent, //信號(hào)量指針指示申請(qǐng)目標(biāo)
);該函數(shù)無(wú)等待地申請(qǐng)指定的信號(hào)量。函數(shù)返回值解釋?zhuān)孩?gt;0信號(hào)量申請(qǐng)成功;②0信號(hào)量申請(qǐng)不成功;342023/7/244.2信號(hào)量及其操作信號(hào)量的操作----刪除信號(hào)量刪除信號(hào)量系統(tǒng)函數(shù)的原型:OS_EVENT*OSSemDel( OS_EVENT*pevent, //信號(hào)量指針指示刪除目標(biāo)
INT8Uopt, //刪除條件、方式
INT8U*err); //函數(shù)執(zhí)行情況備注:(信號(hào)量不能在ISR中刪除)1、刪除系統(tǒng)不再使用的信號(hào)量,歸還事件資源;2、參數(shù)opt用于約定刪除信號(hào)量的條件,其可有兩個(gè)取值:OS_DEL_NO_PEND----若事件無(wú)等待任務(wù)時(shí),刪除該事件且*err=OS_NO_ERR;否則直接返回,且*err=OS_ERR_TASK_WAITING;OS_DEL_ALLWAYS----直接刪除,且*err=OS_NO_ERR
;錯(cuò)誤的
opt參數(shù)時(shí),*err=OS_ERR_INVALID_OPT;352023/7/244.2信號(hào)量及其操作信號(hào)量的操作----查詢信號(hào)量的狀態(tài)查詢信號(hào)量系統(tǒng)函數(shù)的原型:INT8UOSSemQuery( OS_EVENT*pevent, //信號(hào)量指針指示申請(qǐng)目標(biāo)
OS_SEM_DATA*pdata); //信號(hào)量查詢結(jié)果數(shù)據(jù)結(jié)構(gòu)指針Typedefstruct{ INT16UOSCnt; INT8UOSEventTbl[OS_EVENT_TBL_SIZE]; INT8UOSEventGrp; }OS_SEM_DATA;備注:(該數(shù)據(jù)類(lèi)型在uCOS_II.H文件中定義)①OS_NO_ERR信號(hào)量查詢成功;②在使用該函數(shù)前要先定義一個(gè)OS_SEM_DATA類(lèi)型的變量;362023/7/244.2信號(hào)量及其操作信號(hào)量的應(yīng)用舉例1某系統(tǒng)中有Task_A、Task_B兩個(gè)任務(wù)都要使用公共資源(例如UART),他們可以分別使用,但不能同時(shí)使用??捎眯盘?hào)量的方法解決此問(wèn)題。372023/7/24……OS_EVENT*UART_Flag;//聲明事件指針變量INT8Uerr; //聲明全局狀態(tài)變量……voidmain(void){OSInit();UART_Flag=OSSemCreate(1);//創(chuàng)建信號(hào)量
OSTaskCreate(Task_A,……);//創(chuàng)建任務(wù)AOSTaskCreate(Task_B,……);//創(chuàng)建任務(wù)BOSStart();}信號(hào)量的應(yīng)用舉例1-----主函數(shù)部分382023/7/24voidTask_A(void*pdata){……;for(;;) //任務(wù)體A{OSSemPend(UART_Flag,0,&err);//請(qǐng)求信號(hào)量UART_FlagFunction(UART); //使用信號(hào)量UART_Flag
OSSemPost(UART_Flag); //發(fā)送信號(hào)量UART_FlagOSTimeDly(nnnn); //Task_A延時(shí)nnnn個(gè)時(shí)鐘節(jié)拍
}}信號(hào)量的應(yīng)用舉例1-----任務(wù)部分voidTask_B(void*pdata){……;for(;;) //任務(wù)體B{OSSemPend(UART_Flag,0,&err);//請(qǐng)求信號(hào)量UART_FlagFunction(UART); //使用信號(hào)量UART_Flag
OSSemPost(UART_Flag); //發(fā)送信號(hào)量UART_FlagOSTimeDly(mmm); //Task_B延時(shí)mmm個(gè)時(shí)鐘節(jié)拍
}}392023/7/244.2信號(hào)量及其操作信號(hào)量的應(yīng)用舉例2某系統(tǒng)中有Task_A、Task_B兩個(gè)任務(wù),若想執(zhí)行Task_B,必須首先經(jīng)過(guò)Task_A??捎眯盘?hào)量的方法,將Task_B作為T(mén)ask_A的后續(xù)功能,解決此問(wèn)題。402023/7/24……OS_EVENT*Task_Flag;//聲明信號(hào)量……voidmain(void){OSInit();
Task_Flag=OSSemCreate(0);//創(chuàng)建信號(hào)量
OSTaskCreate(Task_A,……);//創(chuàng)建任務(wù)AOSTaskCreate(Task_B,……);//創(chuàng)建任務(wù)BOSStart();}信號(hào)量的應(yīng)用舉例2-----主函數(shù)部分412023/7/24voidTask_A(void*pdata){……;for(;;) //任務(wù)體A{OSSemPost(Task_Flag);//發(fā)送信號(hào)量Task_Flag…… ; //Task_A業(yè)務(wù)功能代碼
OSTimeDly(nnnn); //Task_A延時(shí)nnnn個(gè)時(shí)鐘節(jié)拍
}}信號(hào)量的應(yīng)用舉例2-----任務(wù)部分voidTask_B(void*pdata){……;for(;;) //任務(wù)體B{OSSemPend(Task_Flag,0,&err);//請(qǐng)求信號(hào)量Task_Flag……;
//Task_B業(yè)務(wù)功能代碼
/*OSTimeDly(mmm); //Task_B延時(shí)mmm個(gè)時(shí)鐘節(jié)拍*/}}備注:Task_B一直等待Task_A而運(yùn)行。422023/7/24第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作432023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)所謂的互斥型信號(hào)量是一個(gè)二值信號(hào)量,簡(jiǎn)稱(chēng)為“信號(hào)”,它是一種特殊的信號(hào)量,主要用于處理任務(wù)對(duì)共享資源獨(dú)占問(wèn)題。使用互斥型信號(hào)量時(shí)要注意任務(wù)優(yōu)先級(jí)反轉(zhuǎn)的問(wèn)題。442023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)任務(wù)優(yōu)先級(jí)的反轉(zhuǎn)現(xiàn)象是指在剝奪式OS中,當(dāng)任務(wù)以獨(dú)占方式使用共享資源時(shí),低優(yōu)先級(jí)的任務(wù)可能先于高優(yōu)先級(jí)任務(wù)得到系統(tǒng)調(diào)度而運(yùn)行的現(xiàn)象。452023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)任務(wù)優(yōu)先級(jí)的反轉(zhuǎn)現(xiàn)象分析造成的結(jié)果:Task_B優(yōu)先于Task_A得到運(yùn)行。問(wèn)題的嚴(yán)重性:如果Task_B之類(lèi)的任務(wù)較多時(shí),甚至?xí)绊懴到y(tǒng)的設(shè)計(jì)目標(biāo)。原因:低優(yōu)先級(jí)的任務(wù)獨(dú)占共享資源,迫使高優(yōu)先級(jí)任務(wù)因等待資源而讓出CPU。解決辦法:暫時(shí)提升獲得共享資源任務(wù)的優(yōu)先級(jí)別,盡快釋放共享資源,之后再恢復(fù)其原有的優(yōu)先級(jí)別。備注:決定任務(wù)得到運(yùn)行的條件不僅僅是優(yōu)先級(jí),還有任務(wù)所需的資源。462023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)互斥型信號(hào)量(Mutex)互斥型信號(hào)量是一個(gè)二值信號(hào)量,是一種處理“任務(wù)優(yōu)先級(jí)反轉(zhuǎn)”現(xiàn)象的特殊信號(hào)量,主要用于處理任務(wù)對(duì)共享資源獨(dú)占問(wèn)題。為此,“事件”數(shù)據(jù)結(jié)構(gòu)上有一些特約:將OSEventCnt拆為了高8位(prio事件優(yōu)先級(jí))和低8位(資源標(biāo)志)兩個(gè)成員。472023/7/244.1任務(wù)間的同步和事件控制塊---(臨時(shí)參考)事件控制塊(ECB)uC/OS-II使用ECB的數(shù)據(jù)結(jié)構(gòu)統(tǒng)一描述三類(lèi)事件(信號(hào)量、消息郵箱、消息隊(duì)列)。uC/OS-II中的ECB數(shù)據(jù)結(jié)構(gòu)如下:typedefstruct{INT8UOSEventType; //事件類(lèi)型
INT16U
OSEventCnt;
//計(jì)數(shù)信號(hào)量的計(jì)數(shù)器
void*OSEventPtr; //消息(消息隊(duì)列)指針
INT8UOSEventGrp; //等待事件的任務(wù)組
INT8UOSEventTbl[OS_EVENT_TBL_SIZE];//任務(wù)等待表}OS_EVENT;482023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)創(chuàng)建互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexCreate()創(chuàng)建互斥型信號(hào)量,其原型如下:OS_EVENT*OSMutexCreate( INT8Uprio, //信號(hào)量?jī)?yōu)先級(jí)別
INT8U*err //函數(shù)結(jié)果狀態(tài)信息
);函數(shù)操作說(shuō)明:①該函數(shù)從空事件控制塊隊(duì)列(OSEventFreeList)獲得一個(gè)ECB,并將其初始化(初始化后的數(shù)據(jù)情況見(jiàn)前頁(yè)插圖);②用戶查看*err可知道本函數(shù)的執(zhí)行結(jié)果(OS_NO_ERR);③用戶通過(guò)本函數(shù)返回的事件指針來(lái)使用該“信號(hào)”。492023/7/244.2信號(hào)量及其操作----(臨時(shí)參考)信號(hào)量的操作----創(chuàng)建信號(hào)量信號(hào)量操作系統(tǒng)函數(shù)定義在OS_SEM.C文件。在使用信號(hào)量之前,必須創(chuàng)建信號(hào)量。創(chuàng)建信號(hào)量系統(tǒng)函數(shù)的原型:OS_EVENT*OSSemCreate( INT16Ucnt //信號(hào)量計(jì)數(shù)初值
)功能:從OSEventFreeList中申請(qǐng)一個(gè)ECB,并進(jìn)行初始化(用cnt初始化ECB(Sem)->OSEventCnt);返回一個(gè)已初始化的ECB的指針。502023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)創(chuàng)建互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexCreate()創(chuàng)建互斥型信號(hào)量注意事項(xiàng):1、不支持在ISR中創(chuàng)建互斥信號(hào)量;否則,創(chuàng)建失敗且返回出錯(cuò)信息*err=OS_ERR_CREATE_ISR2、指定的互斥信號(hào)量?jī)?yōu)先級(jí)不能與其它任務(wù)沖突;否則,創(chuàng)建失敗且返回出錯(cuò)信息*err=OS_PRIO_EXIST3、指定的優(yōu)先級(jí)要合法,否則,創(chuàng)建失敗且返回出錯(cuò)信息*err=OS_PRIO_INVALID4、如果信號(hào)量創(chuàng)建失敗,創(chuàng)建函數(shù)返回事件的指針為空(即=Null)5、正確創(chuàng)建了互斥信號(hào)量,函數(shù)返回一個(gè)ECB指針,且*err=OS_NO_ERR512023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)請(qǐng)求互斥型信號(hào)量當(dāng)任務(wù)要訪問(wèn)一個(gè)獨(dú)占共享資源時(shí),要先調(diào)用系統(tǒng)函數(shù)OSMutexPend()函數(shù)申請(qǐng)相應(yīng)的互斥信號(hào)量;其原型如下:voidOSMutexPend( OS_EVENT*pevent, //信號(hào)量指針
INT16Utimeout, //等待時(shí)間
INT8U*err //函數(shù)結(jié)果狀態(tài)信息
);522023/7/244.2信號(hào)量及其操作----(臨時(shí)參考)信號(hào)量的操作----請(qǐng)求信號(hào)量請(qǐng)求信號(hào)量系統(tǒng)函數(shù)的原型:voidOSSemPend( OS_EVENT*pevent,//信號(hào)量指針指示申請(qǐng)目標(biāo)
INT16Utimeout, //等待限時(shí),OSTick數(shù)
INT8U*err); //函數(shù)執(zhí)行情況備注:①參數(shù)timeout用于約定本任務(wù)等待申請(qǐng)信號(hào)量的時(shí)限,單位是Tick;當(dāng)?shù)却瑫r(shí)時(shí),本任務(wù)被uC/OS-II直接轉(zhuǎn)入就續(xù)狀態(tài)。當(dāng)該參數(shù)為0時(shí),含義為無(wú)限時(shí)等待。②通過(guò)查閱*err參數(shù)可知函數(shù)的執(zhí)行情況。操作:如果信號(hào)量有效(ECB(Sem)->OSEventCnt>0),則OSEventCnt--,本任務(wù)goon;否則,將申請(qǐng)的事件的ECB->OSEventGrp及OSEventTbl[]相應(yīng)位置1,本Task轉(zhuǎn)入Wait狀態(tài)并執(zhí)行OS_Sched()。532023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)請(qǐng)求互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexPend()申請(qǐng)互斥型信號(hào)量注意事項(xiàng):1、不支持在ISR中申請(qǐng)互斥信號(hào)量;否則,申請(qǐng)失敗且返回出錯(cuò)信息*err=OS_ERR_PEND_ISR2、申請(qǐng)的互斥信號(hào)量必須存在;否則,申請(qǐng)失敗且返回出錯(cuò)信息*err=OS_ERR_PEVENT_NULL3、指定的事件要是互斥信號(hào)量,否則,申請(qǐng)失敗且返回出錯(cuò)信息*err=OS_ERR_EVENT_TYPE4、申請(qǐng)到了互斥信號(hào)量,*err=OS_NO_ERR5、如果信號(hào)量未申請(qǐng)到,本任務(wù)則進(jìn)入“等待”狀態(tài)。542023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)發(fā)送互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexPost()發(fā)送(釋放)互斥型信號(hào)量,其原型如下:INT8UOSMutexPost( OS_EVENT*pevent //信號(hào)量指針
);552023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)發(fā)送互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexPost()釋放互斥型信號(hào)量注意事項(xiàng):1、不支持在ISR中釋放互斥信號(hào)量;否則釋放失敗且函數(shù)返回OS_ERR_POST_ISR2、釋放的互斥信號(hào)量必須存在;否則釋放失敗且函數(shù)返回OS_ERR_PEVENT_NULL3、釋放的事件要是互斥信號(hào)量,否則釋放失敗且函數(shù)返回OS_ERR_EVENT_TYPE4、只能釋放自己的信號(hào),否則釋放失敗且函數(shù)返回OS_ERR_NOT_MUTEX_OWNER5、正確釋放了互斥信號(hào)量,函數(shù)返回OS_NO_ERR562023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)刪除互斥型信號(hào)量可以調(diào)用系統(tǒng)函數(shù)OSMutexDel()函數(shù)刪除不再使用的互斥信號(hào)量;其原型如下:OS_EVENT*OSMutexDel( OS_EVENT*pevent, //信號(hào)量指針
INT8Uopt, //刪除方式選項(xiàng)
INT8U*err //函數(shù)結(jié)果狀態(tài)信息
);備注:函數(shù)返回刪除事件的“事件指針”;當(dāng)刪除一個(gè)不存在的事件時(shí),返回Null。572023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)刪除互斥型信號(hào)量系統(tǒng)函數(shù)OSMutexDel()刪除互斥型信號(hào)量注意事項(xiàng):1、opt參數(shù)含義:2、返回信息*err的含義:OS_NO_ERRMutex刪除成功;OS_ERR_DEL_ISR不允許在ISR中進(jìn)行刪除OS_ERR_INVALID_OPT刪除方式參數(shù)非法OS_ERR_TASK_WAITING還有等待該信號(hào)的任務(wù)OS_ERR_EVENT_TYPE指定的事件不是MutexOS_ERR_PEVENT_NULL事件指針為空了OS_DEL_NO_PEND-----無(wú)申請(qǐng)等待任務(wù)時(shí)方刪除。OS_DEL_ALWAYS-----無(wú)條件直接刪除,所有的等待任務(wù)皆轉(zhuǎn) 入到ready狀態(tài)。582023/7/244.3互斥型信號(hào)量無(wú)等待請(qǐng)求操作互斥信號(hào)量----無(wú)等待請(qǐng)求操作無(wú)等待請(qǐng)求互斥信號(hào)量系統(tǒng)函數(shù)的原型:INT16UOSMutexAccept( OS_EVENT*pevent, //信號(hào)量指針指示申請(qǐng)目標(biāo)
INT8U*err );該函數(shù)無(wú)等待地申請(qǐng)指定的互斥信號(hào)量。函數(shù)返回值解釋?zhuān)孩?=1信號(hào)量申請(qǐng)成功;②==0信號(hào)量申請(qǐng)不成功;592023/7/244.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)互斥型信號(hào)量應(yīng)用舉例某系統(tǒng)中有Task_A、Task_B兩個(gè)任務(wù)都要使用公共資源(例如UART),他們可以分別使用,但不能同時(shí)使用;Task_A、Task_B兩任務(wù)的優(yōu)先級(jí)之間還存在許多中間優(yōu)先級(jí)的任務(wù);例如:Prio(Task_A)=3,Prio(Task_B)=20,優(yōu)先級(jí)在[3,20]之間還存在5個(gè)任務(wù)Task_1,Task_2,……,Task_5,有可能引起優(yōu)先級(jí)反轉(zhuǎn)。使用互斥信號(hào)量的方法解決此問(wèn)題。602023/7/24……OS_EVENT*UART_Flag;//聲明信號(hào)量INT8Uerr; //聲明全局狀態(tài)變量……voidmain(void){OSInit();UART_Flag=OSMutexCreate(2,&err);//創(chuàng)建互斥信號(hào)量
OSTaskCreate(Task_A,……,3);//創(chuàng)建任務(wù)AOSTaskCreate(Task_B,……,20);//創(chuàng)建任務(wù)BOSTaskCreate(Task_1,……,6);
……OSTaskCreate(Task_5,……,18);OSStart();}互斥信號(hào)量的應(yīng)用舉例-----主函數(shù)部分612023/7/24voidTask_A(void*pdata){……;for(;;) //任務(wù)體A{OSMutexPend(UART_Flag,0,&err);//請(qǐng)求信號(hào)量UART_Flag
Function(UART); //使用信號(hào)量UART_Flag
OSMutexPost(UART_Flag);//發(fā)送信號(hào)量UART_Flag
OSTimeDly(nnnn); //Task_A
延時(shí)nnnn
個(gè)時(shí)鐘節(jié)拍
}}互斥信號(hào)量的應(yīng)用舉例-----任務(wù)部分voidTask_B(void*pdata){……;for(;;) //任務(wù)體B{OSMutexPend(UART_Flag,0,&err);//請(qǐng)求信號(hào)量UART_Flag
Function(UART); //使用信號(hào)量UART_Flag
OSMutexPost(UART_Flag);//發(fā)送信號(hào)量UART_Flag
OSTimeDly(mmm); //Task_B
延時(shí)mmm
個(gè)時(shí)鐘節(jié)拍
}}622023/7/24第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作632023/7/24程序間(任務(wù)間)及與ISR間的數(shù)據(jù)通信問(wèn)題函數(shù)調(diào)用時(shí)的參數(shù)傳遞----只適合于函數(shù)調(diào)用場(chǎng)合;全局變量----可以適用在函數(shù)調(diào)用場(chǎng)合,也可應(yīng)用在“任務(wù)”之間數(shù)據(jù)傳遞;但其只能進(jìn)行數(shù)據(jù)傳送,不具有“任務(wù)同步控制”功能!郵箱事件----多任務(wù)OS中任務(wù)間的參數(shù)傳遞!不但要能在任務(wù)間傳送數(shù)據(jù),還要能在任務(wù)間同步控制!642023/7/244.4消息郵箱及其操作消息郵箱(Mbox)
它的主要功能就是用于在任務(wù)間傳遞一組數(shù)據(jù);還要為操作系統(tǒng)管理事件和任務(wù)提供一些參數(shù)(任務(wù)同步控制)。結(jié)構(gòu)如下:消息郵箱使用傳遞變量指針的手段在任務(wù)之間進(jìn)行通信。這個(gè)ECB稱(chēng)之為----消息郵箱652023/7/244.4消息郵箱及其操作消息郵箱的操作----創(chuàng)建消息郵箱可以調(diào)用系統(tǒng)函數(shù)OSMboxCreate()函數(shù)創(chuàng)建消息郵箱;其原型如下:OS_EVENT*OSMboxCreate( void*msg //消息指針
);備注:1、形參msg
是一個(gè)要在任務(wù)間傳遞的變量指針;2、當(dāng)創(chuàng)建消息郵箱成功時(shí),返回消息郵箱指針;3、消息郵箱創(chuàng)建失敗時(shí),返回一個(gè)Null。662023/7/244.4消息郵箱及其操作消息郵箱的操作----向消息郵箱發(fā)送消息可以調(diào)用系統(tǒng)函數(shù)OSMboxPost()函數(shù)向消息郵箱發(fā)送消息;其原型如下:INT8UOSMboxPost( OS_EVENT*pevent, //消息郵箱指針
void*msg //消息指針
);備注:1、形參msg
是一個(gè)要在任務(wù)間傳遞的變量指針;2、形參pevent
是消息郵箱指針;672023/7/244.4消息郵箱及其操作消息郵箱的操作----向消息郵箱發(fā)送消息向消息郵箱發(fā)送消息系統(tǒng)函數(shù)OSMboxPost()返回值含義:1、OS_NO_ERR----消息發(fā)送成功;2、OS_MBOX_FULL----不能向滿郵箱在發(fā)送消息;3、OS_ERR_EVENT_TYPE----指定的事件不是消息郵箱類(lèi)型;4、OS_ERR_PEVENT_NULL----不能向不存在的消息郵箱發(fā)送消息;5、OS_ERR_POST_NULL_PTR----消息緩沖區(qū)不能為空;682023/7/244.4消息郵箱及其操作消息郵箱的操作----請(qǐng)求消息郵箱void*OSMboxPend( OS_EVENT*pevent, //消息郵箱指針
INT16Utimeout, //等待時(shí)限
INT8U*err //函數(shù)執(zhí)行信息
);所謂的“請(qǐng)求消息郵箱”就是等待一個(gè)消息傳送到消息郵箱,或取得一個(gè)消息數(shù)據(jù)。請(qǐng)求消息郵箱函數(shù)原型:當(dāng)返回值!=Null時(shí),返回值就是一個(gè)預(yù)期消息的指針;當(dāng)返回值=Null時(shí),意味著未得到消息,此時(shí)uC/OS-II執(zhí)行OS_Sched();可能消息未準(zhǔn)備好,或指示的事件出錯(cuò)、超時(shí)等,此時(shí)函數(shù)直接返回,用戶應(yīng)查閱*err的狀態(tài)。692023/7/244.4消息郵箱及其操作消息郵箱的操作----請(qǐng)求消息郵箱err是本函數(shù)執(zhí)行狀態(tài)的返回值,*err的值含義:OS_NO_ERR----請(qǐng)求成功,得到目標(biāo)數(shù)據(jù);OS_TIMEOUT----超時(shí),未得到目標(biāo)數(shù)據(jù);OS_ERR_EVENT_TYPE----無(wú)效的事件類(lèi)型;OS_ERR_PEND_ISR----不支持ISR中的消息郵箱請(qǐng)求;OS_ERR_PEVENT_NULL----指定的事件為空(不存在);702023/7/244.4消息郵箱及其操作消息郵箱的操作----刪除消息郵箱對(duì)一個(gè)不再使用的消息郵箱要及時(shí)刪除以釋放資源。其函數(shù)原型為:函數(shù)參數(shù)說(shuō)明:1、opt==OS_DEL_NO_PEND如果沒(méi)有等待任務(wù)時(shí)刪除郵箱;2、opt==OS_DEL_ALWAYS
無(wú)條件刪除又向,所有等待該事件的任務(wù)急轉(zhuǎn)到就緒狀態(tài);OS_EVENT*OSMboxDel( OS_EVENT*pevent, //消息郵箱指針
INT8Uopt, //刪除方式選項(xiàng)
INT8U*err //函數(shù)執(zhí)行信息
);712023/7/244.4消息郵箱及其操作消息郵箱的操作----刪除消息郵箱err是本函數(shù)執(zhí)行狀態(tài)的返回值,*err的值含義:OS_NO_ERR----函數(shù)成功,指定的郵箱被刪除;OS_INVALID_OPT----刪除方式數(shù)據(jù)錯(cuò);OS_ERR_EVENT_TYPE----欲刪除的事件類(lèi)型不是郵箱;OS_ERR_DEL_ISR----不支持ISR中的消息郵箱刪除操作;OS_ERR_PEVENT_NULL----指定的事件為空(不存在);OS_ERR_TASK_WAITING----郵箱中還有等待任務(wù);722023/7/244.4消息郵箱及其操作消息郵箱的操作----查詢消息郵箱(略)732023/7/244.4消息郵箱及其操作消息郵箱的應(yīng)用舉例某應(yīng)用系統(tǒng)含有“數(shù)據(jù)采集”任務(wù)Task_A
和“數(shù)據(jù)處理”任務(wù)Task_B
;Task_A
周期性的定時(shí)采集數(shù)據(jù),用消息郵箱的方式將數(shù)據(jù)傳送到Task_B處理。742023/7/24消息郵箱的應(yīng)用舉例INT16Uzql_data; //存放AD轉(zhuǎn)換后的數(shù)據(jù)OS_EVENT*Dt_box; //消息郵箱指針voidmain(void){
OSInit();
Dt_box=OSMboxCreate(void*0);//創(chuàng)建(空)消息郵箱
OSTaskCreate(Task_A,…); //創(chuàng)建Task_A
OSTaskCreate(Task_B,…); //創(chuàng)建Task_B
OSStart();}752023/7/24消息郵箱的應(yīng)用舉例voidTask_A(void*pdata) //采集數(shù)據(jù)任務(wù){(diào)for(;;)
{……; //啟動(dòng)A/D轉(zhuǎn)換
zql_data=GetAD(); //得到一次轉(zhuǎn)換數(shù)據(jù)
OSMboxPost(Dt_box,&zql_data); //將zql_data數(shù)據(jù)發(fā)送到消息郵箱
OSTimeDlyHMSM(0,0,1,0) //定時(shí)1秒
}}voidTask_B(void*pdata) //處理數(shù)據(jù)任務(wù){(diào)INT16U*data_B;for(;;){……; //其他業(yè)務(wù)
data_B=OSMboxPend(Dt_box,0,&err);//等待從Dt_box郵箱中取得數(shù)據(jù)
……; //處理data_B數(shù)據(jù)
}}762023/7/24第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作4.5消息隊(duì)列及其操作消息隊(duì)列(Q)----結(jié)構(gòu)消息隊(duì)列是uC/OS-II中的一種事件,用于任務(wù)或ISR向其他任務(wù)傳送多條數(shù)據(jù);消息隊(duì)列由4部分組成:ECB、OS_Q(隊(duì)列控制塊)、void*Msg
Tbl[]、Message。(隊(duì)列控制塊)(消息指針數(shù)組)(事件控制塊)782023/7/244.5消息隊(duì)列及其操作消息隊(duì)列----隊(duì)列控制塊(OS_Q)結(jié)構(gòu)消息隊(duì)列相當(dāng)于共用一個(gè)等待任務(wù)列表的消息郵箱數(shù)組。結(jié)構(gòu)核心增加了“隊(duì)列控制塊”(OS_Q),它是一個(gè)數(shù)據(jù)結(jié)構(gòu),用于描述和控制消息指針數(shù)組,結(jié)構(gòu)定義如下(7個(gè)成員):typedef
struct
os_q
{struct
os_q*OSQPtr;
/*空OS_Q表中的“鏈項(xiàng)”,僅用于空OS_Q鏈表管理*/void**OSQStart;/*消息指針數(shù)組的起始指針*/void**OSQEnd;/*消息指針數(shù)組的結(jié)束指針*/void**OSQIn;/*新消息指針插入隊(duì)列的指針---隊(duì)列使用中可變化*/void**OSQOut;/*待讀出消息指針的指針---隊(duì)列使用中可變化*/INT16UOSQSize;/*隊(duì)列長(zhǎng)度(最多可緩沖的消息數(shù))*/INT16UOSQEntries;/*隊(duì)列中當(dāng)前的消息數(shù)---隊(duì)列使用中可變化*/}OS_Q;/*隊(duì)列控制塊*/792023/7/244.5消息隊(duì)列及其操作消息隊(duì)列----隊(duì)列控制塊(OS_Q)消息隊(duì)列相當(dāng)于共用一個(gè)等待任務(wù)列表的消息郵箱數(shù)組。結(jié)構(gòu)核心增加了“隊(duì)列控制塊”(OS_Q),其各成員(7個(gè))參數(shù)含義:參數(shù)說(shuō)明OSQPtr僅用于在OSQFreeList中OS_Q的鏈接管理;OSQStart指向用戶預(yù)定義的指針數(shù)組的指針;(靜態(tài))OSQSize用戶預(yù)定義的指針數(shù)組的長(zhǎng)度;<=65535OSQOut下一個(gè)被取出消息的“消息指針”(的指針);(動(dòng)態(tài))OSQIn(隊(duì)列)
一條新消息指針的插入位置(指針);(動(dòng)態(tài))OSQEnd消息隊(duì)列數(shù)組結(jié)束單元的next單元指針;(靜態(tài))OSQEntries消息隊(duì)列中當(dāng)前的消息個(gè)數(shù);{0,1,…,OSQSize}802023/7/244.5消息隊(duì)列及其操作消息隊(duì)列----空白隊(duì)列控制塊鏈表(OSQFreeList)備注:①
OSQ_FreeList
是系統(tǒng)變量,它是個(gè)指針,uCOS
固定的 從其指向獲得OS_Q;②OS_MAX_QS是OS_CFG.H中配置。812023/7/244.5消息隊(duì)列及其操作消息隊(duì)列----消息指針數(shù)組(void*MsgTbl[])消息指針數(shù)組
----物理結(jié)構(gòu)上僅僅是個(gè)數(shù)組,在OS_Q的控制下可以表現(xiàn)為FIFO(隊(duì)列)或LIFO(堆棧)兩種形式。消息隊(duì)列表現(xiàn)為FIFO方式時(shí),OSQIn是隊(duì)列的寫(xiě)入端,OSQOut是隊(duì)列的讀出端;表現(xiàn)為L(zhǎng)IFO方式時(shí),OSQOut既是隊(duì)列的寫(xiě)入端,也是隊(duì)列的讀出端;消息隊(duì)列以何種方式(FIFO/LIFO)表現(xiàn)是通過(guò)不同的系統(tǒng)函數(shù)實(shí)現(xiàn)的;822023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----創(chuàng)建消息隊(duì)列創(chuàng)建消息隊(duì)列:1、首先定義一個(gè)“消息隊(duì)列”(Q)中使用的消息指針數(shù)組;2、使系統(tǒng)函數(shù)(OSQCreate)創(chuàng)建消息隊(duì)列事件;OS_EVENT*OSQCreate(void
**start,INT16Usize)創(chuàng)建消息隊(duì)列系統(tǒng)函數(shù)原型:832023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----創(chuàng)建消息隊(duì)列OS_EVENT*OSQCreate(void**start,INT16Usize)參數(shù)說(shuō)明:**start是消息指針數(shù)組的地址指針;size是消息指針數(shù)組的長(zhǎng)度。消息指針數(shù)組必須聲明為void指針數(shù)據(jù)類(lèi)型?!璒S_EVENT*My_Q;void*MyMsgPtr[MSIZE];……My_Q=OSQCreate(&MyMsgPtr[0],MSIZE);……消息隊(duì)列創(chuàng)建方法:隊(duì)列創(chuàng)建系統(tǒng)函數(shù)流程852023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----消息隊(duì)列后創(chuàng)建的數(shù)據(jù)結(jié)構(gòu):OS_EVENT*OSQCreate(void**start,INT16Usize)862023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----向消息隊(duì)列發(fā)送消息有兩種向消息隊(duì)列發(fā)送消息的方法;OSQPost()---從OSQIn指向位置向Q發(fā)送消息,實(shí)現(xiàn)一個(gè)FIFO型的消息隊(duì)列;OSQPostFront()---從OSQOut指向位置向Q發(fā)送消息,實(shí)現(xiàn)一個(gè)LIFO型的消息隊(duì)列;這兩個(gè)系統(tǒng)函數(shù)原型分別為:INT8UOSQPost(OS_EVENT*pevent,void*msg)INT8U
OSQPostFront
(OS_EVENT*pevent,void*msg)參數(shù)說(shuō)明:pevent----Q事件指針;msg----傳遞的消息指針872023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----向消息隊(duì)列發(fā)送消息INT8UOSQPost(OS_EVENT*pevent,void*msg)INT8UOSQPostFront(OS_EVENT*pevent,void*msg)OS_NO_ERR----函數(shù)正確執(zhí)行,消息傳送成功;OS_Q_FULL----消息指針數(shù)組已滿,本次傳送不成功;OS_ERR_EVENT_TYPE----事件指針指定的必須是一個(gè)Q事件;OS_ERR_PEVENT_NULL----事件指針不能為Null;OS_ERR_POST_NULL_PTR----不允許謊傳消息(msg==(void*)0)兩個(gè)向消息隊(duì)列發(fā)送消息的系統(tǒng)函數(shù),其返回值及其含義:882023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----向消息隊(duì)列發(fā)送消息舉例main(void){……;OS_EVENT*My_Q; //聲明一個(gè)事件
void*MyMsgPtr[MSIZE]; //聲明一個(gè)指針數(shù)祖
……;
My_Q=OSQCreate(&MyMsgPtr[0],MSIZE);//創(chuàng)建隊(duì)列事件My_Q……;}voidTask_A(void*pdata
){INT16Umsg;
msg=Get_AD(void); //準(zhǔn)備好一個(gè)消息數(shù)據(jù)msg
OSQPost(My_Q,&msg
); //向My_Q
隊(duì)列發(fā)送msg
消息
……;}892023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----向隊(duì)列發(fā)送消息后的數(shù)據(jù)結(jié)構(gòu):902023/7/244.5消息隊(duì)列及其操作消息隊(duì)列的操作----增強(qiáng)型的向消息隊(duì)列發(fā)送消息
INT8UOSQPostOpt(OS_EVENT*pevent,void*msg,INT8Uopt)opt==OS_POST_OPT_NONE
時(shí)
----相當(dāng)于OSQPost()
;opt==OS_POST_OPT_FRONT
時(shí)----相當(dāng)于OSQPost
溫馨提示
- 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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 智能化系統(tǒng)安裝工程合同書(shū)
- 水利水電工程勞務(wù)承包合同
- 土地使用權(quán)征收補(bǔ)償合同協(xié)議
- 影視劇本供應(yīng)與購(gòu)買(mǎi)合同書(shū)版
- 規(guī)范化離婚合同文本范文
- 采購(gòu)合同簡(jiǎn)版-鋼材專(zhuān)項(xiàng)
- 婦科培訓(xùn)課件模板
- 小學(xué)生唱音階課件圖片
- 公證員網(wǎng)絡(luò)知識(shí)產(chǎn)權(quán)考核試卷
- 墨水制備實(shí)驗(yàn)室建設(shè)與管理考核試卷
- 2024年南京城市職業(yè)學(xué)院?jiǎn)握新殬I(yè)技能測(cè)試題庫(kù)及答案解析
- 醫(yī)療安全不良事件課件
- 部編版小學(xué)語(yǔ)文二年級(jí)下冊(cè)第三單元集體備課教材分析
- 珠寶專(zhuān)業(yè)知識(shí)課件
- 先天性腎上腺皮質(zhì)增生癥
- 2024年保密法培訓(xùn)課件
- 凈菜加工技術(shù)通則
- 懷念戰(zhàn)友混聲四部合唱簡(jiǎn)譜
- 城市軌道交通通信信號(hào)系統(tǒng)-綜合練習(xí)題含答案
- 安全生產(chǎn)投訴與舉報(bào)處理培訓(xùn)
- 20以內(nèi)退位減法口算練習(xí)題100題30套(共3000題)
評(píng)論
0/150
提交評(píng)論