版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理第第7 7章章 消息管理消息管理OSMboxCreate()OSMboxPend()OSMboxPost()OSMboxPostOpt()OSMboxDel()OSMboxAccept()OSMboxQuery()OSQCreate()OSQDel()OSQPend()OSQPost()OSQPostFront()OSQPostOpt()OSQAccept()OSQFlush()OSQQuery()消息隊列消息郵箱主要內容概念,功能,差別,用法 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS
2、-教程教程 第七章第七章 消息管理消息管理7.1 7.1 消息郵箱管理消息郵箱管理7.1.1 概述n概念:概念:郵箱是一種通信機制,它能使任務或中斷服務向另一個任務發(fā)送一個指針型的變量,這個指針指向一個包含指定“消息”的數(shù)據(jù)結構。郵箱發(fā)送的不是消息本身,而是消息的地址指針。n使用郵箱之前,必須先建立郵箱,并且要指定指針的初始值。一般情況下,這個初始值是NULL,但也可以在初始化時,就使其在最開始就包含一條消息。n郵箱主要用于兩種目的郵箱主要用于兩種目的:q通知一個事件的發(fā)生;一作二值信號量用。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1
3、.1.2 消息郵箱的特點n郵箱中的內容是一個指向消息的指針,指針指向的內容即是消息;n郵箱為滿時,郵箱只包含一個指向消息的指針;郵箱為空時,郵箱消息的指針指向NULL;1.郵箱只能接收和發(fā)送一則消息,郵箱為滿時,將丟棄新消息,保留舊消息。 7.1.1.1 消息郵箱初始值的設置方法n如果使用郵箱是用于通知一個事件的發(fā)生(發(fā)送一條消息),那么就要初始化該郵箱為NULL,因為在開始時,事件還沒有發(fā)生;1.如果作二值信號量用,即用于共享某些資源,那么就要初始化該郵箱為一個非NULL的指針。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.1.3 消
4、息郵箱管理函數(shù) 如表7.1所示,C/OS-II提供了7種對郵箱的操作,郵箱函數(shù)所屬文件是OS_MBOX.C。 表表7.1 消息郵箱函數(shù)一覽表消息郵箱函數(shù)一覽表函數(shù)函數(shù)功能功能調用者調用者OSMboxCreate()建立郵箱建立郵箱任務或啟動代碼任務或啟動代碼OSMboxPend()等待郵箱消息等待郵箱消息只能是任務只能是任務OSMboxPost()發(fā)出郵箱消息發(fā)出郵箱消息任務或中斷任務或中斷OSMboxPostOpt()發(fā)出郵箱消息發(fā)出郵箱消息任務或者中斷任務或者中斷OSMboxDel()刪除郵箱消息刪除郵箱消息任務任務OSMboxAccept()無等待地請求郵箱消息無等待地請求郵箱消息任務或
5、中斷任務或中斷OSMboxQuery()查詢郵箱狀態(tài)查詢郵箱狀態(tài) 任務或中斷任務或中斷嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.1.4 消息郵箱的配置常量 在使用郵箱函數(shù)之前,必須將 OS_CFG.H文件中相應的配置常量設置為0或1,以確定是編譯還是裁剪該函數(shù),其配置常量如表7.2所示。 表表7.2 OS_CFG.H文件中郵箱的配置常數(shù)一覽表文件中郵箱的配置常數(shù)一覽表郵箱函數(shù)配置常數(shù)說明系統(tǒng)配置OS_MBOX_EN該常量為0時,屏蔽所有郵箱函數(shù)OS_MAX_EVENTS決定郵箱最大數(shù)目的常量OSMboxCreate()無郵箱必須支持
6、這兩個函數(shù),不能單獨屏蔽OSMboxPend()OSMboxDel()OS_MBOX_DEL_ENOSMboxPost()OS_MBOX_POST_EN這兩個函數(shù)必須至少任選其一OSMboxPostOpt()OS_MBOX_POST_OPT_ENOSMboxAccept()OS_MBOX_ACCEPT_ENOSMboxQuery()OS_MBOX_QUERY_EN嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.1.5 任務、中斷服務子程序與郵箱之間的關系 圖7.1任務、中斷服務子程序與郵箱之間的關系任務任務ISRISRI任務任務ISRIS
7、R消息消息OSMboxCreate()OSMboxDel()OSMboxPost()OSMboxPostOpt()OSMboxPost()OSMboxPostOpt()OSMboxPend()OSMboxAccept()OSMboxQuery()OSMboxAccept()嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.2 建立郵箱,OSMboxCreate() 7.1.2.1 函數(shù)原型OS_EVENT OS_EVENT * *OSMboxCreateOSMboxCreate(void void * *msgmsg)reentrantre
8、entrant 在使用郵箱之前,必須建立一個郵箱,OSMboxCreate()函數(shù)用于建立并初始化一個消息郵箱。消息郵箱允許任務或中斷向其它一個或幾個任務發(fā)送消息。n參數(shù):參數(shù):msgmsg,指向消息的指針。該參數(shù)的設置方法如前一節(jié)所述,可以為空,也可以不為空。如果該指針不為空,建立的消息郵箱將含有消息。n函數(shù)所屬文件:函數(shù)所屬文件:OS_MBOX.C。n調用者:調用者:任務或啟動代碼。n配置常量:OS_MBOX_EN。 7.1.2.2 返回值 如果建立成功,函數(shù)返回指向分配給所建立的消息郵箱的事件控制塊的指針。如果沒有可用的事件控制塊,則返回空指針。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/O
9、S-C/OS-教程教程 第七章第七章 消息管理消息管理圖圖7.2 OSMboxCreate()7.2 OSMboxCreate()流程與源代碼流程與源代碼 7.1.2.3 原理與實現(xiàn)n基本原理如圖7.2所示:從空閑ECB鏈表中抽取一個ECB數(shù)據(jù)結構,對其進行初始化,設置:.OSEventType = OS_EVENT_TYPE_MBOX,.OSEventCnt = 0,OSEventPtr = msg,調用OSEventWaitListInit()函數(shù)清空等待任務列表。最后返回ECB指針,以供其它消息郵箱函數(shù)使用。實現(xiàn)代碼如程序清單7.1所示源代碼, 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/O
10、S-C/OS-教程教程 第七章第七章 消息管理消息管理OS_EVENT OS_EVENT_TYPE_MBOX 0 x00 msg 0 x00765432106362616059585756pevent圖7.3 OSMboxCreate()函數(shù)返回之前的事件控制塊ECB.OS_EvenType.OS_EvenType.OS_EventCnt.OS_EventCnt.OS_EventPtr.OS_EventPtr.OS_EventGrp.OS_EventGrp OS_EvntTbl OS_EvntTbl表中所有值均初始化為0嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第
11、七章 消息管理消息管理 OSMboxCreate()函數(shù)的應用范例如程序清單7.2所示,應用前必須定義一個OS_EVENT類型全局指針變量,以便保存調用時的返回值,供其它郵箱函數(shù)使用。 程序清單程序清單7.2 OSMboxCreate()7.2 OSMboxCreate()應用范例應用范例OS_EVENT *RxMbox; / 定義郵箱指針void main(void) . OSInit(); / 初始化C/OS- . RxMbox = OSMboxCreate(void *)0); / 建立消息郵箱,初始值為空 . OSStart(); / 啟動多任務內核7.1.2.4 應用范例嵌入式實時操
12、作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.3 刪除郵箱, OSMboxDel()7.1.3.1 函數(shù)原型OS_EVENT *OSMboxDel( OS_EVENT *pevent,INT8U opt,INT8U *err) reentrantn功能:功能:用于刪除郵箱。n所屬文件:所屬文件:OS_MBOX.C。n調用者:調用者:任務。n配置常量:配置常量:OS_MBOX_DEL_EN。n函數(shù)參數(shù):函數(shù)參數(shù):npevent pevent 指向郵箱的指針,該指針是郵箱建立時,返回給應用程序的指針;noptopt 用于定義郵箱刪除條件的選項,可供選擇
13、的值如下:qOS_DEL_NO_PENDOS_DEL_NO_PEND 選擇只能是沒有任何任務在等待該郵箱的消息時,才能刪除郵箱;qOS_DEL_ALWAYS OS_DEL_ALWAYS 不管有沒有任務在等待郵箱的消息,都立即刪除郵箱。刪除后,所有等待郵箱消息的任務都立即進入就緒狀態(tài)。nerrerr 指向出錯代碼的指針,返回的出錯代碼可以是以下幾種之一:qOS_NO_ERROS_NO_ERR調用成功,表明郵箱已被刪除;qOS_ERR_DEL_ISROS_ERR_DEL_ISR 試圖在中斷服務子程序中刪除郵箱;qOS_ERR_INVALID_OPTOS_ERR_INVALID_OPT 無效的opt
14、參數(shù);qOS_ERR_EVENT_TYPEOS_ERR_EVENT_TYPEpevent不是指向郵箱的指針;一一OS_ERR_PEVENT_NULLOS_ERR_PEVENT_NULL 沒有可以使用的OS_EVENT數(shù)據(jù)結構。 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.3.2 返回值n返回空指針NULL,表示郵箱已被刪除;n返回pevent,表示郵箱沒有刪除,在這種情況下,應該進一步查看出錯代碼,找到出錯原因。7.1.3.3 應用要點n調用這個函數(shù)時,應該注意是否有其它任務還要使用這個郵箱;n當掛起的任務轉入就緒時,中斷是關閉的,這
15、就使得中斷延遲時間與等待郵箱的消息的任務數(shù)有關;1.調用OSMboxAccpet()函數(shù)不能判斷郵箱是否已經(jīng)被刪除。OS_EVENT *RxMbox/ 定義郵箱指針void task( void *ppdata) reentrant INT8U *err; pdata = ppdata; for (;) 應用程序; RxMbox = OSMboxDel (RxMbox,OS_DEL_ALWAYS,&err); 應用程序;7.1.3.5 應用范例嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.4 等待郵箱中的消息, OSMboxPe
16、nd() 7.1.4.1 函數(shù)原型void *OSMboxPend( OS_EVNNT *pevent, INT16U timeout, INT8U*err ) reentrantn功能:功能:用于任務等待消息。任務或者中斷發(fā)出的消息是一個指針型的變量,在不同的應用中消息的使用也可能不同。該函數(shù)具有如下特點:n如果調用時郵箱中已有消息,那么該消息被返回給調用者,并從郵箱中清除該消息;n調用時,如果郵箱中沒有消息,OSMboxPend()函數(shù)掛起當前任務直到得到需要的消息或等待超時期滿;n如果同時有多個任務等待同一個消息,C/OS-將把消息交給優(yōu)先級最高的任務并且恢復它的運行;n一個由OSTas
17、kSuspend()函數(shù)掛起的任務也可以接受消息,但這個任務將一直保持掛起狀態(tài)直到通過調用OSTaskResume()函數(shù)來恢復任務的運行;一函數(shù)的調用者只能是任務,中斷不能調用,配置常量是OS_MBOX_EN。 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理n參數(shù)參數(shù)qpeventpevent 指向包含有所需消息的郵箱的指針,它是調用OSMboxCreate()函數(shù)建立消息郵箱時的返回值。qtimeouttimeout 任務等待的延時時限,單位是時鐘節(jié)拍,取值范圍是065,535。q如果參數(shù)取值為0,則表示任務無限期地等待消息,直到收到消息才
18、轉入就緒。q如果參數(shù)取值為165,535之間的任何值,這個值即為任務等待消息的最長延時。若在指定的延時期限內還沒有得到消息,即使任務進入就緒。q這個時間長度存在1個時鐘節(jié)拍的誤差,因為超時時鐘節(jié)拍數(shù)量僅在每個時鐘節(jié)拍發(fā)生后才會遞減。qerrerr 指向錯誤代碼變量的指針,錯誤代碼有如下幾種:qOS_NO_ERR 成功得到消息;qOS_TIMEOUT 消息沒有在指定的延時期內送到;qOS_ERR_PEND_ISR 從中斷調用該函數(shù);qOS_ERR_EVENT_TYPE pevent 不是指向消息郵箱的指針。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消
19、息管理7.1.4.2 返回值n如果收到的消息正確,OSMboxPend()函數(shù)返回接收的消息并將 *err置為OS_NO_ERR;n如果在指定的延時期限內沒有接收到需要的消息,OSMboxPend()函數(shù)返回空指針,并且將 *err設置為OS_TIMEOUT。7.1.4.3 原理與實現(xiàn) 基本原理:從pevent指向的ECB中讀取成員變量 . .OSEventPtr,若其值為非空,表明郵箱中有消息,則返回消息指針,并清 . .OSEventPtr;若其值為空,表明沒有郵箱中沒有消息,則掛起當前任務等待消息。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消
20、息管理程序清單程序清單7.5 OSMboxPend()7.5 OSMboxPend()應用范例應用范例OS_EVENT *RxMbox; / 定義郵箱指針void Task(void *ppdata) reentrant INT8U err; void *msg; ppdata = ppdata; for (;) 應用程序代碼; msg = OSMboxPend (RxMbox,10,&err) ;/ 返回消息指針,據(jù)該指/ 針可獲消息 if (err = OS_NO_ERR) / 延時期內消息正確收到 應用程序代碼; else / 延時期滿未收到消息 應用程序代碼; 應用程序代碼;
21、7.1.4.4 應用范例嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.5 發(fā)送消息到郵箱中, OSMboxPost()7.1.5.1 函數(shù)原型INT8U OSMboxPost( OS_EVENT INT8U OSMboxPost( OS_EVENT * *pevent, void pevent, void * *msg ) reentrantmsg ) reentrantn功能功能:OSMboxPost()函數(shù)通過消息郵箱向任務發(fā)送消息,消息是一個指針型變量,消息的數(shù)據(jù)類型允許根據(jù)實際需求而定義成不同的類型。它具有如下特點:q如果郵箱中
22、已有消息,返回錯誤代碼說明郵箱已滿,函數(shù)立即返回調用者,并丟棄新消息。q如果郵箱無消息,則:n如果有任務在等待消息,最高優(yōu)先級的任務將得到這個消息。如果等待消息的任務的優(yōu)先級比函數(shù)的調用者優(yōu)先級高,這個高優(yōu)先級任務得以恢復運行,調用者被掛起,發(fā)生一次任務切換。 若從中斷調用,則不發(fā)生任務切換;n如果沒有任務在等待消息,消息的指針將被保存在郵箱中。q調用者可以是任務或中斷,配置常量是OS_MBOX_POST_EN。n函數(shù)參數(shù)函數(shù)參數(shù):qpeventpevent 指向即將接受消息的郵箱的指針,它是調用OSMboxCreate()函數(shù)建立消息郵箱時的返回值;一一msgmsg 發(fā)送給任務的消息。不允許
23、傳遞一個空指針,因為這意味著消息郵箱為空。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.5.2 返回值函數(shù)的返回值err的錯誤代碼可能是如下幾種之一:qOS_NO_ERR 消息成功的放到郵箱中;qOS_MBOX_FULL 郵箱滿,已經(jīng)包含了其它消息;qOS_ERR_EVENT_TYPE pevent 不是指向郵箱的指針;qOS_ERR_PEVENT_NULL pevent 是空指針;qOS_ERR_POST_NULL_PTR 用戶試圖發(fā)出空指針,根據(jù)規(guī)則,空指針無效。 7.1.5.3 原理與實現(xiàn) 函數(shù)基本原理:首先檢查pevent指向的
24、等待任務列表中是否有任務在等待消息,若有,則調用OSEventTaskRdy()函數(shù)將消息發(fā)給任務并置于就緒;若無任務在等待消息,且郵箱為空,則將消息保存到郵箱中;若無任務等待消息,且郵箱非空,則丟棄消息返回。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.5.4 應用實例CFG.H 程程序序組組成成修改修改8處處加頭文件加頭文件申明全局變量和函數(shù)申明全局變量和函數(shù)初始化多任務環(huán)境初始化多任務環(huán)境創(chuàng)建創(chuàng)建2個郵箱個郵箱創(chuàng)建創(chuàng)建2個任務個任務啟動多任務等啟動多任務等啟動段啟動段任務任務1任務任務2P3.1口波形輸出口波形輸出P3.2口波形輸
25、出口波形輸出例:例:編寫在單片機P3.1和P3.2端口上分別輸出2個周期相同相位相反方波的程序。解:PENDPENDACKIRXI調郵箱調郵箱RX等待電平等待電平L1在在P3.2口輸口輸出電平出電平L1L2 = 取反取反L1調郵箱調郵箱ACK發(fā)送電平發(fā)送電平L200POSTPOST高優(yōu)先級高優(yōu)先級Task1低優(yōu)先級低優(yōu)先級Task2調郵箱調郵箱ACK等待電平等待電平L2調郵箱調郵箱RX發(fā)電平發(fā)電平L1在在P3.1口輸口輸出電平出電平L2L1 = L2延時延時1秒秒嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理程序清單程序清單7.7 7.7 郵箱
26、管理函數(shù)應用實例郵箱管理函數(shù)應用實例/*模 塊 名:OS_CFG.H任 務:定義配置常量*/#define OS_LOWEST_PRIO 20/ 最低優(yōu)先級不能大于63#define OS_MAX_TASKS 8/ TCB數(shù)量至少大于2#define TaskStkSize 64/ 定義系統(tǒng)任務棧容量#define OS_TASK_CREATE_EN 1/ 任務建立函數(shù)使能#define OS_MAX_EVENTS 2/ 定義ECB數(shù)量#define OS_MBOX_EN 1/ 郵箱功能使能#define OS_MBOX_POST_EN 1/ OSMboxPost()函數(shù)使能#define O
27、S_TIME_DLY_HMSM_EN 1/ “時分秒毫秒”延時函數(shù)使能#define OS_TASK_IDLE_STK_SIZE TaskStkSize/ 定義空閑任務堆棧容量#define OS_TASK_STAT_STK_SIZE TaskStkSize/ 定義統(tǒng)計任務堆棧容量嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理/*模 塊 名:main任 務:啟動代碼段程序*/#include “includes.h” / C/OS-總頭文件#include “reg51.h”/ MCS51寄存器定義頭文件sbit P31= 0 xb1;/ 定義
28、單片機端口P3.1sbit P32 = 0 xb2;/ 定義單片機端口P3.2OS_EVENT*RxMbox; / 定義2個郵箱指針OS_EVENT *AckMbox;OS_STK Task1Stk100; / 聲明2個任務堆棧OS_STK Task2Stk100;void Task1(void *ppdata) reentrant ;/ 聲明2個任務函數(shù)原型void Task2(void *ppdata) reentrant ;void main (void) OSInit(); / 初始化多任務InitTimer0(); / 設置定時器,用作時鐘節(jié)拍發(fā)生器RxMbox = OSMboxCr
29、eate(void *)0); / 建立2個郵箱AckMbox= OSMboxCreate(void *)0);OSTaskCreate(Task1,(void *)0,&Task1Stk0,10); / 建立2個任務OSTaskCreate(Task2,(void *)0,&Task2Stk0,15);OSStart(); / 啟動多任務嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理/*模 塊 名:Task1任 務:在P3.1端口輸出周期2s的方波信號功能描述:用郵箱發(fā)電平給Task2,等待Task2將電平取反后發(fā)回,在 P3
30、.1端口輸出此電平后在發(fā)給Task2,如此循環(huán)往復*/void Task1(void *ppdata) reentrant INT8U *RxBuf; INT8U SxBuf; INT8U err; ppdata = ppdata; SxBuf = 0 xff; for(;)OSMboxPost(RxMbox,(INT8U *)&SxBuf);/ 發(fā)送電平給Task2/* 等待Task2發(fā)來的反相電平 */RxBuf = (INT8U *)OSMboxPend(AckMbox,0,&err); P31 = *RxBuf;/ 在端口P3.1上輸出電平SxBuf= (* RxBuf
31、);/ 保存P3.1端口輸出電平OSTimeDlyHMSM (0,0,1,0); / 掛起1秒,形成2秒周期的方波 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理/*模 塊 名:Task2任 務:輸出與P3.1端口周期相同、相位相反的方波功能描述:等待Task1通過郵箱發(fā)來的電平信號,取反發(fā)回Task1后在P3.2端口輸出,如此循環(huán)*/void Task2(void *ppdata) reentrant INT8U *RxBuf; INT8U SeBuf; INT8U err; ppdata = ppdata; for(;)/* 等待Task1
32、發(fā)來的電平值 */RxBuf = (INT8U *)OSMboxPend (RxMbox,0,&err); P32 = *RxBuf; / 在端口P3.2上輸出電平SeBuf= (*RxBuf); / Task1發(fā)來的電平值取反OSMboxPost(AckMbox,,(INT8U *)&SeBuf);/ 發(fā)送給Task1 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.6 發(fā)送消息到郵箱中, OSMboxPostOpt() 7.1.6.1 函數(shù)原型INT8U OSMboxPostOpt(OS_EVENT *pevent,
33、void *msg,INT8U opt) reentrantn功能:功能:OSMboxPostOpt()函數(shù)通過郵箱給任務廣播發(fā)送消息,消息是一個指針型變量,消息的數(shù)據(jù)類型允許根據(jù)實際需求而定義成不同的類型。nOSMboxPostOpt()OSMboxPostOpt()函數(shù)的特點函數(shù)的特點n如果消息郵箱中已有消息,則返回錯誤碼,說明消息郵箱已滿。OSMboxPostOpt()立即返回調用者,并丟棄新消息;n如果有任務在等待郵箱里的消息,那么OSMboxPostOpt()允許用戶選擇以下兩種情況之一: q若opt = OS_POST_OPT_NONEOS_POST_OPT_NONE,讓最高優(yōu)先級
34、的任務得到這則消息;q若opt = OS_POST_OPT_BROADCASTOS_POST_OPT_BROADCAST,讓所有等待消息的任務都得到這則消息。一無論哪種情況下,如果得到消息的任務的優(yōu)先級比函數(shù)的調用者優(yōu)先級高,那么得到消息的任務將恢復執(zhí)行,函數(shù)的調用者被掛起,發(fā)生一次任務切換。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理n兩個發(fā)送函數(shù)的比較:兩個發(fā)送函數(shù)的比較:OSMboxPostOpt()函數(shù)與OSMboxPost()函數(shù)相比兩者工作方式相同,都用指針傳遞消息;不同的是OSMboxPost() 只能給一個任務發(fā)送消息,而OS
35、MboxPostOpt()允許將消息廣播給所有的等待郵箱消息的任務,且可以仿真OSMboxPost()。n配置常量:配置常量:OS_MBOX_POST_OPT_EN。n調用者:調用者:可以是任務,也可以是中斷。n函數(shù)參數(shù)函數(shù)參數(shù)npeventpevent 指向即將接受消息的郵箱的指針,它是調OSMboxCreate()函數(shù)建立消息郵箱時的返回值。nmsgmsg 發(fā)送給任務的消息。消息是一個以指針表示的某種數(shù)據(jù)類型的變量,消息的數(shù)據(jù)類型允許根據(jù)實際需求而定義成不同的類型。不允許傳遞一個空指針,因為這樣意味著消息郵箱為空。noptopt 定義發(fā)送消息方式的選項,它有兩種形式: opt = OS_P
36、OST_OPT_NONEOS_POST_OPT_NONE,則定義消息只發(fā)給等待消息 的最高優(yōu)先級任務; opt = OS_POST_OPT_BROADCAST OS_POST_OPT_BROADCAST,則定義讓所有等待消 息的任務都得到消息。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.6.2 返回值OSMboxPostOpt()函數(shù)返回值是錯誤代碼,有如下幾種:qOS_NO_ERROS_NO_ERR 消息發(fā)送成功;qOS_MBOX_FULL OS_MBOX_FULL 箱中已經(jīng)有消息;qOS_ERR_EVENT_TYPEOS_ERR_
37、EVENT_TYPEpevent不是指向郵箱的指針;qOS_ERR_PEVENT_NULLOS_ERR_PEVENT_NULL pevent是空指針;qOS_ERR_POST_NULL_PTROS_ERR_POST_NULL_PTR試圖發(fā)送空指針。根據(jù)規(guī)則,空指針無效。7.1.6.3 原理與實現(xiàn) 基本原理:首先在pevent指向的ECB中檢查等待任務列表,以確定是否有任務在等待消息。如果有在等待消息,再根據(jù)opt參數(shù),調用OSEventTaskRdy()函數(shù)分別發(fā)給所有任務或者最高優(yōu)先級任務,且將它們置于就緒狀態(tài);如果沒有任務在等待消息,則保存消息至ECB。7.1.6.4 應用要點q如需要使用
38、郵箱函數(shù),必須先建立郵箱;q不允許向郵箱發(fā)送空指針,因為這意味著消息郵箱為空;q若想使用本函數(shù),又想壓縮代碼長度,那么可以將OSMboxPost()函數(shù)的配置常量關掉。此時,可以利用OSMboxPostOpt()仿真OSMboxPost()。1.在廣播方式下,函數(shù)的執(zhí)行時間取決于等待郵箱消息的任務的數(shù)量。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.7 無等待地從郵箱中得到消息, OSMboxAccept()7.1.7.1 函數(shù)原型void *OSMboxAccept( OS_EVENT *pevent ) reentrantn功能:功
39、能:OSMboxAccept()函數(shù)用于查看指定的消息郵箱是否有需要的消息。n比較:比較:OSMboxPend()函數(shù)的功能與之相似,不同點在于:n如果郵箱中沒有需要的消息,OSMboxPend()函數(shù)將掛起任務,而OSMboxAccept()函數(shù)不掛起任務;n中斷可以調用OSMboxAccept()函數(shù),而不能調用OSMboxPend()函數(shù),因為中斷不允許掛起等待消息。使用OSMboxAccept()函數(shù)時,如果消息已經(jīng)到達,該消息被傳遞到用戶任務,并且從消息郵箱中清除。n參數(shù):參數(shù):pevent 是指向需要查看的消息郵箱的指針,它是調用OSMboxCreate()函數(shù)建立消息郵箱時的返回
40、值。n調用者:調用者:可以是任務,也可以是中斷。一一配置常量:配置常量:OS_MBOX_ACCEPT_EN。 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.7.2 返回值OSMboxAccept()函數(shù)的返回值如下:q如果消息已經(jīng)到達,返回指向該消息的指針;q如果消息郵箱沒有消息,返回空指針。7.1.7.3 原理與實現(xiàn) 基本原理:從pevent指向的ECB中,直接讀取保存消息的成員變量 . .OSEventPtr,不管其中有沒有消息,都取走并清空。OS_EVENT *ComMbox;void Task (void *ppdata) re
41、entrant void *msg; ppdata = ppdata; for (;) msg = OSMboxAccept(ComMbox); / 檢查消息郵箱是否有消息 if (msg != (void *)0) / 如果郵箱中有消息 應用程序; else / 如果郵箱中沒有消息 應用程序; .7.1.7.4 應用范例嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.8 查詢一個郵箱的狀態(tài), OSMboxQuery()7.1.8.1 函數(shù)原型INT8U OSMboxQuery(OS_EVENT *pevent, OS_MBOX_DATA
42、 *ppdata) reentrantn功能:功能:OSMboxQuery()OSMboxQuery()用于查詢一個郵箱的當前狀態(tài),用于查詢一個郵箱的當前狀態(tài),查詢的內容包括:查詢的內容包括:n郵箱事件控制塊中的消息指針;郵箱事件控制塊中的消息指針;n當前的等待任務列表當前的等待任務列表OSEventTblOSEventTbl和和OSEventGrpOSEventGrp,n但不包括但不包括.OSEventCnt.OSEventCnt和和.OSEventType.OSEventType。n在調用該函數(shù)之前,必須定義一個新的數(shù)據(jù)結構,用于在調用該函數(shù)之前,必須定義一個新的數(shù)據(jù)結構,用于復制郵箱復制
43、郵箱ECBECB中的某些成員變量,這個新數(shù)據(jù)結構復制中的某些成員變量,這個新數(shù)據(jù)結構復制的不是整個事件控制塊中的內容,而只是與指定郵箱相的不是整個事件控制塊中的內容,而只是與指定郵箱相關的內容。關的內容。n調用者:調用者:因為因為OSMboxQuery()OSMboxQuery()函數(shù)無需等待,所以可以函數(shù)無需等待,所以可以是任務,也可以是中斷。是任務,也可以是中斷。一一配置常量:配置常量:OS_MBOX_QUERY_ENOS_MBOX_QUERY_EN。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理n函數(shù)參數(shù)函數(shù)參數(shù)npevent peven
44、t 是指向即將查詢的郵箱的指針,它是調用OSMboxCreate()函數(shù)建立消息郵箱時的返回值。nppdata 是指向OS_MBOX_DATA數(shù)據(jù)結構的指針,數(shù)據(jù)結構包含如下成員變量:void void * *OSMsgOSMsg 消息郵箱中消息指針的復制;INT8U OSEventTblINT8U OSEventTbl 郵箱中等待列表的復制;INT8U OSEventGrpINT8U OSEventGrp 等待任務所在組的復制。7.1.8.2 返回值OSMboxQuery()函數(shù)的返回值是錯誤代碼,有如下幾種:nOS_NO_ERROS_NO_ERR 調用成功;nOS_ERR_PEVENT_N
45、ULLOS_ERR_PEVENT_NULL pevent 是空指針nOS_ERR_EVENT_TYPEOS_ERR_EVENT_TYPEpevent 不是指向消息郵箱的指針。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.1.8.3 原理與實現(xiàn) 基本原理:將pevent指向的ECB數(shù)據(jù)結構中的相關數(shù)據(jù)復制到OS_MBOX_DATA數(shù)據(jù)結構中。 程序清單程序清單7.117.11 OSMboxQuery() OSMboxQuery()應用范例應用范例OS_EVENT *RxMbox; void Task (void *ppdata) reentr
46、ant OS_MBOX_DATA cbox_data; INT8U err; ppdata = ppdata; for (;) . err = OSMboxQuery(RxMbox,&cbox_data); if (err = = OS_NO_ERR) 應用程序; 應用程序; 7.1.8.4 應用范例嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.2 消息隊列管理 嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.2.1 概述概念:消息隊列是一種以消息鏈表的方式進行通信的機制,它可以使
47、一個任務或者中斷服務子程序向另一個任務發(fā)送以指針方式定義的變量。 從本質上說,消息隊列是一個郵箱陣列。每個指針指向的數(shù)據(jù)結構,允許根據(jù)實際需求而定義成不同的類型。7.2.1.1 消息隊列的特點n由于實現(xiàn)消息隊列需要事件控制塊、隊列控制塊等多種數(shù)據(jù)結構,所以它增加了管理的負擔;n消息隊列通信機制非??旖荩籲消息隊列機制是異步信息處理,不是實時的。7.2.1.2 使用條件n在OS_CFG.H 文件中,應該將OS_Q_EN常數(shù)設置為1;n通過設置配置常量OS_MAX_QS 2來決定C/OS-支持的最多消息隊列數(shù);n必須定義一個含有與消息隊列最大消息數(shù)相同個數(shù)的指針數(shù)組;1.在使用一個消息隊列之前,必
48、須先建立該消息隊列。這可以通過調用OSQCreate()函數(shù),并定義消息隊列中的單元數(shù)(消息數(shù))來完成。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.2.1.3 應用場合q發(fā)送者不需要等待應答時;q當發(fā)送者和接收者有可能不在同一時間運行時;q當與一組接收者中任何一個接收者進行通信時;q對于多個發(fā)送者和接收者之間復雜的交互操作。7.2.1.4 消息隊列管理函數(shù) 表表7.3 7.3 消息隊列函數(shù)一覽表消息隊列函數(shù)一覽表函數(shù)功能調用者OSQCreate()建立消息隊列任務或者啟動代碼OSQDel()刪除消息任務OSQPend()等消息任務OSQP
49、ost()發(fā)消息FIFO任務或者中斷OSQPostFront()發(fā)消息LIFO任務或者中斷OSQPostOpt()發(fā)消息,F(xiàn)IFO或LIFO任務或者中斷OSQAccept()無等待地從隊列中獲得消息任務或者中斷OSQFlush()清空消息隊列任務或者中斷OSQQuery()獲得消息隊列的狀態(tài)任務嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理 7.2.1.5 消息隊列的配置常量 表表7.4 7.4 消息隊列配置常量一覽表消息隊列配置常量一覽表隊列函數(shù)配置常數(shù)說明系統(tǒng)配置OS_Q_EN該常量為0時,屏蔽所有隊列函數(shù)OS_MAX_QS決定隊列的最大數(shù)
50、目,為0時,屏蔽所有隊列函數(shù)OS_MAX_EVENTS決定隊列的最大數(shù)目OSQCreate()隊列必須支持這兩個函數(shù),不能單獨屏蔽,所以無配置常量OSQPend()OSQDel()OS_Q_DEL_ENOSQPost()OS_Q_POST_EN這3個函數(shù)至少要選擇其中的一個OSQPostFront()OS_Q_FRONT_ENOSQPostOpt()OS_Q_POST_OPT_ENOSQAccept()OS_Q_ACCEPT_ENOSQFlush()OS_Q_FLUSH_ENOSQQuery()OS_Q_QUERY_EN嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第
51、七章 消息管理消息管理7.2.1.6 任務、中斷服務子程序和消息隊列之間的關系 OSQCreate()OSQDel()OSQPost()OSQPostFront()OSQPostOpt()OSQFlush()OSQPost()OSQPostFront()OSQPostOpt()OSQFlush()任務任務中斷中斷任務任務中斷中斷nOSQPend()OSQAccept()OSQQuery()OSQAccept()n n則消息則消息0圖圖7.47.4任務、中斷服務子程序和消息隊列之間的關系任務、中斷服務子程序和消息隊列之間的關系嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七
52、章第七章 消息管理消息管理7.2.2 實現(xiàn)消息隊列所需要的各種數(shù)據(jù)結構 圖圖7.5 7.5 用于消息隊列的各種數(shù)據(jù)結構用于消息隊列的各種數(shù)據(jù)結構 事件控制塊隊列控制塊消息隊列嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理一、隊列控制塊1 1、隊列控制塊數(shù)據(jù)結構、隊列控制塊數(shù)據(jù)結構 隊列控制塊是一個用于維護消息隊列的數(shù)據(jù)結構,其代碼如程序清單7.12所示。 程序清單程序清單7.12 隊列控制塊隊列控制塊typedef struct os_q / 隊列控制塊數(shù)據(jù)結構 struct os_q *OSQPtr; / 在空閑隊列控制塊鏈表中鏈接下一個隊列
53、控制塊的/ 指針,一旦消息隊列建立,該變量就不再有用了。 void*OSQStart; / 指向消息隊列的指針數(shù)組的起始地址的指針,用戶/ 應用程序在使用消息隊列之前必須先定義該數(shù)組。void*OSQEnd; / 指向消息隊列結束單元的下一個地址的指針,該指/ 針使得消息隊列構成一個循環(huán)的緩沖區(qū)。 void*OSQIn; / 指向消息隊列中插入下一條消息的位置的指針,/ 當.OSQIn和.OSQEnd相等時,.OSQIn被調整指向/ 消息隊列的起始單元。 void *OSQOut; / 指向消息隊列中下一個取出消息的位置的指針。 INT16U OSQSize; / 消息隊列中總的單元數(shù),最大值
54、為65,536。INT16U OSQEntries; / 消息隊列中當前的消息數(shù)量,當消息隊列為空時,/ 該值為0。/ 當消息隊列滿了以后,該值和.OSQSize值一樣。 在/ 消息隊列剛剛建立時,該值為0。 OS_Q;嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理圖圖7.6 7.6 空閑隊列控制塊鏈表空閑隊列控制塊鏈表 2 2、空閑隊列控制塊鏈表、空閑隊列控制塊鏈表 息隊列的最大消息數(shù)由OS_CFG.H文件中的配置常量OS_MAX_QS決定,當這個值和OS_Q_EN為0時,所有隊列功能都不能使用。當C/OS-在初始化時,會根據(jù)OS_MAX_Q
55、S的值建立一個空閑隊列控制塊鏈表,如圖7.6所示。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理圖圖7.7 7.7 由指針組成的消息隊列循環(huán)緩沖區(qū)由指針組成的消息隊列循環(huán)緩沖區(qū) 二、消息隊列 消息隊列的核心是一個循環(huán)緩沖區(qū),如圖7.7所示,詳細說明如下:* *.OSQSize(3).OSQStart(5).OSQEnd(5).OSQOut(4).OSQOut(2).OSQIn(1)指向消息的指針指向消息的指針.OSQEntries(3)嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.2.3 建
56、立一個消息隊列,OSQCreate() 7.2.3.1 函數(shù)原型OS_EVENT *OSQCreate( void *start,INT16U size) reentrantn功能:功能:OSQCreate()函數(shù)用于建立一個消息隊列,任務或中斷可函數(shù)用于建立一個消息隊列,任務或中斷可以通過消息隊列向其它一個或多個任務發(fā)送消息,消息的含義是以通過消息隊列向其它一個或多個任務發(fā)送消息,消息的含義是和具體的應用密切相關的。和具體的應用密切相關的。n配置常量:配置常量:沒有單獨的配置常量。沒有單獨的配置常量。n函數(shù)參數(shù)函數(shù)參數(shù)nstart 是消息內存區(qū)的基地址,消息內存區(qū)是一個指針數(shù)組,指針數(shù)組必是
57、消息內存區(qū)的基地址,消息內存區(qū)是一個指針數(shù)組,指針數(shù)組必須聲明為須聲明為void 類型;類型;nsize 是消息內存區(qū)的容量。是消息內存區(qū)的容量。7.2.3.2 返回值n如果隊列建立成功,如果隊列建立成功,OSQCreate()函數(shù)返回一個指向消息隊列事函數(shù)返回一個指向消息隊列事件控制塊的指針;件控制塊的指針;一一如果沒有空閑的事件塊,說明建立不成功,如果沒有空閑的事件塊,說明建立不成功,OSQCreate()函數(shù)返函數(shù)返回空指針?;乜罩羔?。嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.2.3.3 原理與實現(xiàn)基本原理:分別從空閑基本原理:分
58、別從空閑ECB鏈表和空閑隊列控制塊鏈表中各取一個控鏈表和空閑隊列控制塊鏈表中各取一個控制塊,對這制塊,對這2個控制塊進行初始化配置,并將隊列控制塊鏈接到個控制塊進行初始化配置,并將隊列控制塊鏈接到ECB中,最后返回的指針即為消息隊列的指針。中,最后返回的指針即為消息隊列的指針。7.2.3.4 應用范例 程序清單程序清單7.14 OSQCreate()應用范例應用范例OS_EVENT *TaskQ; / 定義一個ECB類型的指針void *ComMsg20;/ 定義一個指針數(shù)組,用于保存消息指針void main(void) OSInit(); / 初始化C/OS- TaskQ = OSQCre
59、ate(&ComMsg0, 20); / 建立消息隊列 OSStart(); / 啟動多任務內核嵌入式實時操作系統(tǒng)嵌入式實時操作系統(tǒng)C/OS-C/OS-教程教程 第七章第七章 消息管理消息管理7.2.4 刪除一個消息隊列,OSQDel() 7.2.4.1 函數(shù)原型OS_EVENT *OSQDel(OS_EVENT *pevent,INT8U opt,INT8U *err)reentrantn功能:功能:OSQDel()函數(shù)用于刪除消息隊列。函數(shù)用于刪除消息隊列。n函數(shù)參數(shù)函數(shù)參數(shù)qpevent 是指向即將被刪除的消息隊列的指針,它是調用是指向即將被刪除的消息隊列的指針,它是調用OSQC
60、reate()函數(shù)建立隊列時的返回值。函數(shù)建立隊列時的返回值。qopt定義消息隊列刪除條件的選項,它有如下定義消息隊列刪除條件的選項,它有如下2種選擇:種選擇:qOS_DEL_NO_PEND 只能在沒有任何任務等待該消息隊列的消息時,只能在沒有任何任務等待該消息隊列的消息時,才能刪除消息隊列;才能刪除消息隊列;qOS_DEL_ALWAYS 不管有沒有任務在等待隊列消息,都立即刪除消不管有沒有任務在等待隊列消息,都立即刪除消息隊列。刪除后,所有等待消息的任務立即進入就緒狀態(tài)。息隊列。刪除后,所有等待消息的任務立即進入就緒狀態(tài)。qerr指向錯誤代碼的指針,錯誤代碼有以下幾種:指向錯誤代碼的指針,錯誤代碼有以下幾種:nOS_NO_ERR 消息隊列刪除成功;消息隊列刪除成
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論