




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第七章任務(wù)間的同步與通訊消息郵箱什么是消息郵箱消息郵箱的數(shù)據(jù)結(jié)構(gòu)消息郵箱相關(guān)函數(shù)消息郵箱指針消息郵箱任務(wù)1任務(wù)2發(fā)送消息請求消息消息緩沖區(qū)(發(fā)送消息緩沖區(qū)指針)(讀取消息緩沖區(qū)指針)消息郵箱是一種通信機制,它能使任務(wù)或中斷服務(wù)向另一個任務(wù)發(fā)送一個指針型的變量,這個指針指向一個包含指定“消息”的數(shù)據(jù)結(jié)構(gòu)。消息郵箱發(fā)送的不是消息本身,而是消息的地址指針。
第七章任務(wù)間的同步與通訊消息郵箱什么是消息郵箱消息郵箱的數(shù)據(jù)結(jié)構(gòu)消息郵箱相關(guān)函數(shù)消息郵箱的數(shù)據(jù)結(jié)構(gòu)typedefstruct{INT8UOSEventType;/*事件類型*/INT8UOSEventGrp;/*等待任務(wù)所在的組*/INT16UOSEventCnt;
/*計數(shù)器(當(dāng)事件是信號量時)*/void*OSEventPtr;
/*指向消息或者消息隊列的指針*/INT8UOSEventTbl[OS_EVENT_TBL_SIZE];
/*等待任務(wù)列表*/}OS_EVENT;第七章任務(wù)間的同步與通訊消息郵箱什么是消息郵箱消息郵箱的數(shù)據(jù)結(jié)構(gòu)消息郵箱相關(guān)函數(shù)
消息郵箱函數(shù)一覽表消息郵箱函數(shù)所屬文件是OS_MBOX.COS_CFG.H文件中消息郵箱的配置常數(shù)一覽表任務(wù)、中斷服務(wù)子程序與消息郵箱之間的關(guān)系消息郵箱的操作OSMboxCreate()OSMboxDel()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxAccept()OSMboxQuery()建立一個郵箱,OSMboxCreate()函數(shù)OSMboxCreate()的原型如下:OS_EVENT*OSMboxCreate(void*msg);參數(shù):msg參數(shù)用來初始化建立的消息郵箱。如果該指針不為空,建立的消息郵箱將含有消息。返回值:指向分配給所建立的消息郵箱的事件控制塊的指針。如果沒有可用的事件控制塊,返回空指針。郵箱作用:通知一個消息(此時,msg為空)作為二值信號量范例OS_EVENT*RxMbox;
/*定義消息郵箱指針 */
voidmain(void){
.
OSInit();
RxMbox=OSMboxCreate((void*)0);
/*建立消息郵箱,初始值為空 */
OSStart();
/*啟動多任務(wù)內(nèi)核 */
}OSMboxCreate()函數(shù)返回前,事件控制塊的內(nèi)容郵箱特點消息郵箱的內(nèi)容是一個指向消息的指針,指針指向的內(nèi)容就是消息郵箱只能接收和發(fā)送一條消息,當(dāng)郵箱滿時,將丟棄新消息,保持舊消息當(dāng)郵箱為滿是,郵箱里存放指向消息的指針;當(dāng)郵箱為空時,郵箱指針為NULL消息郵箱的操作OSMboxCreate()OSMboxDel()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxAccept()OSMboxQuery()刪除消息郵箱——OSMboxDel()函數(shù)原型如下:
OS_EVENT*OSMboxDel(OS_EVENT*pevent,INT8Uopt,INT8U*err)
該函數(shù)用于刪除消息郵箱,所屬文件為OS_MBOX.C,調(diào)用者為任務(wù),開關(guān)量為OS_MBOX_EN和OS_MBOX_DEL_EN。參數(shù):
(1)?pevent:指向消息郵箱的指針,該指針是消息郵箱建立時,返回給應(yīng)用程序的指針。(2)?opt:用于定義消息郵箱刪除條件的選項??晒┻x擇的值如下:
①OS_DEL_NO_PEND:選擇只能是沒有任何任務(wù)在等待該消息郵箱的消息時,才能刪除消息郵箱。
②OS_DEL_ALWAYS:不管有沒有任務(wù)在等待消息郵箱的消息,都立即刪除消息郵箱。刪除后,所有等待消息郵箱消息的任務(wù)都立即進入就緒狀態(tài)。
(3)?err:指向出錯代碼的指針。
①?OS_NO_ERR:調(diào)用成功,表明郵箱已被刪除。②?OS_ERR_DEL_ISR:試圖在中斷服務(wù)子程序中刪除郵箱。
③?OS_ERR_INVALID_OPT:無效的opt參數(shù)。
④?OS_ERR_EVENT_TYPE:pevent不是指向郵箱的指針。
⑤?OS_ERR_PEVENT_NULL:沒有可以使用的OS_EVENT數(shù)據(jù)結(jié)構(gòu)返回值
OSMboxDel()函數(shù)的返回值為如下內(nèi)容之一:
(1)返回空指針NULL,表示消息郵箱已被刪除。
(2)返回pevent,表示消息郵箱沒有刪除,在這種情況下,應(yīng)該進一步查看出錯代碼,找到出錯原因。.范例。。。。OS_EVENT*RxMbox
/*定義消息郵箱指針 */
voidtask(void*pdata){
INT8U*err;
pdata=pdata;
for(;;){RxMbox=OSMboxDel(RxMbox,OS_DEL_ALWAYS,&err);
應(yīng)用程序;
}
}消息郵箱的操作OSMboxCreate()OSMboxDel()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxAccept()OSMboxQuery()等待郵箱中的消息,OSMboxPend()函數(shù)OSMboxPend()的原型如下:void*OSMboxPend(OS_EVNNT*pevent,INT16Utimeout,int8u*err);參數(shù):pevent:是指向即將接受消息的消息郵箱的指針。timeout:允許一個任務(wù)在經(jīng)過了指定數(shù)目的時鐘節(jié)拍后還沒有得到需要的消息時恢復(fù)運行。err:是指向包含錯誤碼的變量的指針。OSMboxPend()函數(shù)返回的錯誤碼可能為下述幾種:OS_NO_ERR:消息被正確的接收。OS_TIMEOUT:消息沒有在指定的周期數(shù)內(nèi)送到。OS_ERR_PEND_ISR:從中斷調(diào)用該函數(shù)。雖然規(guī)定了不允許從中斷調(diào)用該函數(shù),但μC/OS-Ⅱ仍然包含了檢測這種情況的功能。OS_ERR_EVENT_TYPE:pevent不是指向消息郵箱的指針。返回值:OSMboxPend()函數(shù)返回接收的消息并將*err置為OS_NO_ERR。如果沒有在指定數(shù)目的時鐘節(jié)拍內(nèi)接受到需要的消息,OSMboxPend()函數(shù)返回空指針并且將*err設(shè)置為OS_TIMEOUT。范例OS_EVENT*RxMbox;
/*定義消息郵箱指針 */
voidTask(void*pdata){
INT8Uerr;
void *msg;
pdata=pdata;
for(;;){
應(yīng)用程序代碼;
msg=OSMboxPend(RxMbox,10,&err);/*返回消息指針,據(jù)該指針可獲消息 */if(err==OS_NO_ERR){
消息正確接收的應(yīng)用程序代碼;
}else{
在指定時間內(nèi)沒有接收到消息的應(yīng)用程序代碼;
}
應(yīng)用程序代碼;
}
}等待消息說明消息郵箱已經(jīng)存在需要的消息,那么該消息被返回給OSMboxPend()的調(diào)用者,消息郵箱中清除該消息。如果調(diào)用OSMboxPend()函數(shù)時消息郵箱中沒有需要的消息,OSMboxPend()函數(shù)掛起當(dāng)前任務(wù)直到得到需要的消息或超出定義等待超時的時間。如果同時有多個任務(wù)等待同一個消息,μC/OS-Ⅱ默認最高優(yōu)先級的任務(wù)取得消息并且任務(wù)恢復(fù)執(zhí)行。一個由OSTaskSuspend()函數(shù)掛起的任務(wù)也可以接受消息,但這個任務(wù)將一直保持掛起狀態(tài)直到通過調(diào)用OSTaskResume()函數(shù)恢復(fù)任務(wù)的運行。消息郵箱的操作OSMboxCreate()OSMboxDel()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxAccept()OSMboxQuery()向郵箱發(fā)送一則消息,OSMboxPost()
函數(shù)OSMboxPost()的原型如下:INT8UOSMboxPost(OS_EVENT*pevent,void*msg);參數(shù):pevent:指向即將接受消息的消息郵箱的指針。該指針的值在建立該消息郵箱時可以得到。(參考OSMboxCreate()函數(shù))。msg:即將實際發(fā)送給任務(wù)的消息。消息是一個指針長度的變量,在不同的程序中消息的使用也可能不同。不允許傳遞一個空指針,因為這意味著消息郵箱為空。返回值:OS_NO_ERR:消息成功的放到消息郵箱中。OS_MBOX_FULL:消息郵箱已經(jīng)包含了其他消息,不空。OS_ERR_EVENT_TYPE:pevent不是指向消息郵箱的指針。調(diào)用者是任務(wù)或中斷,開關(guān)量是OS_MBOX_EN和OS_MBOX_POST_EN發(fā)送消息說明如果消息郵箱中已經(jīng)存在消息,返回錯誤碼說明消息郵箱已滿。如果有多個任務(wù)在等待消息郵箱的消息,最高優(yōu)先級的任務(wù)將得到這個消息。如果等待消息的任務(wù)優(yōu)先級比發(fā)送消息的任務(wù)優(yōu)先級高,那么高優(yōu)先級的任務(wù)將得到消息而恢復(fù)執(zhí)行,也就是說,發(fā)生了一次任務(wù)切換。消息郵箱的操作OSMboxCreate()OSMboxDel()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxAccept()OSMboxQuery()廣播發(fā)送消息到消息郵箱中—OSMboxPostOpt()
函數(shù)原型如下:
INT8UOSMboxPostOpt(OS_EVENT*pevent,void*msg,INT8Uopt)
OSMboxPostOpt()函數(shù)與OSMboxPost()函數(shù)比較兩者工作方式相同,都用指針傳遞消息;不同的是OSMboxPost()只能給一個任務(wù)發(fā)送消息,而OSMboxPostOpt()允許將消息廣播給所有的等待消息郵箱消息的任務(wù),且可以仿真OSMboxPost()。OSMboxPostOpt()函數(shù)的開關(guān)量是OS_MBOX_EN和OS_MBOX_POST_OPT_EN,調(diào)用者可以是任務(wù),也可以是中斷。在廣播方式下,函數(shù)的執(zhí)行時間取決于等待消息郵箱消息的任務(wù)數(shù)量。OSMboxpostOpt()函數(shù)有如下三個參數(shù):
(1)?pevent:指向即將接收消息的消息郵箱的指針。該指針的值可以在建立該消息郵箱時得到。
(2)?msg:即將發(fā)送給任務(wù)的消息。消息是以指針表示的某種數(shù)據(jù)類型的變量,消息的數(shù)據(jù)類型可能會因具體應(yīng)用的不同而有所差異。不允許傳遞空指針,因為這樣意味著消息郵箱為空。
(3)?opt:定義發(fā)送消息方式的選項。它有兩種形式:
①若opt=OS_POST_OPT_NONE,則定義消息只發(fā)給等待消息的任務(wù)中優(yōu)先級最高的任務(wù);
②若opt=OS_POST_OPT_BROADCAST,則讓所有等待郵箱消息的任務(wù)都得到消息。
返回值
(1)?OS_NO_ERR:調(diào)用成功,消息已經(jīng)發(fā)出。
(2)?OS_MBOX_FULL:郵箱中已經(jīng)有消息。
(3)?OS_ERR_EVENT_TYPE:pevent不是指向郵箱的指針。
(4)?OS_ERR_PEVENT_NULL:pevent是空指針。
(5)?OS_ERR_POST_NULL_PTR:試圖發(fā)送空指針。根據(jù)規(guī)則,空指針無效。消息郵箱的操作OSMboxCreate()OSMboxDel()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxAccept()OSMboxQuery()無等待地從郵箱中得到一則消息,OSMboxAccept()
OSMboxAccept()的函數(shù)原型如下:void*OSMboxAccept(OS_EVENT*pevent);參數(shù):pevent:是指向需要查看的消息郵箱的指針。返回值:如果消息已經(jīng)到達,返回指向該消息的指針;如果消息郵箱沒有消息,返回空指針。范例OS_EVENT*ComMbox;
voidTask(void*pdata)
{
void*msg;
pdata=pdata;
for(;;){
msg=OSMboxAccept(ComMbox);
/*檢查消息郵箱是否有消息 if(msg!=(void*)0){
處理消息;
}else{
處理無消息的情況;
}
.
}
}消息郵箱的操作OSMboxCreate()OSMboxDel()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxAccept()OSMboxQuery()查詢一個郵箱的狀態(tài),OSMboxQuery()
OSMboxQuery()的函數(shù)原型如下:INT8UOSMboxQuery(OS_EVENT*pevent,OS_MBOX_DATA*pdata);參數(shù):pevent:指向即將接收消息的消息郵箱的指針。pdata:指向OS_MBOX_DATA數(shù)據(jù)結(jié)構(gòu)的指針,該數(shù)據(jù)結(jié)構(gòu)包含下述成員:Void*OSMsg; /*消息郵箱中消息的復(fù)制*/INT8UOSEventTbl[OS_EVENT_TBL_SIZE]; /*消息郵箱等待隊列的復(fù)制*/INT8UOSEventGrp;返回值:OS_NO_ERR:調(diào)用成功。OS_ERR_EVENT_TYPE:pevent不是指向消息郵箱的指針。范例
OS_EVENT*RxMbox;
/*定義指針 /
voidTask(void*pdata){
OS_MBOXDATA cbox_data;
INT8U err;
pdata=pdata;
for(;;){err=OSMboxQuery(RxMbox,&cbox_data);
if(err==OS_NO_ERR){
./*如果cbox_data.OSMsg為非空指針,說明消息郵箱非空 */
}
.
}
}
舉例本例中有兩個任務(wù):MyTask和YouTask。任務(wù)YouTask要向任務(wù)MyTask發(fā)送消息/************************Test*****************************/#include“includes.h”#defineTASK_STK_SIZE512//任務(wù)堆棧長度OS_STKStartTaskStk[TASK_STK_SIZE];//定義任務(wù)堆棧區(qū)OS_STKMyTaskStk[TASK_STK_SIZE];//定義任務(wù)堆棧區(qū)OS_STKYouTaskStk[TASK_STK_SIZE];//定義任務(wù)堆棧區(qū)INT16Skey;//用于退出μc/os-II的鍵INT8Uy1=0,y2=0;//字符顯示位置
OS_EVENT*msg;
//消息郵箱voidStartTask(void*data);//聲明起始任務(wù)voidMyTask(void*data);//聲明任務(wù)voidYouTask(void*data);//聲明任務(wù)/********************主函數(shù)*******************/voidmain(void){OSInit();//初始化μc/os-IIPC_DOSSaveReturn();//保存DOS環(huán)境
PC_VectSet(uCOS,OSCtxSw);//安裝μc/os-II中斷msg=OSMboxCreate((void*)0);
OSTaskCreate(StartTask,//創(chuàng)建任務(wù)StartTask(void*)0,//給任務(wù)傳遞參數(shù)
&StartTaskStk[TASK_STK_SIZE-1],//設(shè)置任務(wù)堆棧棧頂指針
0);//使任務(wù)的優(yōu)先級別為0OSStart();//啟動多任務(wù)管理}/****************任務(wù)StartTask**********************/voidStartTask(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifpdata=pdata;OS_ENTER_CRITICAL();PC_VectSet(0x08,OSTickISR);//安裝時鐘中斷向量
PC_SetTickRate(OS_TICKS_PER_SEC);//設(shè)置μc/os-II時鐘頻率
OS_EXIT_CRITICAL();OSStatInit();//初始化統(tǒng)計任務(wù)
OSTaskCreate(MyTask,(void*)0,&MyTaskStk[TASK_STK_SIZE-1],
1);OSTaskCreate(YouTask,(void*)0,&YouTaskStk[TASK_STK_SIZE-1],
2);for(;;){//如果按下ESC鍵,則退出μc/os-IIif(PC_GetKey(&key)==TRUE){if(key==0x1B){PC_DOSReturn();}}OSTimeDlyHMSM(0,0,3,0);//等待3s}}/*****************任務(wù)MyTask***********************/voidMyTask(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifpdata=pdata;void*msg_My;INT8Uerr;for(;;){PC_DispStr(5,++y1,“MyTask”,DISP_BGND_BLACK+DISP_FGND_WHITE);
msg_My=OSMboxPend(msg,0,err);if(err==OS_NO_ERR){PC_DispStr(15,y1,msg_My,DISP_BGND_BLACK+DISP_FGND_WHITE);}OSTimeDlyHMSM(0,0,1,0);//等待1s}/***********************任務(wù)YouTask*******************/voidYouTask(void*pdata){#ifOS_CRITICAL_METHOD==3OS_CPU_SRcpu_sr;#endifchar*s=“YouTask發(fā)送的消息”;//定義消息INT8Uerr;
pdata=pdata;for(;;){PC_DispStr(40,++y2,“YouTask”,DISP_BGND_BLACK+DISP_FGND_WHITE);
err=OSMboxPost(msg,(void*)s);OSTimeDlyHMSM(0,0,2,0);//等待2s}}/********************************END***************************************/再看一個例子設(shè)計一個應(yīng)用程序,該程序有兩個任務(wù)MyTask和YouTask。在任務(wù)MyTask中用一個變量Times記錄任務(wù)MyTask的運行次數(shù),并將其作為消息用郵箱Str_Box發(fā)給任務(wù)YouTask且由任務(wù)YouTask顯示出來。/***********************Test*****************************/#include“includes.h”#defineTASK_STK_SIZE512//任務(wù)堆棧長度OS_STKStartTaskStk[TASK_STK_SIZE];//定義任務(wù)堆棧區(qū)OS_STKMyTaskStk[TASK_STK_SIZE];//定義任務(wù)堆棧區(qū)OS_STKYouTaskStk[TASK_STK_SIZE];//定義任務(wù)堆棧區(qū)INT16Skey;//用于退出的鍵char*s;char*ss;INT8Uerr;INT8Uy=0;//字符顯示位置INT32UTimes=0;OS_EVENT*Str_Box;
//定義事件控制塊指針voidStartTask(void*data);//聲明起始任務(wù)voidMyTask(void*data);//聲明任務(wù)voidYouTask(void*data);//聲明任務(wù)/*******************主函數(shù)****************************/voidmain(void){OSInit();//初始化μc/os-II……
Str_Box=OSMboxCreate((void*)0);
//創(chuàng)建消息郵箱OSTaskCreate(StartTask,//創(chuàng)建任務(wù)StartTask(void*)0,//給任務(wù)傳遞參數(shù)
&StartTaskStk[TASK_STK_SIZE-1],//設(shè)置任務(wù)堆棧棧頂指針
0);//使任務(wù)的優(yōu)先級別為0OSStart();//啟動多任務(wù)管理}/******************任務(wù)StartTask*****************************/voidStartTask(void*pdata){……OSStatInit();//初始化統(tǒng)計任務(wù)
OSTaskCreate(MyTask,//創(chuàng)建任務(wù)MyTask(void*)0,//給任務(wù)傳遞參數(shù)
&MyTaskStk[TASK_STK_SIZE-1],//設(shè)置任務(wù)堆棧棧頂指針
3);//使任務(wù)的優(yōu)先級別為3OSTaskCreate(YouTask,//創(chuàng)建任務(wù)YouTask(void*)0,//給任務(wù)傳遞參數(shù)
&YouTaskStk[TASK_STK_SIZE-1],//設(shè)置任務(wù)堆棧棧頂指針
4);//使任務(wù)的優(yōu)先級別為4for(;;){//如果按下ESC鍵,則退出μc/os-II
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 共同股權(quán)投資合同范本
- 關(guān)于續(xù)簽監(jiān)控合同范本
- 涼皮店用工合同范例
- 事業(yè)單位勞務(wù)合同范本3篇
- 公司考核合同范本
- 下班無償保潔合同范本
- 入股銷售合同范本
- 北京貸款合同范本
- 農(nóng)業(yè)設(shè)備運輸合同范例
- 公司簽承攬合同范本
- 秦荻輝科技英語寫作教程練習(xí)答案(共42頁)
- GB∕T 41168-2021 食品包裝用塑料與鋁箔蒸煮復(fù)合膜、袋
- 反興奮劑知識試題及答案
- 初中八年級上冊音樂課件4.2欣賞沃爾塔瓦河(14張)ppt課件
- 部編版語文一年級下冊繪本閱讀課-優(yōu)質(zhì)課件.pptx
- 新人教版九年級全一冊物理知識點填空題匯編
- 人教版五年級數(shù)學(xué)下冊每個單元教材分析(共九個單元)
- 辦好高水平民辦高中的哲學(xué)思考-教育文檔
- 小學(xué)生如何理解句子的含義(課堂PPT)
- 學(xué)科分類與代碼(管理學(xué))
- PROE拆電極教程
評論
0/150
提交評論