/******************************************************************************** * File Name: MsgQueue.c * Function Describe: 共享消息数据缓冲区的消息队列 * Explain: 此消息队列是一个环形数据结构,可以接受消息入队列,并提取消息出队列,队列最多可容纳MSG_QUEUE_NUM_MAX个消息 每个消息队列使用一个环形结构的消息数据缓冲区,该消息队列内的所有消息将共用此数据缓冲区 适用于串口接收的数据处理,尤其适用于与模块的串口接收数据处理。 用法: 先定义消息队列SUT_MSG_QUEUE实例,并定义存放消息数据缓冲区实例 然后用MsgQueueInit初始化消息队列 用MsgQueuePost将消息入队列,入队列时将拷贝消息的数据内容到SUT_MSG_QUEUE实例的数据缓冲区中。 用MsgQueueAccept将从队列中取消息,取消息时将从数据缓冲区中拷贝数据到指定的其他非环形缓冲区,以便处理消息 * Writer: ShiLiangWen * Date: 2015-7-2 *******************************************************************************/ #define THIS_FILE_ID 5 /********************************************************************************/ #include "includes.h" /******************************************************************************************** * *********************************************************************************************/ void MsgQueueInit(SUT_MSG_QUEUE *pMsgQueue,char *pDataBuffer,unsigned short DataBufferLenMax) { int i; pMsgQueue->MsgIn=0; pMsgQueue->MsgNum=0; pMsgQueue->MsgOut=0; for(i=0;iMsgQueue[i].DataStartIndex=0; pMsgQueue->MsgQueue[i].MsgLen=0; } // pMsgQueue->DataBuffer=pDataBuffer; for(i=0;iDataBuffer[i]=0; pMsgQueue->DataBufferLenMax=DataBufferLenMax; pMsgQueue->DataBufferIn=0; pMsgQueue->DataBufferOut=0; pMsgQueue->DataBufferLen=0; } /******************************************************************************************** * *********************************************************************************************/ void MsgQueuePost(SUT_MSG_QUEUE *pMsgQueue,char *pData,unsigned short DataLen) { unsigned short i; //队列满,不允许再入队列 if(pMsgQueue->MsgNum>=MSG_QUEUE_NUM_MAX){ //SlwTrace("MsgQueue full!\r\n"); return; } //数据缓冲区不够,不允许入队列 if((DataLen+pMsgQueue->DataBufferLen)>pMsgQueue->DataBufferLenMax){ //SlwTrace("DataBuffer full!\r\n"); return; } RunMake(THIS_FILE_ID); //消息入队列 pMsgQueue->MsgQueue[pMsgQueue->MsgIn].DataStartIndex=pMsgQueue->DataBufferIn; pMsgQueue->MsgQueue[pMsgQueue->MsgIn].MsgLen=DataLen; RunMake(THIS_FILE_ID); //消息数据入缓冲区 for(i=0;iDataBuffer[pMsgQueue->DataBufferIn]=pData[i]; pMsgQueue->DataBufferIn++; if(pMsgQueue->DataBufferIn>=pMsgQueue->DataBufferLenMax)pMsgQueue->DataBufferIn=0; pMsgQueue->DataBufferLen++; } RunMake(THIS_FILE_ID); //消息个数增加 pMsgQueue->MsgIn++; if(pMsgQueue->MsgIn>=MSG_QUEUE_NUM_MAX)pMsgQueue->MsgIn=0; pMsgQueue->MsgNum++; } /******************************************************************************************** * *********************************************************************************************/ void MsgQueuePostLoopBuf(SUT_MSG_QUEUE *pMsgQueue,char *pLoopBuf,unsigned short LoopDataBufLen,unsigned short LoopDataStart,unsigned short DataLen) { unsigned short i; unsigned short LoopDataIndex; //队列满,不允许再入队列 if(pMsgQueue->MsgNum>=MSG_QUEUE_NUM_MAX){ SlwTrace(DEBUG,"MsgQueue full!\r\n"); return; } //数据缓冲区不够,不允许入队列 if((DataLen+pMsgQueue->DataBufferLen)>=pMsgQueue->DataBufferLenMax){ SlwTrace(DEBUG,"MsgQueue DataBuffer full!\r\n"); return; } RunMake(THIS_FILE_ID); //消息入队列 pMsgQueue->MsgQueue[pMsgQueue->MsgIn].DataStartIndex=pMsgQueue->DataBufferIn; pMsgQueue->MsgQueue[pMsgQueue->MsgIn].MsgLen=DataLen; RunMake(THIS_FILE_ID); //消息数据入缓冲区 LoopDataIndex=LoopDataStart; for(i=0;iDataBuffer[pMsgQueue->DataBufferIn]=pLoopBuf[LoopDataIndex]; if(++LoopDataIndex>=LoopDataBufLen)LoopDataIndex=0; pMsgQueue->DataBufferIn++; if(pMsgQueue->DataBufferIn>=pMsgQueue->DataBufferLenMax)pMsgQueue->DataBufferIn=0; pMsgQueue->DataBufferLen++; } RunMake(THIS_FILE_ID); //消息个数增加 pMsgQueue->MsgIn++; if(pMsgQueue->MsgIn>=MSG_QUEUE_NUM_MAX)pMsgQueue->MsgIn=0; pMsgQueue->MsgNum++; RunMake(THIS_FILE_ID); } /******************************************************************************************** 提取pMsgQueue消息,并放入pBuf中,给定pBuf空间长度为BufLen 返回r: r=0 --无消息 r>0 --有消息,并已拷贝消息数据到pData,r为消息数据长度 r<0 --有消息,但接受数据缓冲区长度不够,r为长度的负数 *********************************************************************************************/ int MsgQueueAccept(SUT_MSG_QUEUE *pMsgQueue,char *pBuf,unsigned short BufLen) { int len; unsigned short i,j; char data; SUT_MESSAGE msg; tsk_lock (); BufLen-=1;//流出一个字节保存/0 RunMake(THIS_FILE_ID); if(pMsgQueue->MsgNum==0){ tsk_unlock (); return 0; } msg.MsgLen = pMsgQueue->MsgQueue[pMsgQueue->MsgOut].MsgLen; msg.DataStartIndex = pMsgQueue->MsgQueue[pMsgQueue->MsgOut].DataStartIndex; j=0; for(i=0;iDataBufferLen)break; data=pMsgQueue->DataBuffer[pMsgQueue->DataBufferOut]; pMsgQueue->DataBufferOut++; if(pMsgQueue->DataBufferOut>=pMsgQueue->DataBufferLenMax)pMsgQueue->DataBufferOut=0; pMsgQueue->DataBufferLen--; if(jMsgOut++; if(pMsgQueue->MsgOut>=MSG_QUEUE_NUM_MAX)pMsgQueue->MsgOut=0; pMsgQueue->MsgNum--; pBuf[j]=0; RunMake(THIS_FILE_ID); if(i!=msg.MsgLen){ SlwTrace(DEBUG,"MsgQueueAccept Err=-2\r\n"); len=-1*msg.MsgLen; tsk_unlock (); return len;//Databuffer len error! } if(msg.MsgLen>BufLen){ SlwTrace(DEBUG,"MsgQueueAccept Err=-1\r\n"); len=-1*msg.MsgLen; tsk_unlock (); return len; }else{ tsk_unlock (); return msg.MsgLen; } } /******************************************************************************************** * *********************************************************************************************/