μCOS-Ⅱ嵌入式操作系統(tǒng)及開發(fā)課件-4_第1頁
μCOS-Ⅱ嵌入式操作系統(tǒng)及開發(fā)課件-4_第2頁
μCOS-Ⅱ嵌入式操作系統(tǒng)及開發(fā)課件-4_第3頁
μCOS-Ⅱ嵌入式操作系統(tǒng)及開發(fā)課件-4_第4頁
μCOS-Ⅱ嵌入式操作系統(tǒng)及開發(fā)課件-4_第5頁
已閱讀5頁,還剩101頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

12024/3/29嵌入式操作系統(tǒng)及開發(fā)2024/3/292第4章任務(wù)的

同步與通信32024/3/29第4章任務(wù)的同步與通信一個(gè)應(yīng)用系統(tǒng)通常是由多個(gè)任務(wù)組成,任務(wù)之間互相協(xié)作共同完成目標(biāo)功能。例如任務(wù)對(duì)共享資源競爭,先采集數(shù)據(jù)才能處理數(shù)據(jù)等情況?!踩蝿?wù)的同步控制,共享資源的競爭,任務(wù)間的通信等問題的解決方案---OS〕任務(wù)間的同步----任務(wù)間的制約性的合作運(yùn)行機(jī)制。系統(tǒng)各任務(wù)之間通過“任務(wù)通信”的方式,實(shí)現(xiàn)任務(wù)的信息傳遞和同步控制,“任務(wù)通信”的載體就是----事件。常用的事件:信號(hào)量〔計(jì)數(shù)型---SEM/互斥型---MUTEX〕、消息郵箱(MBOX)、消息隊(duì)列(Q)、事件標(biāo)志組等。事件用“事件控制塊”〔ECB〕來描述。42024/3/29第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作52024/3/29第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作62024/3/294.1任務(wù)間的同步和事件控制塊任務(wù)間的同步---各任務(wù)運(yùn)行的先后、觸發(fā)等關(guān)系備注:數(shù)據(jù)采集任務(wù)A和數(shù)據(jù)處理任務(wù)B之間存在同步關(guān)系。72024/3/294.1任務(wù)間的同步和事件控制塊任務(wù)間的互斥

---共享資源的申請(qǐng)使用備注:數(shù)據(jù)采集任務(wù)A和數(shù)據(jù)處理任務(wù)B之間存在互斥關(guān)系。82024/3/294.1任務(wù)間的同步和事件控制塊任務(wù)之間的這種相互制約、相互合作的運(yùn)行機(jī)制稱為“任務(wù)間的同步”系統(tǒng)中任務(wù)之間相互傳遞事件,來實(shí)現(xiàn)任務(wù)的同步、協(xié)作。備注:用戶自定義全局變量的方法,也可以編程實(shí)現(xiàn)程序間的信息傳遞。但如果想將信息傳遞的各項(xiàng)功能作完備,工作量是比較大的。況且,這類需求在應(yīng)用系統(tǒng)設(shè)計(jì)中是很常用的。uC/OS-II中將此類工作以系統(tǒng)功能方式提供與用戶----事件操作。92024/3/29舉例:任務(wù)間的共享資源競爭問題及處理方式。某一分布式系統(tǒng),需要主設(shè)備〔M_Dev〕使用同一個(gè)UART資源分別與從設(shè)備1〔S_Dev1〕和從設(shè)備2〔S_Dev2〕以不同的“串行通信模式”進(jìn)行通信。102024/3/29voidmain(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);}}說明:如此設(shè)計(jì)未對(duì)共享資源作任何約束,實(shí)際運(yùn)行中可能發(fā)生Task_A與Task_B沖突競爭。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ù)處理〕說明:通過用戶定義全局變量uart_key對(duì)任務(wù)使用共享資源作約束,可以防止Task_A與Task_B沖突競爭,但其管理性能支持較弱。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ù)處理〕說明:Task_A數(shù)據(jù)采集任務(wù),Task_B數(shù)據(jù)處理任務(wù);通過用戶定義全局指針變量msg_ptr對(duì)(采集、處理數(shù)據(jù))任務(wù)作約束,可以協(xié)調(diào)Task_A與Task_B,但其管理性能支持較弱。132024/3/294.1任務(wù)間的同步和事件控制塊事件漢語中所謂的“事件”,是指一個(gè)事情的發(fā)生。在uC/OS-II中將信號(hào)量、消息郵箱和消息隊(duì)列的一個(gè)存在稱為一個(gè)事件,事件操作:創(chuàng)立、發(fā)送、請(qǐng)求和刪除等?!瞮C/OS的原作者將“事件---EVENT”理解為靜態(tài)的數(shù)據(jù)結(jié)構(gòu)?!嘲l(fā)送事件----向信號(hào)量、消息郵箱和消息隊(duì)列的一次信息發(fā)送〔寫---Post〕操作。請(qǐng)求事件----對(duì)信號(hào)量、消息郵箱和消息隊(duì)列的一次查詢〔讀---Pend〕操作。uC/OS-II中以系統(tǒng)函數(shù)的方式向任務(wù)提供事件操作。142024/3/294.1任務(wù)間的同步和事件控制塊事件〔1〕----信號(hào)量〔Sem/Mutex〕兩類信號(hào)量:互斥信號(hào)量---Mutex、計(jì)數(shù)型信號(hào)量---Sem;互斥信號(hào)量是一個(gè)二值信號(hào)量,主要用于“獨(dú)占式共享資源”的管理〔例如:打印機(jī)〕。計(jì)數(shù)型信號(hào)量用以“多個(gè)同類型資源”的管理,通常用一個(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ù)處理〕說明:通過用戶定義全局變量uart_key對(duì)任務(wù)使用共享資源作約束,可以防止Task_A與Task_B沖突競爭,但其管理性能支持較弱。162024/3/294.1任務(wù)間的同步和事件控制塊事件〔2〕----消息郵箱〔Mbox〕用于解決任務(wù)間的數(shù)據(jù)傳送問題。在多任務(wù)OS中采用消息傳送的方式實(shí)現(xiàn)任務(wù)間的“單批次數(shù)據(jù)”通信,這個(gè)數(shù)據(jù)稱為“消息”。例如:Task_A采集一個(gè)數(shù)據(jù),Task_B要使用Task_A采集的數(shù)據(jù)。原理:在內(nèi)存中創(chuàng)立數(shù)據(jù)傳送緩沖區(qū)〔消息緩沖區(qū)〕,通過傳送該緩沖區(qū)的地址指針傳遞數(shù)據(jù)。這個(gè)緩沖區(qū)指針的數(shù)據(jù)結(jié)構(gòu)稱為“消息郵箱”。172024/3/294.1任務(wù)間的同步和事件控制塊事件〔2〕----消息郵箱〔Mbox〕182024/3/294.1任務(wù)間的同步和事件控制塊事件〔3〕----消息隊(duì)列〔Q〕用于解決任務(wù)間的“多個(gè)數(shù)據(jù)”傳送問題。在多任務(wù)OS中,采用“指針數(shù)組”的方式進(jìn)行多數(shù)據(jù)的傳送。這個(gè)指向“指針數(shù)組”的指針+“指針數(shù)組”+消息緩沖區(qū)所構(gòu)成的數(shù)據(jù)結(jié)構(gòu)稱為“消息隊(duì)列”。192024/3/294.1任務(wù)間的同步和事件控制塊等待任務(wù)列表當(dāng)一個(gè)“事件”被占用時(shí),其它請(qǐng)求該事件的任務(wù)暫時(shí)得不到事件的效勞,處于等待狀態(tài)。OS使用《等待任務(wù)表》管理“事件”;即使用《等待任務(wù)表》對(duì)那些等待該事件的各個(gè)任務(wù)進(jìn)行管理〔記錄等待該事件的任務(wù)并排序,任務(wù)等待事件有限時(shí)等〕。每個(gè)事件都有一個(gè)“等待任務(wù)表”,用于完成事件對(duì)任務(wù)的驅(qū)動(dòng)、限時(shí)等管理,其原理類似于任務(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)。202024/3/294.1任務(wù)間的同步和事件控制塊事件控制塊〔ECB〕uC/OS-II使用ECB的數(shù)據(jù)結(jié)構(gòu)統(tǒng)一描述三類事件〔信號(hào)量、消息郵箱、消息隊(duì)列〕。uC/OS-II中的ECB數(shù)據(jù)結(jié)構(gòu)如下:typedefstruct{INT8UOSEventType; //事件類型INT16UOSEventCnt; //計(jì)數(shù)信號(hào)量的計(jì)數(shù)器void*OSEventPtr; //消息〔消息隊(duì)列〕指針I(yè)NT8UOSEventGrp; //等待事件的任務(wù)組INT8UOSEventTbl[OS_EVENT_TBL_SIZE];//任務(wù)等待表}OS_EVENT;212024/3/294.1任務(wù)間的同步和事件控制塊事件控制塊〔ECB〕的結(jié)構(gòu)OSEventType的值說明OS_EVENT_TYPE_SEM信號(hào)量事件_MUTEX互斥型信號(hào)量_MBOX消息郵箱事件_Q消息隊(duì)列事件_UNUSED未用(空)ECBOSEventType取值含義OSEventTypeOSEventCntOSEventPtrOSEventGrp1/0peventOSEventTbl[]任務(wù)等待表222024/3/294.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,并填寫相關(guān)成員初值;刪除一個(gè)事件時(shí),會(huì)將相應(yīng)事件的ECB歸還該鏈表。232024/3/294.1任務(wù)間的同步和事件控制塊事件控制塊〔ECB〕操作函數(shù)uC/OS-II有三類事件〔信號(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〕242024/3/29第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作252024/3/294.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();}262024/3/294.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的指針。272024/3/29……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ù)局部282024/3/294.2信號(hào)量及其操作信號(hào)量的操作----發(fā)送信號(hào)量發(fā)送信號(hào)量也稱為釋放信號(hào)量。釋放信號(hào)量系統(tǒng)函數(shù)的原型:INT8UOSSemPost( OS_EVENT*pevent //信號(hào)量指針指示釋放目標(biāo)

)操作:檢查是否還有等待該信號(hào)量的任務(wù),假設(shè)有那么OS_Sched()調(diào)度優(yōu)先級(jí)最高的任務(wù)運(yùn)行,否那么OSEventCnt++;函數(shù)返回值解釋:①OS_NO_ERR釋放成功;②OS_ERR_EVENT_TYPE釋放的不是信號(hào)量事件;③OS_SEM_OVF信號(hào)量〔個(gè)數(shù)<65535〕溢出;292024/3/29voidTask_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é)拍

}}302024/3/294.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í),含義為無限時(shí)等待。②通過查閱*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()。312024/3/294.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ù)返回值解釋:①OS_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í)退出;322024/3/29voidTask_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é)拍

}}332024/3/294.2信號(hào)量及其操作信號(hào)量的操作----無等待請(qǐng)求信號(hào)量無等待請(qǐng)求信號(hào)量系統(tǒng)函數(shù)的原型:INT16UOSSemAccept( OS_EVENT*pevent, //信號(hào)量指針指示申請(qǐng)目標(biāo)

);該函數(shù)無等待地申請(qǐng)指定的信號(hào)量。函數(shù)返回值解釋:①>0信號(hào)量申請(qǐng)成功;②0信號(hào)量申請(qǐng)不成功;342024/3/294.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----假設(shè)事件無等待任務(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;352024/3/294.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ù)類型在uCOS_II.H文件中定義〕①OS_NO_ERR信號(hào)量查詢成功;②在使用該函數(shù)前要先定義一個(gè)OS_SEM_DATA類型的變量;362024/3/294.2信號(hào)量及其操作信號(hào)量的應(yīng)用舉例1某系統(tǒng)中有Task_A、Task_B兩個(gè)任務(wù)都要使用公共資源〔例如UART〕,他們可以分別使用,但不能同時(shí)使用??捎眯盘?hào)量的方法解決此問題。372024/3/29……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ù)局部382024/3/29voidTask_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é)拍

}}392024/3/294.2信號(hào)量及其操作信號(hào)量的應(yīng)用舉例2某系統(tǒng)中有Task_A、Task_B兩個(gè)任務(wù),假設(shè)想執(zhí)行Task_B,必須首先經(jīng)過Task_A??捎眯盘?hào)量的方法,將Task_B作為Task_A的后續(xù)功能,解決此問題。402024/3/29……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ù)局部412024/3/29voidTask_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)行。422024/3/29第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作432024/3/294.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)所謂的互斥型信號(hào)量是一個(gè)二值信號(hào)量,簡稱為“信號(hào)”,它是一種特殊的信號(hào)量,主要用于處理任務(wù)對(duì)共享資源獨(dú)占問題。使用互斥型信號(hào)量時(shí)要注意任務(wù)優(yōu)先級(jí)反轉(zhuǎn)的問題。442024/3/294.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)象。452024/3/294.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)行。問題的嚴(yán)重性:如果Task_B之類的任務(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ù)所需的資源。462024/3/294.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ú)占問題。為此,“事件”數(shù)據(jù)結(jié)構(gòu)上有一些特約:將OSEventCnt拆為了高8位〔prio事件優(yōu)先級(jí)〕和低8位〔資源標(biāo)志〕兩個(gè)成員。472024/3/294.1任務(wù)間的同步和事件控制塊---〔臨時(shí)參考〕事件控制塊〔ECB〕uC/OS-II使用ECB的數(shù)據(jù)結(jié)構(gòu)統(tǒng)一描述三類事件〔信號(hào)量、消息郵箱、消息隊(duì)列〕。uC/OS-II中的ECB數(shù)據(jù)結(jié)構(gòu)如下:typedefstruct{INT8UOSEventType; //事件類型INT16UOSEventCnt; //計(jì)數(shù)信號(hào)量的計(jì)數(shù)器void*OSEventPtr; //消息〔消息隊(duì)列〕指針I(yè)NT8UOSEventGrp; //等待事件的任務(wù)組INT8UOSEventTbl[OS_EVENT_TBL_SIZE];//任務(wù)等待表}OS_EVENT;482024/3/294.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)量優(yōu)先級(jí)別

INT8U*err //函數(shù)結(jié)果狀態(tài)信息

);函數(shù)操作說明:①該函數(shù)從空事件控制塊隊(duì)列〔OSEventFreeList〕獲得一個(gè)ECB,并將其初始化〔初始化后的數(shù)據(jù)情況見前頁插圖〕;②用戶查看*err可知道本函數(shù)的執(zhí)行結(jié)果〔OS_NO_ERR〕;③用戶通過本函數(shù)返回的事件指針來使用該“信號(hào)”。492024/3/294.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的指針。502024/3/294.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)創(chuàng)立互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexCreate()創(chuàng)立互斥型信號(hào)量本卷須知:1、不支持在ISR中創(chuàng)立互斥信號(hào)量;否那么,創(chuàng)立失敗且返回出錯(cuò)信息*err=OS_ERR_CREATE_ISR2、指定的互斥信號(hào)量優(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_ERR512024/3/294.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)請(qǐng)求互斥型信號(hào)量當(dāng)任務(wù)要訪問一個(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)信息

);522024/3/294.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í),含義為無限時(shí)等待。②通過查閱*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()。532024/3/294.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)請(qǐng)求互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexPend()申請(qǐng)互斥型信號(hào)量本卷須知: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)。542024/3/294.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)量指針

);552024/3/294.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)發(fā)送互斥型信號(hào)量調(diào)用系統(tǒng)函數(shù)OSMutexPost()釋放互斥型信號(hào)量本卷須知: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_ERR562024/3/294.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。572024/3/294.3互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)刪除互斥型信號(hào)量系統(tǒng)函數(shù)OSMutexDel()刪除互斥型信號(hào)量本卷須知: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-----無申請(qǐng)等待任務(wù)時(shí)方刪除。OS_DEL_ALWAYS-----無條件直接刪除,所有的等待任務(wù)皆轉(zhuǎn) 入到ready狀態(tài)。582024/3/294.3互斥型信號(hào)量無等待請(qǐng)求操作互斥信號(hào)量----無等待請(qǐng)求操作無等待請(qǐng)求互斥信號(hào)量系統(tǒng)函數(shù)的原型:INT16UOSMutexAccept( OS_EVENT*pevent, //信號(hào)量指針指示申請(qǐng)目標(biāo)

INT8U*err );該函數(shù)無等待地申請(qǐng)指定的互斥信號(hào)量。函數(shù)返回值解釋:①==1信號(hào)量申請(qǐng)成功;②==0信號(hào)量申請(qǐng)不成功;592024/3/294.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)量的方法解決此問題。602024/3/29……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ù)局部612024/3/29voidTask_A(void*pdata){……;for(;;) //任務(wù)體A{OSMutexPend(UART_Flag,0,&err);//請(qǐng)求信號(hào)量UART_FlagFunction(UART); //使用信號(hào)量UART_Flag

OSMutexPost(UART_Flag);//發(fā)送信號(hào)量UART_FlagOSTimeDly(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_FlagFunction(UART); //使用信號(hào)量UART_Flag

OSMutexPost(UART_Flag);//發(fā)送信號(hào)量UART_FlagOSTimeDly(mmm); //Task_B延時(shí)mmm個(gè)時(shí)鐘節(jié)拍

}}622024/3/29第4章目錄1、任務(wù)間的同步和事件控制塊2、信號(hào)量及其操作3、互斥型信號(hào)量和任務(wù)優(yōu)先級(jí)反轉(zhuǎn)4、消息郵箱及其操作5、消息隊(duì)列及其操作632024/3/29程序間〔任務(wù)間〕及與ISR間的數(shù)據(jù)通信問題函數(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ù)間同步控制!642024/3/294.4消息郵箱及其操作消息郵箱〔Mbox〕它的主要功能就是用于在任務(wù)間傳遞一組數(shù)據(jù);還要為操作系統(tǒng)管理事件和任務(wù)提供一些參數(shù)〔任務(wù)同步控制〕。結(jié)構(gòu)如下:消息郵箱使用傳遞變量指針的手段在任務(wù)之間進(jìn)行通信。這個(gè)ECB稱之為----消息郵箱652024/3/294.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。662024/3/294.4消息郵箱及其操作消息郵箱的操作----向消息郵箱發(fā)送消息可以調(diào)用系統(tǒng)函數(shù)OSMboxPost()函數(shù)向消息郵箱發(fā)送消息;其原型如下:INT8UOSMboxPost( OS_EVENT*pevent, //消息郵箱指針

void*msg //消息指針

);備注:1、形參msg是一個(gè)要在任務(wù)間傳遞的變量指針;2、形參pevent是消息郵箱指針;672024/3/294.4消息郵箱及其操作消息郵箱的操作----向消息郵箱發(fā)送消息向消息郵箱發(fā)送消息系統(tǒng)函數(shù)OSMboxPost()返回值含義:1、OS_NO_ERR----消息發(fā)送成功;2、OS_MBOX_FULL----不能向滿郵箱在發(fā)送消息;3、OS_ERR_EVENT_TYPE----指定的事件不是消息郵箱類型;4、OS_ERR_PEVENT_NULL----不能向不存在的消息郵箱發(fā)送消息;5、OS_ERR_POST_NULL_PTR----消息緩沖區(qū)不能為空;682024/3/294.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)。692024/3/294.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----無效的事件類型;OS_ERR_PEND_ISR----不支持ISR中的消息郵箱請(qǐng)求;OS_ERR_PEVENT_NULL----指定的事件為空〔不存在〕;702024/3/294.4消息郵箱及其操作消息郵箱的操作----刪除消息郵箱對(duì)一個(gè)不再使用的消息郵箱要及時(shí)刪除以釋放資源。其函數(shù)原型為:函數(shù)參數(shù)說明:1、opt==OS_DEL_NO_PEND如果沒有等待任務(wù)時(shí)刪除郵箱;2、opt==OS_DEL_ALWAYS

無條件刪除又向,所有等待該事件的任務(wù)急轉(zhuǎn)到就緒狀態(tài);OS_EVENT*OSMboxDel( OS_EVENT*pevent, //消息郵箱指針

INT8Uopt, //刪除方式選項(xiàng)

INT8U*err //函數(shù)執(zhí)行信息

);712024/3/294.4消息郵箱及其操作消息郵箱的操作----刪除消息郵箱err是本函數(shù)執(zhí)行狀態(tài)的返回值,*err的值含義:OS_NO_ERR----函數(shù)成功,指定的郵箱被刪除;OS_INVALID_OPT----刪除方式數(shù)據(jù)錯(cuò);OS_ERR_EVENT_TYPE----欲刪除的事件類型不是郵箱;OS_ERR_DEL_ISR----不支持ISR中的消息郵箱刪除操作;OS_ERR_PEVENT_NULL----指定的事件為空〔不存在〕;OS_ERR_TASK_WAITING----郵箱中還有等待任務(wù);722024/3/294.4消息郵箱及其操作消息郵箱的操作----查詢消息郵箱〔略〕732024/3/294.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處理。742024/3/29消息郵箱的應(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_AOSTaskCreate(Task_B,…); //創(chuàng)立Task_BOSStart();}752024/3/29消息郵箱的應(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ù)

}}762024/3/29第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*MsgTbl[]、Message。〔隊(duì)列控制塊〕〔消息指針數(shù)組〕〔事件控制塊〕782024/3/294.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è)成員〕:typedefstructos_q{structos_q*OSQPtr;/*空OS_Q表中的“鏈項(xiàng)”,僅用于空OS_Q鏈表管理*/void**OSQStart;/*消息指針數(shù)組的起始指針*/void**OSQEnd;/*消息指針數(shù)組的結(jié)束指針*/void**OSQIn;/*新消息指針插入隊(duì)列的指針---隊(duì)列使用中可變化*/void**OSQOut;/*待讀出消息指針的指針---隊(duì)列使用中可變化*/INT16UOSQSize;/*隊(duì)列長度〔最多可緩沖的消息數(shù)〕*/INT16UOSQEntries;/*隊(duì)列中當(dāng)前的消息數(shù)---隊(duì)列使用中可變化*/}OS_Q;/*隊(duì)列控制塊*/792024/3/294.5消息隊(duì)列及其操作消息隊(duì)列----隊(duì)列控制塊〔OS_Q〕消息隊(duì)列相當(dāng)于共用一個(gè)等待任務(wù)列表的消息郵箱數(shù)組。結(jié)構(gòu)核心增加了“隊(duì)列控制塊”〔OS_Q〕,其各成員〔7個(gè)〕參數(shù)含義:參數(shù)說明OSQPtr僅用于在OSQFreeList中OS_Q的鏈接管理;OSQStart指向用戶預(yù)定義的指針數(shù)組的指針;(靜態(tài))OSQSize用戶預(yù)定義的指針數(shù)組的長度;<=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}802024/3/294.5消息隊(duì)列及其操作消息隊(duì)列----空白隊(duì)列控制塊鏈表〔OSQFreeList〕備注:①

OSQ_FreeList是系統(tǒng)變量,它是個(gè)指針,uCOS固定的 從其指向獲得OS_Q;②OS_MAX_QS是OS_CFG.H中配置。812024/3/294.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ì)列的寫入端,OSQOut是隊(duì)列的讀出端;表現(xiàn)為LIFO方式時(shí),OSQOut既是隊(duì)列的寫入端,也是隊(duì)列的讀出端;消息隊(duì)列以何種方式〔FIFO/LIFO〕表現(xiàn)是通過不同的系統(tǒng)函數(shù)實(shí)現(xiàn)的;822024/3/294.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ù)原型:832024/3/294.5消息隊(duì)列及其操作消息隊(duì)列的操作----創(chuàng)立消息隊(duì)列OS_EVENT*OSQCreate(void**start,INT16Usize)參數(shù)說明:**start是消息指針數(shù)組的地址指針;size是消息指針數(shù)組的長度。消息指針數(shù)組必須聲明為void指針數(shù)據(jù)類型?!璒S_EVENT*My_Q;void*MyMsgPtr[MSIZE];……My_Q=OSQCreate(&MyMsgPtr[0],MSIZE);……消息隊(duì)列創(chuàng)立方法:隊(duì)列創(chuàng)立系統(tǒng)函數(shù)流程852024/3/294.5消息隊(duì)列及其操作消息隊(duì)列的操作----消息隊(duì)列后創(chuàng)立的數(shù)據(jù)結(jié)構(gòu):OS_EVENT*OSQCreate(void**start,INT16Usize)862024/3/294.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)INT8UOSQPostFront(OS_EVENT*pevent,void*msg)參數(shù)說明:pevent----Q事件指針;msg----傳遞的消息指針872024/3/294.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ù),其返回值及其含義:882024/3/294.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ù)msgOSQPost(My_Q,&msg); //向My_Q隊(duì)列發(fā)送msg消息……;}892024/3/294.5消息隊(duì)列及其操作消息隊(duì)列的操作----向隊(duì)列發(fā)送消息后的數(shù)據(jù)結(jié)構(gòu):902024/3/294.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)于OSQPostFront();opt==OS_POST_OPT_BROADCAST時(shí)----POSTtoALLtasksthatarewaitingonthequeue;identicaltoOSQPost()butwillbroadcast‘msg’toALLwaitingtasks;這個(gè)向消息隊(duì)列發(fā)送消息的系統(tǒng)函數(shù),功能上覆蓋了OSQPost()和OSQPostFront(),甚至還要強(qiáng):912024/3/294.5消息隊(duì)列及其操作消息隊(duì)列的操作----增強(qiáng)型的向消息隊(duì)列發(fā)送消息

INT8UOSQPostOpt(OS_EVENT*pevent,void*msg,INT8Uopt)OS_NO_ERR

----Thecallwassuccessfulandthemessagewassent;OS_Q_FULL---Thequeueitisfullandcannotacceptanymoremessages;OS_ERR_EVENT_TYPE

---

The'pevent'didn‘tapointertoaqueue;OS_ERR_PEVENT_NULL---If‘pevent’isaNULLpointer;OS_ERR_POST_NULL_PTR---TheOS_QisaNULLpointer;這個(gè)系統(tǒng)函數(shù)的INT8U返回值含義:922024/3/294.5消息隊(duì)列及其操作消息隊(duì)列的操作----請(qǐng)求消息隊(duì)列〔入/出口參數(shù)〕

用戶可以使用OSQPend()系統(tǒng)函數(shù)請(qǐng)求消息隊(duì)列,其目的是為了從消息隊(duì)列中獲取消息。該函數(shù)的原型如下:void*OSQPend(OS_EVENT*pevent,INT16Utimeout,INT8U*err)入口參數(shù)說明:pevent----Q事件指針;timeout----等待時(shí)間限制;err---

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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ǔ)空間,僅對(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)論