簡介 使用消息隊列可以在任務之間傳遞多條消息。消息隊列由三個部分組成:事件控制塊、消息隊列和消息。 當把事件控制塊成員 OSEventType 的值置為 OS_EVENT_TYPE_Q 時,該事件控制塊描述的就是一個消息隊列。 消息隊列相當於一個共用一個任務等待列表的消息郵箱數組,事件控制塊成員 O ...
簡介
使用消息隊列可以在任務之間傳遞多條消息。消息隊列由三個部分組成:事件控制塊、消息隊列和消息。
當把事件控制塊成員 OSEventType 的值置為 OS_EVENT_TYPE_Q 時,該事件控制塊描述的就是一個消息隊列。
消息隊列相當於一個共用一個任務等待列表的消息郵箱數組,事件控制塊成員 OSEventPtr 指向了一個叫做隊列控制塊(OS_Q)的結構,該結構管理了一個數組 MsgTbl[ ],該數組中的元素都是一些指向消息的指針。
消息隊列的數據結構
其中,可以移動的指針為 OSQIn 和 OSQOut,而指針 OSQStart 和 OSQEnd 只是一個標誌(常指針)。當可移動的指針 OSQIn 或 OSQOut 移動到數組末尾,也就是與 OSQEnd 相等時,可移動的指針將會被調整到數組的起始位置 OSQStart。也就是說,從效果上來看,指針 OSQEnd 與 OSQStart 等值。於是,這個由消息指針構成的數組就頭尾銜接起來形成了一個如下圖所示的迴圈的隊列。
為了對圖所示的消息指針數組進行有效的管理,μC/OS-II 把消息指針數組的基本參數都記錄在一個叫做隊列控制塊的結構中,隊列控制塊的結構如下:
typedef struct os_q
{
struct os_q *OSQPtr;
void **OSQStart;
void **OSQEnd;
void **OSQIn;
void **OSQOut;
INT16U OSQSize;
INT16U OSQEntries;
} OS_Q;
消息隊列的創建
創建一個消息隊列首先需要定義一指針數組,然後把各個消息數據緩衝區的首地址存入這個數組中,然後再調用函數 OSQCreate( ) 來創建消息隊列。創建消息隊列函數 OSQCreate( ) 的原型為:
OS_EVENT OSQCreate(
void **start, //指針數組的地址
INT16U size //數組長度
);
請求消息隊列
請求消息隊列的目的是為了從消息隊列中獲取消息。任務請求消息隊列需要調用函數 OSQPend( ),該函數的原型為:
void *OSQPend(
OS_EVENT *pevent, //所請求的消息隊列的指針
INT16U timeout, //等待時限
INT8U *err //錯誤信息
);
向消息隊列發送消息
任務需要通過調用函數 OSQPost( ) 或 OSQPostFront( ) 來向消息隊列發送消息。函數 OSQPost( ) 以 FIFO(先進先出)的方式組織消息隊列,函數 OSQPostFront( ) 以 LIFO(後進先出)的方式組織消息隊列。這兩個函數的原型分別為:
INT8U OSQPost(
OS_EVENT *pevent, //消息隊列的指針
void *msg //消息指針
);
INT8U OSQPostFront(
OS_EVENT *pevent, //消息隊列的指針
void *msg //消息指針
);
函數中的參數 msg 為待發消息的指針。
參考自:《μC/OS-II 入門教程》