實現了迴圈訊息佇列,在初始化的時候分配記憶體。
其中用到了互斥器,可自行實現,或在本部落格中尋找相關實現方法。
/**<br />* @file MQ.h<br />* @brief 實現了訊息佇列的封裝<br />* @author Donhao<br />* @date 2010-4-17 12:57:57<br />* @version<br />* <pre><b>All rights reserved.</b></pre><br />* <pre><b>modification:</b></pre><br />* <pre>Write modifications here.</pre><br />*/<br />#ifndef _MQ_H<br />#define _MQ_H</p><p>/** @brief 寫訊息佇列傳回值 */<br />typedef enum<br />{<br /> MQ_Write_Result_Ok = 0x11, /**< 隊列未滿 */<br /> MQ_Write_Result_Error = 0x22, /**< 隊列已滿 */<br /> MQ_Write_Result_Full = 0x33 /**< 寫隊列失敗 */<br />}MQ_Write_Result_Enum;</p><p>typedef struct<br />{<br /> unsigned long msgSize;<br /> unsigned char* pMsg;<br />} MQ_Msg_Struct;</p><p>typedef struct<br />{<br /> unsigned long initialized; /**< 是否初始化了 */<br /> unsigned long maxMsgNum; /**< MQ中最大訊息個數 */<br /> unsigned long maxMsgSize; /**< 每條訊息的最大位元組數 */<br /> int front; /**< 頭指標 */<br /> int rear; /**< 尾指標 */<br /> unsigned long msgNum; /**< 訊息佇列中訊息個數 */<br /> MUTEX mutex; /**< 保護訊息佇列的互斥器 */<br /> MQ_Msg_Struct* pMQMsg; /**< 指向第一條訊息 */<br />} MQ_Struct;</p><p>/**<br />* @brief MQ_Init<br />*<br />* Detailed description.<br />* @param[in] pMQ 要初始化的訊息佇列<br />* @param[in] maxMsgNum 訊息佇列大小<br />* @param[in] maxMsgSize 每條訊息的大小<br />* @return BOOL<br />*/<br />BOOL MQ_Init(MQ_Struct* pMQ, unsigned long maxMsgNum, unsigned long maxMsgSize);</p><p>/**<br />* @brief MQ_Get_Msg_Num<br />*<br />* Detailed description.<br />* @param[in] pMQ 要獲得訊息個數的訊息佇列<br />* @return int 若失敗則返回-1,否則返回訊息個數<br />*/<br />int MQ_Get_Msg_Num(const MQ_Struct* pMQ);</p><p>/**<br />* @brief MQ_Write<br />*<br />* Detailed description.<br />* @param[in] pMQ 要寫的訊息佇列<br />* @param[in] pMsg 要寫的訊息<br />* @param[in] size 要寫的訊息大小<br />* @return MQ_Write_Result_Enum<br />*/<br />MQ_Write_Result_Enum MQ_Write(MQ_Struct* pMQ, const unsigned char* pMsg, unsigned long size);</p><p>/**<br />* @brief MQ_Read<br />*<br />* Detailed description.<br />* @param[in] pMQ 要讀的訊息佇列<br />* @param[in] pOutBuf 要輸出訊息的緩衝區<br />* @param[in/out] pSize 作為輸入參數時為輸出的緩衝區訊息大小,作為輸出參數為讀到的訊息大小<br />* @return BOOL<br />*/<br />BOOL MQ_Read(MQ_Struct* pMQ, unsigned char* pOutBuf, unsigned long* pSize);</p><p>/**<br />* @brief MQ_Get<br />*<br />* 僅讀取資料,而不彈出.<br />* @param[in] pMQ<br />* @param[in] index<br />* @param[in] pOutBuf<br />* @param[in] pSize<br />* @return BOOL<br />*/<br />BOOL MQ_Get(MQ_Struct* pMQ, unsigned long index, unsigned char* pOutBuf, unsigned long* pSize);</p><p>/**<br />* @brief MQ_Clear<br />*<br />* Detailed description.<br />* @param[in] pMQ 要清空的訊息佇列<br />* @return BOOL<br />*/<br />BOOL MQ_Clear(MQ_Struct* pMQ);</p><p>#endif<br />
/**<br />* @file MQ.c<br />* @brief<br />* @author Donhao<br />* @date 2010-4-17 12:57:43<br />* @version<br />* <pre><b>All rights reserved.</b></pre><br />* <pre><b>modification:</b></pre><br />* <pre>Write modifications here.</pre><br />*/<br />#include "MQ.h"</p><p>#define MQ_INITIALIZE_FLAG 0x1122</p><p>BOOL MQ_Read(MQ_Struct* pMQ, UINT8* pOutBuf, UINT32* pSize)<br />{<br /> BOOL rt = FALSE;</p><p> if ((NULL == pMQ) || (NULL == pOutBuf) || (NULL == pSize)<br /> || (0 == pMQ->msgNum) || (MQ_INITIALIZE_FLAG != pMQ->initialized))<br /> {<br /> rt = FALSE;<br /> }<br /> else<br /> {<br /> Mutex_Lock(pMQ->mutex);</p><p> pMQ->front = (pMQ->front + 1) % pMQ->maxMsgNum;</p><p> --(pMQ->msgNum);</p><p> if (pMQ->pMQMsg[pMQ->front].msgSize > *pSize)<br /> {<br /> rt = FALSE;<br /> }<br /> else<br /> {<br /> memcpy(pOutBuf, pMQ->pMQMsg[pMQ->front].pMsg, pMQ->pMQMsg[pMQ->front].msgSize);<br /> *pSize = pMQ->pMQMsg[pMQ->front].msgSize;</p><p> rt = TRUE;<br /> }</p><p> Mutex_Unlock(pMQ->mutex);<br /> }</p><p> return rt;<br />}</p><p>BOOL MQ_Get(MQ_Struct* pMQ, UINT32 index, UINT8* pOutBuf, UINT32* pSize)<br />{<br /> BOOL rt = FALSE;</p><p> if ((NULL == pMQ) || (NULL == pOutBuf) || (NULL == pSize)<br /> || (index >= pMQ->msgNum) || (MQ_INITIALIZE_FLAG != pMQ->initialized))<br /> {<br /> rt = FALSE;<br /> }<br /> else<br /> {<br /> Mutex_Lock(pMQ->mutex);</p><p> if (pMQ->pMQMsg[(pMQ->front + 1 + index) % pMQ->maxMsgNum].msgSize < *pSize)<br /> {<br /> rt = FALSE;<br /> }<br /> else<br /> {<br /> memcpy(pOutBuf, pMQ->pMQMsg[(pMQ->front + 1 + index) % pMQ->maxMsgNum].pMsg,<br /> pMQ->pMQMsg[(pMQ->front + 1 + index) % pMQ->maxMsgNum].msgSize);<br /> *pSize = pMQ->pMQMsg[(pMQ->front + 1 + index) % pMQ->maxMsgNum].msgSize;</p><p> rt = TRUE;<br /> }</p><p> Mutex_Unlock(pMQ->mutex);<br /> }</p><p> return rt;<br />}</p><p>MQ_Write_Result_Enum MQ_Write(MQ_Struct* pMQ, const UINT8* pMsg, UINT32 size)<br />{<br /> BOOL rt = FALSE;</p><p> if ((NULL == pMQ) || (NULL == pMsg) || (size > pMQ->maxMsgSize)<br /> || (MQ_INITIALIZE_FLAG != pMQ->initialized))<br /> {<br /> rt = MQ_Write_Result_Error;<br /> }<br /> else<br /> {<br /> Mutex_Lock(pMQ->mutex);</p><p> /** @brief 訊息佇列未滿,放入隊列,返回Ok */<br /> pMQ->rear = (pMQ->rear + 1) % pMQ->maxMsgNum;</p><p> memcpy(pMQ->pMQMsg[pMQ->rear].pMsg, pMsg, size);<br /> pMQ->pMQMsg[pMQ->rear].msgSize = size;</p><p> if ((pMQ->maxMsgNum - 1) == pMQ->msgNum)<br /> {<br /> pMQ->front = (pMQ->front + 1) % pMQ->maxMsgNum;</p><p> rt = MQ_Write_Result_Full;<br /> }<br /> else<br /> {<br /> ++(pMQ->msgNum);</p><p> rt = MQ_Write_Result_Ok;<br /> }</p><p> Mutex_Unlock(pMQ->mutex);<br /> }</p><p> return rt;<br />}</p><p>BOOL MQ_Init(MQ_Struct* pMQ, UINT32 maxMsgNum, UINT32 maxMsgSize)<br />{<br /> BOOL rt = FALSE;<br /> UINT32 i = 0;<br /> UINT32 j = 0;</p><p> /** @brief 如果最大訊息個數或每條訊息的最大位元組數為0,則返回錯誤 */</p><p> if ((NULL == pMQ) || (0 == maxMsgNum) || (0 == maxMsgSize))<br /> {<br /> return FALSE;<br /> }</p><p> if (MQ_INITIALIZE_FLAG == pMQ->initialized)<br /> {<br /> return TRUE;<br /> }</p><p> pMQ->pMQMsg = NULL;</p><p> pMQ->msgNum = 0;<br /> pMQ->front = 0;<br /> pMQ->rear = 0;<br /> pMQ->maxMsgNum = maxMsgNum;<br /> pMQ->maxMsgSize = maxMsgSize;<br /> pMQ->pMQMsg = malloc(sizeof(MQ_Msg_Struct) * pMQ->maxMsgNum);</p><p> if (NULL == pMQ)<br /> {<br /> return FALSE;<br /> }</p><p> for (i = 0; i < pMQ->maxMsgNum; ++i)<br /> {<br /> pMQ->pMQMsg[i].pMsg = NULL;<br /> pMQ->pMQMsg[i].pMsg = malloc(pMQ->maxMsgSize);</p><p> /** @brief 如果初始化失敗,則釋放之前分配的資源 */</p><p> if (NULL == pMQ)<br /> {<br /> for (j = i - 1; j >= 0; --j)<br /> {<br /> free(pMQ->pMQMsg[j].pMsg);<br /> pMQ->pMQMsg[j].pMsg = NULL;<br /> }</p><p> free(pMQ->pMQMsg);</p><p> pMQ->pMQMsg = NULL;<br /> return FALSE;<br /> }<br /> else<br /> {<br /> pMQ->pMQMsg[i].msgSize = 0;<br /> memset(pMQ->pMQMsg[i].pMsg, 0, pMQ->maxMsgSize);<br /> }<br /> }</p><p> rt = Mutex_Init(&(pMQ->mutex));</p><p> if (FALSE == rt)<br /> {<br /> return FALSE;<br /> }</p><p> pMQ->initialized = MQ_INITIALIZE_FLAG;</p><p> return TRUE;<br />}</p><p>BOOL MQ_Clear(MQ_Struct* pMQ)<br />{<br /> if ((NULL == pMQ) || (MQ_INITIALIZE_FLAG != pMQ->initialized))<br /> {<br /> return FALSE;<br /> }</p><p> Mutex_Lock(pMQ->mutex);</p><p> pMQ->front = 0;<br /> pMQ->rear = 0;<br /> pMQ->msgNum = 0;</p><p> Mutex_Unlock(pMQ->mutex);</p><p> return TRUE;<br />}</p><p>int MQ_Get_Msg_Num(const MQ_Struct* pMQ)<br />{<br /> if ((NULL == pMQ) || (MQ_INITIALIZE_FLAG != pMQ->initialized))<br /> {<br /> return -1;<br /> }<br /> else<br /> {<br /> return pMQ->msgNum;<br /> }<br />}