![第7章任務(wù)間的同步與通訊之消息隊(duì)列_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/17/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de1.gif)
![第7章任務(wù)間的同步與通訊之消息隊(duì)列_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/17/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de2.gif)
![第7章任務(wù)間的同步與通訊之消息隊(duì)列_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/17/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de3.gif)
![第7章任務(wù)間的同步與通訊之消息隊(duì)列_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/17/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de4.gif)
![第7章任務(wù)間的同步與通訊之消息隊(duì)列_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/17/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de/d3abaec9-3cb9-428b-8fd0-9f3f5bfa62de5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第七章 任務(wù)間的同步與通訊消息隊(duì)列l(wèi) 什么是消息隊(duì)列:消息隊(duì)列數(shù)據(jù)結(jié)構(gòu)l 消息隊(duì)列的操作函數(shù)使用可定義一個(gè)指針數(shù)組。讓數(shù)組的每個(gè)元素都存放一個(gè)消息緩沖區(qū)指針,那么任務(wù)就可通過傳遞這個(gè)指針數(shù)組指針的方法來傳遞多個(gè)消息了。這種可以傳遞多個(gè)消息的數(shù)據(jù)結(jié)構(gòu)叫做消息隊(duì)列。用來傳遞多個(gè)消息什么是消息隊(duì)列什么是消息隊(duì)列第七章 任務(wù)間的同步與通訊消息隊(duì)列l(wèi) 什么是消息隊(duì)列:用來傳遞多個(gè)消息l 消息隊(duì)列數(shù)據(jù)結(jié)構(gòu)l 消息隊(duì)列的操作函數(shù)使用指針消息隊(duì)列任務(wù)1任務(wù)2兩個(gè)任務(wù)使用消息隊(duì)列進(jìn)行通信的示意圖消息緩沖區(qū)1消息緩沖區(qū)n消息緩沖區(qū)2消息緩沖區(qū)指針數(shù)組三部分組成三部分組成消息隊(duì)列的數(shù)據(jù)結(jié)構(gòu)事件控制塊消息隊(duì)列消息OS
2、_EVENT_TYPE_QOS_Q結(jié)構(gòu)typedef struct os_q struct os_q *OSQPtrvoid*OSQStart;void*OSQEnd; void*OSQIn;void *OSQOut; INT16U OSQSize; INT16U OSQEntries; 。 OS_Q; 初始化后消息緩沖區(qū)第七章 任務(wù)間的同步與通訊消息隊(duì)列l(wèi) 什么是消息隊(duì)列:用來傳遞多個(gè)消息l 消息隊(duì)列數(shù)據(jù)結(jié)構(gòu)l 消息隊(duì)列的操作函數(shù)使用 消息隊(duì)列函數(shù)一覽表消息隊(duì)列函數(shù)一覽表 消息隊(duì)列配置常量一覽表消息隊(duì)列配置常量一覽表消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend()
3、 OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()建立一個(gè)消息隊(duì)列,OSQCreate()OSQCreate()的函數(shù)原型如下:OS_EVENT *OSQCreate( void *start, INT8U size); 參數(shù):Start:是消息內(nèi)存區(qū)的基地址,消息內(nèi)存區(qū)是一個(gè)指針數(shù)組。Size:是消息內(nèi)存區(qū)的大小。 返回值:OSQCreate()函數(shù)返回一個(gè)指向消息隊(duì)列事件控制塊的指針。如果沒有空余的事件空閑塊,OSQCreate()函數(shù)返回空指針。示例OS_EVENT *Semaphore; vo
4、id *Msg_Group10; char Msg_Arr1030; Semaphore = OSQCreate(Msg_Group,10); 事件消息隊(duì)列消息消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()刪除消息隊(duì)列OSQDel()函數(shù)原型函數(shù)原型OS_EVENT *OSQDel(OS_EVENT *pevent,INT8U opt,INT8U *err)參數(shù):參數(shù):(1) pevent:指向即將接收消息的隊(duì)列的指針,其
5、值在建立該隊(duì)列時(shí)可以得到。(2) opt:定義消息隊(duì)列刪除條件的選項(xiàng)。它有如下兩種選擇: OS_DEL_NO_PEND:只能在沒有任何任務(wù)等待該消息隊(duì)列的消息時(shí),才能刪除消息隊(duì)列。 OS_DEL_ALWAYS:不管有沒有任務(wù)在等待消息隊(duì)列的消息,都立即刪除消息隊(duì)列。刪除后,所有等待消息的任務(wù)立即進(jìn)入就緒狀態(tài)。(3) err: OS_NO_ERR:調(diào)用成功,消息隊(duì)列已被刪除。 OS_ERR_DEL_ISR:試圖在中斷服務(wù)子程序中刪除消息隊(duì)列。 OS_ERR_INVALID_OPT:無效的opt參數(shù),用戶沒有將opt定義為正確的選擇。 OS_ERR_EVENT_TYPE:pevent不是指向消息隊(duì)
6、列的指針。 OS_ERR_PEVENT_NULL:已經(jīng)沒有OS_EVENT數(shù)據(jù)結(jié)構(gòu)可以使用。消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()等待一個(gè)消息隊(duì)列中的消息,OSQPend()函數(shù)原型如下:void *OSQPend( OS_EVENT *pevent, INT16U timeout, INT8U *err); 參數(shù):pevent:指向即將接收消息的隊(duì)列的指針。timeout:允許一個(gè)任務(wù)在經(jīng)過了指定數(shù)目的時(shí)鐘節(jié)拍后
7、還沒有得到需要的消息時(shí)恢復(fù)運(yùn)行狀態(tài)。err:指向包含錯(cuò)誤碼的變量的指針。OSQPend()函數(shù)返回的錯(cuò)誤碼可能為下述幾種: 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 不是指向消息隊(duì)列的指針。 返回值:接受到消息并將 err置為OS_NO_ERR。如果沒有在指定數(shù)目的時(shí)鐘節(jié)拍內(nèi)接受到需要的消息,OSQPend()函數(shù)返回空指針并且將 err設(shè)置為OS_TIMEO
8、UT。示例OS_EVENT *TaskQ;void Task(void *pdata) INT8U err; void *msg; pdata = pdata; for (;) msg = OSQPend(TaskQ, 100, &err);if (err = = OS_NO_ERR) . /*在指定時(shí)間內(nèi)接收到消息 要做的事情*/ else /*在指定的時(shí)間內(nèi)沒有接收到指定的消息 要做的事情 */ 說明 如果調(diào)用OSQPend()函數(shù)時(shí)隊(duì)列中已經(jīng)存在需要的消息,那么該消息被返回給OSQPend()函數(shù)的調(diào)用者,隊(duì)列中清除該消息。 如果調(diào)用OSQPend()函數(shù)時(shí)隊(duì)列中沒有需要的消息,
9、OSQPend()函數(shù)掛起當(dāng)前任務(wù)直到得到需要的消息或超出定義的超時(shí)時(shí)間。 如果同時(shí)有多個(gè)任務(wù)等待同一個(gè)消息,C/OS-默認(rèn)最高優(yōu)先級的任務(wù)取得消息并且任務(wù)恢復(fù)執(zhí)行。 一個(gè)由OSTaskSuspend()函數(shù)掛起的任務(wù)也可以接受消息,但這個(gè)任務(wù)將一直保持掛起狀態(tài)直到通過調(diào)用OSTaskResume()函數(shù)恢復(fù)任務(wù)的運(yùn)行。消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()向消息隊(duì)列發(fā)送一個(gè)消息(FIFO),OSQPost()OS
10、QPost()的函數(shù)原型如下:INT8U OSQPost(OS_EVENT *pevent, void *msg); 參數(shù):pevent:指向即將接收消息的消息隊(duì)列的指針。該指針的值在建立該隊(duì)列時(shí)可以得到。(參考OSQCreate()函數(shù))。msg:即將實(shí)際發(fā)送給任務(wù)的消息。消息是一個(gè)指針長度的變量,在不同的程序中消息的使用也可能不同。不允許傳遞一個(gè)空指針。 返回值:OS_NO_ERR :消息成功的放到消息隊(duì)列中。OS_MBOX_FULL :消息隊(duì)列已滿。OS_ERR_EVENT_TYPE :pevent 不是指向消息隊(duì)列的指針。示例OS_EVENT *TaskQ;INT8U RxBuf50;
11、 void TaskRx(void *pdata) INT8U err; pdata = pdata; for (;) . err = OSQPost(TaskQ, (void *)& RxBuf0); if (err = OS_NO_ERR) . else . 消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()向消息隊(duì)列發(fā)送一個(gè)消息(LIFO),OSQPostFront()函數(shù)OSQPostFront()以LIFO(
12、后進(jìn)先出)的方式組織消息隊(duì)列。OSQPostFront()函數(shù)的原型如下:INT8U OSQPostFront(OS_EVENT *pevent, void *msg); 參數(shù):pevent:指向即將接收消息的消息隊(duì)列的指針。msg:即將實(shí)際發(fā)送給任務(wù)的消息。消息是一個(gè)指針長度的變量,在不同的程序中消息的使用也可能不同。不允許傳遞一個(gè)空指針。 返回值:OS_NO_ERR:消息成功的放到消息隊(duì)列中。OS_Q_FULL:消息隊(duì)列已滿。OS_ERR_EVENT_TYPE:pevent 不是指向消息隊(duì)列的指針。OS_ERR_PEVENT_NULL:pevent是空指針。 OS_ERR_POST_NUL
13、L_PTR:發(fā)出空指針。示例OS_EVENT *TaskQ;INT8U RxBuf50;void Task (void *pdata) INT8U err; pdata = pdata;for (; ;) . err = OSQPostFront(TaskQ, (void *)&RxBuf0); if (err = = OS_NO_ERR) . /*將消息放入消息隊(duì)列 */ else . /*消息隊(duì)列已滿 */ 消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept()
14、 OSQFlush() OSQQuery()以可選方式(FIFO或LIFO)向消息隊(duì)列發(fā)送消息OSQPostOpt()函數(shù)原型函數(shù)原型INT8U OSQPostOpt (OS_EVENT *pevent, void *msg,INT8U opt)OSQPostOpt()不僅可替代不僅可替代OSQPostFront()和和OSQPostFront (),而,而且可廣播發(fā)送消息。且可廣播發(fā)送消息。該函數(shù)有如下三個(gè)參數(shù):(1) pevent:指向接收消息的消息隊(duì)列的指針。 (2) msg:發(fā)送給任務(wù)的消息。消息是用指針表示的變量,不允許傳遞空指針。(3) opt:定義消息發(fā)送方式的選項(xiàng)。它有如下幾種
15、選擇: OS_POST_OPT_NONE:發(fā)消息給一個(gè)任務(wù),仿真OSQPost()函數(shù)。 OS_POST_OPT_BROADCAST:給等待消息的任務(wù)廣播發(fā)送消息。 OS_POST_OPT_FRONT:以LIFO方式發(fā)送消息,同于OSQPostFront()函數(shù)。 OS_POST_OPT_FRONT + OS_POST_OPT_BROADCAST:仿真OSQPostFront()函數(shù),且廣播消息。返回值:返回值:(1) OS_NO_ERR:消息成功地放到消息隊(duì)列中。:消息成功地放到消息隊(duì)列中。 (2) OS_Q_FULL:消息隊(duì)列已滿。:消息隊(duì)列已滿。 (3) OS_ERR_EVENT_TYP
16、E:pevent不是指向消息隊(duì)列的指針。不是指向消息隊(duì)列的指針。 (4) OS_ERR_PEVENT_NULL:pevent是空指針。是空指針。 (5) OS_ERR_POST_NULL_PTR:發(fā)出空指針。:發(fā)出空指針。示例OS_EVENT *TaskQ;INT8U RxBuf50; /*用于存放消息*/void Task (void *pdata) INT8U err; pdata = pdata; for (; ;) err = OSQPostOpt (TaskQ, (void *)&RxBuf0, OS_POST_OPT_FRONT); . 消息隊(duì)列的操作 OSQCreate(
17、) OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()無等待地從一個(gè)消息隊(duì)列中取得消息, OSQAccept()OSQAccept()函數(shù)的原型如下:void *OSQAccept(OS_EVENT *pevent); 參數(shù):pevent:指向需要查看的消息隊(duì)列的指針。 返回值:如果消息已經(jīng)到達(dá),返回指向該消息的指針;如果消息隊(duì)列沒有消息,返回空指針。消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFr
18、ont() OSQPostOpt() OSQAccept() OSQFlush() OSQQuery()清空一個(gè)消息隊(duì)列, OSQFlush()OSQFlush()的函數(shù)原型如下:INT8U *SOQFlush(OS_EVENT *pevent); 參數(shù):pevent:指向消息隊(duì)列的指針。 返回值:OS_NO_ERR :消息隊(duì)列被成功清空。OS_ERR_EVENT_TYPE :試圖清除不是消息隊(duì)列的對象消息隊(duì)列的操作 OSQCreate() OSQDel() OSQPend() OSQPost() OSQPostFront() OSQPostOpt() OSQAccept() OSQFlush
19、() OSQQuery()查詢一個(gè)消息隊(duì)列的狀態(tài),OSQQuery() OSQQuery()的函數(shù)原型如下: INT8U OSQQuery(OS_EVENT *pevent, OS_Q_DATA *pdata); 參數(shù): pevent:是指向即將接收消息的消息郵箱的指針。 pdata:是指向OS_Q_DATA數(shù)據(jù)結(jié)構(gòu)的指針,該數(shù)據(jù)結(jié)構(gòu)包含下述成員: void *OSMsg; /* 下一個(gè)可用的消息*/ INT16U OSNMsgs;/* 隊(duì)列中的消息數(shù)目*/ INT16UOSQSize;/* 消息隊(duì)列的大小 */ INT8U OSEventTblOS_EVENT_TBL_SIZE;/* 消息隊(duì)
20、列的等待隊(duì)列*/ INT8U OSEventGrp; 返回值:OS_NO_ERR :調(diào)用成功。OS_ERR_EVENT_TYPE :pevent 不是指向消息隊(duì)列的指針。第七章 任務(wù)間的同步與通訊消息隊(duì)列l(wèi) 什么是消息隊(duì)列:消息隊(duì)列數(shù)據(jù)結(jié)構(gòu)l 消息隊(duì)列的操作函數(shù)使用l 舉例舉例本例中有兩個(gè)任務(wù):MyTask和YouTask ,Youtask發(fā)2條消息,mytask收消息/*Test*/#include “includes.h”#define TASK_STK_SIZE 512 /任務(wù)堆棧長度OS_STK StartTaskStkTASK_STK_SIZE; /定義任務(wù)堆棧區(qū)OS_STK MyT
21、askStkTASK_STK_SIZE; /定義任務(wù)堆棧區(qū)OS_STK YouTaskStkTASK_STK_SIZE; /定義任務(wù)堆棧區(qū)INT16S key; /用于退出c/os-II的鍵INT8U y1=0,y2=0; /字符顯示位置 OS_EVENT * Semaphore; void *Msg_Group10; char Msg_Arr1030; uint8_t Index_Msg_Arr = 0; /消息void StartTask(void *data); /聲明起始任務(wù)聲明起始任務(wù)void MyTask(void *data); /聲明任務(wù)聲明任務(wù)void YouTask(voi
22、d *data); /聲明任務(wù)聲明任務(wù)/*主函數(shù)*/void main(void) OSInit(); /初始化c/os-II PC_DOSSaveReturn(); /保存DOS環(huán)境 PC_VectSet(uCOS,OSCtxSw); /安裝c/os-II中斷Semaphore = OSQCreate(Msg_Group,10) OSTaskCreate(StartTask, /創(chuàng)建任務(wù)StartTask (void *)0, /給任務(wù)傳遞參數(shù) &StartTaskStkTASK_STK_SIZE-1, /設(shè)置任務(wù)堆棧棧頂指針 0); /使任務(wù)的優(yōu)先級別為0 OSStart(); /
23、啟動多任務(wù)管理/*任務(wù)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); /安裝時(shí)鐘中斷向量 PC_SetTickRate(OS_TICKS_PER_SEC); /設(shè)置c/os-II時(shí)鐘頻率 OS_EXIT_CRITICAL(); OSStatInit(); /初始化統(tǒng)計(jì)任務(wù) OSTaskCreate(MyTask, (void *)0, &
24、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,0); /等待3s /*任務(wù)MyTask*/void MyTask(void *pdata)#if OS_CRITICAL_METHOD=3 OS_CPU_SR cpu_sr;#e
25、ndif pdata=pdata; void *msg_My; INT8U err; for( ; ; ) PC_DispStr(5,+y1, “MyTask”, DISP_BGND_BLACK+DISP_FGND_WHITE); msg_My=OSQPend(Semaphore,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*/void YouTask(void *pdata)#
26、if OS_CRITICAL_METHOD=3 OS_CPU_SR cpu_sr;#endif char *s10=“YouTask發(fā)送的消息1”,” YouTask發(fā)送的消息2”; /定義消息 INT8U err; INT8U i=0; pdata=pdata; for( ; ; ) PC_DispStr(40,+y2, “YouTask”, DISP_BGND_BLACK+DISP_FGND_WHITE); err=OSQPost(Semaphore,(void*)(s+i); i+; If (i%2=0) i=0;OSTimeDlyHMSM(0,0,2,0); /等待2s /*END*/教材上的例子例例7-7 設(shè)計(jì)了設(shè)計(jì)了6 個(gè)普通應(yīng)用任務(wù):個(gè)普通應(yīng)用任務(wù):TA0(優(yōu)先(優(yōu)先級為級為1)、)、TA1(優(yōu)先級為(優(yōu)先級為2)、)、
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- Fmoc-Phe-bis-Boc-4-guanidino-OH-生命科學(xué)試劑-MCE-3788
- Cannabidiphorol-CBDP-生命科學(xué)試劑-MCE-5981
- 2025年度區(qū)塊鏈技術(shù)股份投資協(xié)議
- 二零二五年度股權(quán)質(zhì)押合同樣本:適用于體育產(chǎn)業(yè)股權(quán)質(zhì)押
- 2025年度民宿窗簾墻布溫馨家居布置合同
- 二零二五年度股東致行動協(xié)議書:文化產(chǎn)業(yè)股權(quán)合作與數(shù)字版權(quán)保護(hù)協(xié)議
- 二零二五年度建筑垃圾處理與簡易房屋拆除合同
- 二零二五年度產(chǎn)學(xué)研合作聘用及錄用合同
- 施工現(xiàn)場施工防化學(xué)毒品泄漏制度
- 施工日志填寫樣本建筑物屋面防水工程
- 部編人教版道德與法治六年級下冊全冊課時(shí)練習(xí)講解課件
- 預(yù)防艾滋病、梅毒和乙肝母嬰傳播服務(wù)流程圖
- 鋼鐵是怎樣煉成的手抄報(bào)
- 防火墻漏洞掃描基礎(chǔ)知識
- 供應(yīng)鏈網(wǎng)絡(luò)安全解決方案
- NPI管理流程文檔
- 運(yùn)動技能學(xué)習(xí)PPT
- 嶺南版三年級美術(shù)下冊教學(xué)工作計(jì)劃
- 應(yīng)急裝備、應(yīng)急物資臺賬(較詳細(xì))
- 運(yùn)動技能學(xué)習(xí)與控制
- 大學(xué)物理光學(xué)答案
評論
0/150
提交評論