第7章 任務間的同步與通訊之消息郵箱._第1頁
第7章 任務間的同步與通訊之消息郵箱._第2頁
第7章 任務間的同步與通訊之消息郵箱._第3頁
第7章 任務間的同步與通訊之消息郵箱._第4頁
第7章 任務間的同步與通訊之消息郵箱._第5頁
已閱讀5頁,還剩48頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、第七章 任務間的同步與通訊消息郵箱l什么是消息郵箱什么是消息郵箱l消息郵箱的數據結構消息郵箱的數據結構l消息郵箱相關函數消息郵箱相關函數消息郵箱指針消息郵箱任務1任務2發(fā)送消息請求消息消息緩沖區(qū)(發(fā)送消息緩沖區(qū)指針)(讀取消息緩沖區(qū)指針)消息郵箱是一種通信機制,它能使任務或中斷服務向另一個任務發(fā)送一個指針型的變量,這個指針指向一個包含指定“消息”的數據結構。消息郵箱發(fā)送的不是消息本身,而是消息的地址指針。第七章 任務間的同步與通訊消息郵箱l什么是消息郵箱什么是消息郵箱l消息郵箱的數據結構消息郵箱的數據結構l消息郵箱相關函數消息郵箱相關函數消息郵箱的數據結構typedef struct INT8

2、U OSEventType; /* 事件類型 */ INT8U OSEventGrp; /* 等待任務所在的組 */ INT16U OSEventCnt; /* 計數器(當事件是信號量時) */ void *OSEventPtr; /* 指向消息或者消息隊列的指針 */INT8U OSEventTblOS_EVENT_TBL_SIZE; /* 等待任務列表 */ OS_EVENT;第七章 任務間的同步與通訊消息郵箱l什么是消息郵箱什么是消息郵箱l消息郵箱的數據結構消息郵箱的數據結構l消息郵箱相關函數消息郵箱相關函數 消息郵箱函數一覽表消息郵箱函數一覽表消息郵箱函數所屬文件是消息郵箱函數所屬文件

3、是OS_MBOX.COS_CFG.H文件中消息郵箱的配置常數一覽表文件中消息郵箱的配置常數一覽表任務、中斷服務子程序與消息郵箱之間的關系消息郵箱的操作 OSMboxCreate() OSMboxDel() OSMboxPend() OSMboxPost() OSMboxPostOpt() OSMboxAccept() OSMboxQuery()建立一個郵箱,OSMboxCreate()函數OSMboxCreate()的原型如下:OS_EVENT *OSMboxCreate(void *msg); 參數:msg 參數用來初始化建立的消息郵箱。如果該指針不為空,建立的消息郵箱將含有消息。 返回值:

4、指向分配給所建立的消息郵箱的事件控制塊的指針。如果沒有可用的事件控制塊,返回空指針。郵箱作用:郵箱作用: 通知一個消息(此時,通知一個消息(此時,msg為空)為空) 作為二值信號量作為二值信號量范例OS_EVENT *RxMbox; /*定義消息郵箱指針*/void main(void) . OSInit(); RxMbox = OSMboxCreate(void *)0); /*建立消息郵箱,初始值為空 */ OSStart(); /*啟動多任務內核 */OSMboxCreate()函數返回前,事件控制塊的內容郵箱特點 消息郵箱的內容是一個指向消息的指針,指針指消息郵箱的內容是一個指向消息的

5、指針,指針指向的內容就是消息向的內容就是消息 郵箱只能接收和發(fā)送一條消息,當郵箱滿時,將郵箱只能接收和發(fā)送一條消息,當郵箱滿時,將丟棄新消息,保持舊消息丟棄新消息,保持舊消息 當郵箱為滿是,郵箱里存放指向消息的指針;當當郵箱為滿是,郵箱里存放指向消息的指針;當郵箱為空時,郵箱指針為郵箱為空時,郵箱指針為NULL消息郵箱的操作 OSMboxCreate() OSMboxDel() OSMboxPend() OSMboxPost() OSMboxPostOpt() OSMboxAccept() OSMboxQuery() 刪除消息郵箱OSMboxDel()函數原型如下:函數原型如下:OS_EVEN

6、T *OSMboxDel(OS_EVENT *pevent,INT8U opt,INT8U *err)該函數用于刪除消息郵箱,所屬文件為該函數用于刪除消息郵箱,所屬文件為OS_MBOX.C,調用者為任務,開關量為,調用者為任務,開關量為OS_MBOX_EN和和OS_MBOX_ DEL_EN。參數:參數:(1) pevent:指向消息郵箱的指針,該指針是消息郵箱建立時,返回給應用程序的:指向消息郵箱的指針,該指針是消息郵箱建立時,返回給應用程序的指針。指針。(2) opt:用于定義消息郵箱刪除條件的選項。可供選擇的值如下:用于定義消息郵箱刪除條件的選項。可供選擇的值如下: OS_DEL_NO_P

7、END:選擇只能是沒有任何任務在等待該消息郵箱的消息時,:選擇只能是沒有任何任務在等待該消息郵箱的消息時,才能刪除消息郵箱。才能刪除消息郵箱。 OS_DEL_ALWAYS:不管有沒有任務在等待消息郵箱的消息,都立即刪除消息:不管有沒有任務在等待消息郵箱的消息,都立即刪除消息郵箱。刪除后,所有等待消息郵箱消息的任務都立即進入就緒狀態(tài)。郵箱。刪除后,所有等待消息郵箱消息的任務都立即進入就緒狀態(tài)。(3) err:指向出錯代碼的指針。:指向出錯代碼的指針。 OS_NO_ERR:調用成功,表明郵箱已被刪除。:調用成功,表明郵箱已被刪除。 OS_ERR_DEL_ISR:試圖在中斷服務子程序中刪:試圖在中斷

8、服務子程序中刪除郵箱。除郵箱。 OS_ERR_INVALID_OPT:無效的:無效的opt參數。參數。 OS_ERR_EVENT_TYPE:pevent不是指向郵箱的不是指向郵箱的指針。指針。 OS_ERR_PEVENT_NULL:沒有可以使用的:沒有可以使用的OS_ EVENT數據結構數據結構返回值返回值OSMboxDel()函數的返回值為如下內容之一:函數的返回值為如下內容之一:(1) 返回空指針返回空指針NULL,表示消息郵箱已被刪除。,表示消息郵箱已被刪除。(2) 返回返回pevent,表示消息郵箱沒有刪除,在這種情況下,表示消息郵箱沒有刪除,在這種情況下,應該進一步查看出錯代碼,找到

9、出錯原因。應該進一步查看出錯代碼,找到出錯原因。. 范例。OS_EVENT *RxMbox/*定義消息郵箱指針定義消息郵箱指針*/void task( void *pdata) INT8U *err; pdata = pdata; for (;) RxMbox = OSMboxDel (RxMbox,OS_DEL_ALWAYS,&err); 應用程序;應用程序; 消息郵箱的操作 OSMboxCreate() OSMboxDel() OSMboxPend() OSMboxPost() OSMboxPostOpt() OSMboxAccept() OSMboxQuery()等待郵箱中的消息,OSM

10、boxPend()函數OSMboxPend()的原型如下:void *OSMboxPend ( OS_EVNNT *pevent, INT16U timeout, int8u *err ); 參數:pevent:是指向即將接受消息的消息郵箱的指針。timeout:允許一個任務在經過了指定數目的時鐘節(jié)拍后還沒有得到需要的消息時恢復運行。err:是指向包含錯誤碼的變量的指針。OSMboxPend()函數返回的錯誤碼可能為下述幾種: OS_NO_ERR :消息被正確的接收。 OS_TIMEOUT :消息沒有在指定的周期數內送到。 OS_ERR_PEND_ISR :從中斷調用該函數。雖然規(guī)定了不允許從

11、中斷調用該函數,但C/OS-仍然包含了檢測這種情況的功能。 OS_ERR_EVENT_TYPE :pevent 不是指向消息郵箱的指針。返回值:OSMboxPend()函數返回接收的消息并將 *err置為OS_NO_ERR。如果沒有在指定數目的時鐘節(jié)拍內接受到需要的消息,OSMboxPend()函數返回空指針并且將 *err設置為OS_TIMEOUT。范例OS_EVENT *RxMbox; /*定義消息郵箱指針*/void Task(void *pdata) INT8U err; void *msg; pdata = pdata; for (; ;) 應用程序代碼; msg = OSMboxP

12、end (RxMbox, 10, &err) ;/*返回消息指針,據該指針可獲消息*/ if (err = OS_NO_ERR) 消息正確接收的應用程序代碼; else 在指定時間內沒有接收到消息的應用程序代碼; 應用程序代碼; 等待消息說明消息郵箱已經存在需要的消息,那么該消息被返回給OSMboxPend()的調用者,消息郵箱中清除該消息。如果調用OSMboxPend()函數時消息郵箱中沒有需要的消息,OSMboxPend()函數掛起當前任務直到得到需要的消息或超出定義等待超時的時間。如果同時有多個任務等待同一個消息,C/OS-默認最高優(yōu)先級的任務取得消息并且任務恢復執(zhí)行。一個由OSTask

13、Suspend()函數掛起的任務也可以接受消息,但這個任務將一直保持掛起狀態(tài)直到通過調用OSTaskResume()函數恢復任務的運行。消息郵箱的操作 OSMboxCreate() OSMboxDel() OSMboxPend() OSMboxPost() OSMboxPostOpt() OSMboxAccept() OSMboxQuery()向郵箱發(fā)送一則消息,OSMboxPost()函數OSMboxPost()的原型如下:INT8U OSMboxPost(OS_EVENT *pevent, void *msg); 參數:pevent:指向即將接受消息的消息郵箱的指針。該指針的值在建立該消息

14、郵箱時可以得到。(參考OSMboxCreate()函數)。msg:即將實際發(fā)送給任務的消息。消息是一個指針長度的變量,在不同的程序中消息的使用也可能不同。不允許傳遞一個空指針,因為這意味著消息郵箱為空。 返回值:OS_NO_ERR :消息成功的放到消息郵箱中。OS_MBOX_FULL :消息郵箱已經包含了其他消息,不空。OS_ERR_EVENT_TYPE :pevent 不是指向消息郵箱的指針。調用者是任務或中斷,開關量是調用者是任務或中斷,開關量是OS_MBOX_EN和和OS_MBOX_POST_EN發(fā)送消息說明 如果消息郵箱中已經存在消息,返回錯誤碼說明消息郵箱已滿。 如果有多個任務在等待

15、消息郵箱的消息,最高優(yōu)先級的任務將得到這個消息。 如果等待消息的任務優(yōu)先級比發(fā)送消息的任務優(yōu)先級高,那么高優(yōu)先級的任務將得到消息而恢復執(zhí)行,也就是說,發(fā)生了一次任務切換。消息郵箱的操作 OSMboxCreate() OSMboxDel() OSMboxPend() OSMboxPost() OSMboxPostOpt() OSMboxAccept() OSMboxQuery()廣播發(fā)送消息到消息郵箱中OSMboxPostOpt()函數原型如下:函數原型如下:INT8U OSMboxPostOpt(OS_EVENT *pevent, void *msg,INT8U opt)OSMboxPostO

16、pt()函數與函數與OSMboxPost()函數比較函數比較 兩者工作方式相同,都用指針傳遞消息;兩者工作方式相同,都用指針傳遞消息; 不同的是不同的是OSMboxPost()只能給一個任務發(fā)送消息,而只能給一個任務發(fā)送消息,而OSMboxPostOpt()允許允許將消息廣播給所有的等待消息郵箱消息的任務,且可以仿真將消息廣播給所有的等待消息郵箱消息的任務,且可以仿真OSMboxPost()。 OSMboxPostOpt()函數的開關量是函數的開關量是OS_MBOX_EN和和OS_MBOX_POST_OPT_EN,調用者可以是任務,也可以是中斷。調用者可以是任務,也可以是中斷。 在廣播方式下,

17、函數的執(zhí)行時間取決于等待消息郵箱消息的任務數量。在廣播方式下,函數的執(zhí)行時間取決于等待消息郵箱消息的任務數量。 OSMboxpostOpt()函數有如下三個參數:函數有如下三個參數:(1) pevent:指向即將接收消息的消息郵箱的指針。該指針的值可以在建立:指向即將接收消息的消息郵箱的指針。該指針的值可以在建立該消息郵箱時得到。該消息郵箱時得到。(2) msg:即將發(fā)送給任務的消息。消息是以指針表示的某種數據類型的變:即將發(fā)送給任務的消息。消息是以指針表示的某種數據類型的變量,消息的數據類型可能會因具體應用的不同而有所差異。不允許傳遞空指針,量,消息的數據類型可能會因具體應用的不同而有所差異

18、。不允許傳遞空指針,因為這樣意味著消息郵箱為空。因為這樣意味著消息郵箱為空。(3) opt:定義發(fā)送消息方式的選項。它有兩種形式:定義發(fā)送消息方式的選項。它有兩種形式: 若若opt = OS_POST_OPT_NONE,則定義消息只發(fā)給等待消息的任務中優(yōu)先,則定義消息只發(fā)給等待消息的任務中優(yōu)先級最高的任務;級最高的任務; 若若opt = OS_POST_OPT_BROADCAST,則讓所有等待郵箱消息的任務都得,則讓所有等待郵箱消息的任務都得到消息。到消息。返回值返回值(1) OS_NO_ERR:調用成功,消息已經發(fā)出。:調用成功,消息已經發(fā)出。(2) OS_MBOX_FULL:郵箱中已經有消

19、息。:郵箱中已經有消息。(3) OS_ERR_EVENT_TYPE:pevent不是指向郵箱的指針。不是指向郵箱的指針。(4) OS_ERR_PEVENT_NULL:pevent是空指針。是空指針。(5) OS_ERR_POST_NULL_PTR:試圖發(fā)送空指針。根據規(guī):試圖發(fā)送空指針。根據規(guī)則,空指針無效則,空指針無效。消息郵箱的操作 OSMboxCreate() OSMboxDel() OSMboxPend() OSMboxPost() OSMboxPostOpt() OSMboxAccept() OSMboxQuery()無等待地從郵箱中得到一則消息,OSMboxAccept()OSMb

20、oxAccept()的函數原型如下:void *OSMboxAccept(OS_EVENT *pevent); 參數:pevent:是指向需要查看的消息郵箱的指針。返回值:如果消息已經到達,返回指向該消息的指針;如果消息郵箱沒有消息,返回空指針。范例OS_EVENT *ComMbox;void Task (void *pdata) void *msg; pdata = pdata; for (; ;) msg = OSMboxAccept(ComMbox); /*檢查消息郵箱是否有消息if (msg != (void *)0) 處理消息; else 處理無消息的情況; . 消息郵箱的操作 OS

21、MboxCreate() OSMboxDel() OSMboxPend() OSMboxPost() OSMboxPostOpt() OSMboxAccept() OSMboxQuery()查詢一個郵箱的狀態(tài),OSMboxQuery()OSMboxQuery()的函數原型如下:INT8U OSMboxQuery(OS_EVENT *pevent, OS_MBOX_DATA *pdata); 參數: pevent:指向即將接收消息的消息郵箱的指針。 pdata:指向OS_MBOX_DATA數據結構的指針, 該數據結構包含下述成員: Void *OSMsg;/* 消息郵箱中消息的復制 */ INT

22、8U OSEventTblOS_EVENT_TBL_SIZE;/*消息郵箱等待隊列的復制*/ INT8U OSEventGrp; 返回值: OS_NO_ERR :調用成功。 OS_ERR_EVENT_TYPE :pevent 不是指向消息郵箱的指針。范例OS_EVENT *RxMbox; /*定義指針/ void Task (void *pdata) OS_MBOXDATA cbox_data; INT8U err; pdata = pdata; for (; ;) err = OSMboxQuery(RxMbox, &cbox_data); if (err = OS_NO_ERR) . /*

23、如果cbox_data.OSMsg為非空指針,說明消息郵箱非空*/ . 舉例本例中有兩個任務:MyTask和YouTask。任務YouTask要向任務MyTask發(fā)送消息/*Test*/#include “includes.h”#define TASK_STK_SIZE 512 /任務堆棧長度OS_STK StartTaskStkTASK_STK_SIZE; /定義任務堆棧區(qū)OS_STK MyTaskStkTASK_STK_SIZE; /定義任務堆棧區(qū)OS_STK YouTaskStkTASK_STK_SIZE; /定義任務堆棧區(qū)INT16S key; /用于退出c/os-II的鍵INT8U

24、y1=0,y2=0; /字符顯示位置 OS_EVENT *msg; /消息郵箱void StartTask(void *data); /聲明起始任務void MyTask(void *data); /聲明任務void YouTask(void *data); /聲明任務/*主函數*/void main(void) OSInit(); /初始化c/os-II PC_DOSSaveReturn(); /保存DOS環(huán)境 PC_VectSet(uCOS,OSCtxSw); /安裝c/os-II中斷msg=OSMboxCreate(void*)0); OSTaskCreate(StartTask, /創(chuàng)

25、建任務StartTask (void *)0, /給任務傳遞參數 &StartTaskStkTASK_STK_SIZE-1, /設置任務堆棧棧頂指針 0); /使任務的優(yōu)先級別為0 OSStart(); /啟動多任務管理/*任務StartTask*/void StartTask(void *pdata)#if OS_CRITICAL_METHOD=3 OS_CPU_SR cpu_sr;#endif pdata=pdata; OS_ENTER_CRITICAL(); PC_VectSet(0 x08,OSTickISR); /安裝時鐘中斷向量 PC_SetTickRate(OS_TICKS_PE

26、R_SEC); /設置c/os-II時鐘頻率 OS_EXIT_CRITICAL(); OSStatInit(); /初始化統(tǒng)計任務 OSTaskCreate(MyTask, (void *)0, &MyTaskStkTASK_STK_SIZE-1, 1); OSTaskCreate(YouTask, (void *)0, &YouTaskStkTASK_STK_SIZE-1, 2); for( ; ; ) /如果按下ESC鍵,則退出c/os-II if(PC_GetKey(&key)=TRUE) if(key=0 x1B) PC_DOSReturn(); OSTimeDlyHMSM(0,0,3

27、,0); /等待3s /*任務MyTask*/void MyTask(void *pdata)#if OS_CRITICAL_METHOD=3 OS_CPU_SR cpu_sr;#endif pdata=pdata; void *msg_My; INT8U err; 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+DIS

28、P_FGND_WHITE); OSTimeDlyHMSM(0,0,1,0); /等待1s/*任務YouTask*/void YouTask(void *pdata)#if OS_CRITICAL_METHOD=3 OS_CPU_SR cpu_sr;#endif char *s=“YouTask發(fā)送的消息”; /定義消息 INT8U err; pdata=pdata; for( ; ; ) PC_DispStr(40,+y2, “YouTask”, DISP_BGND_BLACK+DISP_FGND_WHITE); err=OSMboxPost(msg,(void*)s);OSTimeDlyHM

29、SM(0,0,2,0); /等待2s /*END*/再看一個例子設計一個應用程序,該程序有兩個任務設計一個應用程序,該程序有兩個任務MyTask和和YouTask。在任務。在任務MyTask中用一個中用一個變量變量Times記錄任務記錄任務MyTask的運行次數,并的運行次數,并將其作為消息用郵箱將其作為消息用郵箱Str_Box發(fā)給任務發(fā)給任務YouTask且由任務且由任務YouTask顯示出來。顯示出來。/*Test*/#include “includes.h”#define TASK_STK_SIZE 512 /任務堆棧長度OS_STK StartTaskStkTASK_STK_SIZE;

30、 /定義任務堆棧區(qū)OS_STK MyTaskStkTASK_STK_SIZE; /定義任務堆棧區(qū)OS_STK YouTaskStkTASK_STK_SIZE; /定義任務堆棧區(qū)INT16S key; /用于退出的鍵char *s; char *ss;INT8U err; INT8U y=0; /字符顯示位置INT32U Times=0;OS_EVENT *Str_Box; /定義事件控制塊指針void StartTask(void *data); /聲明起始任務void MyTask(void *data); /聲明任務void YouTask(void *data); /聲明任務/*主函數*/void main(void) OSInit(); /初始化c/os-II Str_Box=OSMboxCreate(void *)0); /創(chuàng)建消息郵箱OSTaskCreate(StartTask, /創(chuàng)建任務StartTask (void *)0, /給任務傳遞參數 &StartTaskStkTASK_STK_SIZE-1, /設置任務堆棧棧頂指針 0); /使任務的優(yōu)先級別為0 OSStart(); /啟動多

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論