此处消息队列源自FREERTOS,还是采用先进先出的方式.去掉任务,信号量,等待等等功能。最后的流程打印很容易看。
// queue-01.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdlib.h"
/* exact-width signed integer types */
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
// typedef signed __INT64 int64_t;
/* exact-width unsigned integer types */
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
// typedef unsigned __INT64 uint64_t;
typedef struct QueueDefinition
{
int8_t *pcHead; /*指向队列存储区开始地址。< Points to the beginning of the queue storage area. */
int8_t *pcTail; /*指向队列存储区最后一个字节< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */
int8_t *pcWriteTo; /*指向存储区中下一个空闲区域。< Points to the free next place in the storage area. */
int8_t *pcReadFrom; /*当用作队列的时候指向最后一个出队的队列项首地址< Points to the last place that a queued item was read from when the structure is used as a queue. */
uint32_t uxMessagesWaiting; /*队列中当前队列项数量,也就是消息数 < The number of items currently in the queue. */
uint32_t uxLength; /*创建队列时指定的队列长度,也就是队列中最大允许的队列项(消息)数量< The length of the queue defined as the number of items it will hold, not the number of bytes. */
uint32_t uxItemSize; /*创建队列时指定的每个队列项(消息)最大长度,单位字节< The size of each items that the queue will hold. */
} Queue_t;
int xQueueGenericCreateStatic(Queue_t *pxQueue,const uint32_t uxQueueLength, const uint32_t uxItemSize,uint8_t *QueueStorageHead)
{
Queue_t *const pxNewQueue = pxQueue;
//printf("xQueueGenericCreate uxQueueLength=%d uxItemSize=%d *****\r\n",uxQueueLength,uxItemSize);
if ((uxItemSize == (uint32_t)0)|| (uxQueueLength == (uint32_t)0))
{
//printf("队列个数,和队列元素大小不能为0 \r\n");
return 1;
}
pxNewQueue->pcHead = (int8_t *)QueueStorageHead;
pxNewQueue->uxLength = uxQueueLength;
pxNewQueue->uxItemSize = uxItemSize;
pxQueue->pcTail = pxQueue->pcHead + (pxQueue->uxLength * pxQueue->uxItemSize);
pxQueue->uxMessagesWaiting = (uint32_t)0U;
pxQueue->pcWriteTo = pxQueue->pcHead;
pxQueue->pcReadFrom = pxQueue->pcHead + ((pxQueue->uxLength - (uint32_t)1U) * pxQueue->uxItemSize);
//printf("pxNewQueue->pcHead= %#x pxNewQueue->pcTail = %#x pxNewQueue->pcWriteTo= %#x pxNewQueue->pcReadFrom=%#x \r\n",pxNewQueue->pcHead,pxNewQueue->pcTail,pxNewQueue->pcWriteTo,pxNewQueue->pcReadFrom);
return 0;
}
void prvCopyDataToQueue(Queue_t *const pxQueue, const void *pvItemToQueue)
{
//BaseType_t xReturn = pdFALSE;
uint32_t uxMessagesWaiting;
uxMessagesWaiting = pxQueue->uxMessagesWaiting;
//if (xPosition == queueSEND_TO_BACK)
(void)memcpy((void *)pxQueue->pcWriteTo, pvItemToQueue, (size_t)pxQueue->uxItemSize); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. */
pxQueue->pcWriteTo += pxQueue->uxItemSize;
if (pxQueue->pcWriteTo >= pxQueue->pcTail) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */
{
pxQueue->pcWriteTo = pxQueue->pcHead;
//printf("pxQueue->pcWriteTo >= pxQueue->pcTail 从头开始 \r\n");
}
pxQueue->uxMessagesWaiting = uxMessagesWaiting + 1;
//return xReturn;
}
int xQueueGenericSend(Queue_t * xQueue, const void *const pvItemToQueue)
{
Queue_t *const pxQueue = (Queue_t *)xQueue;
//printf("xQueueGenericSend******\r\n");
if ((pxQueue->uxMessagesWaiting < pxQueue->uxLength) )
{
prvCopyDataToQueue(pxQueue, pvItemToQueue);
//printf("pxQueue->pcHead= %#x pxQueue->pcTail = %#x pxQueue->pcWriteTo= %#x pxQueue->pcReadFrom=%#x \r\n",pxQueue->pcHead,pxQueue->pcTail,pxQueue->pcWriteTo,pxQueue->pcReadFrom);
return 0;
}
else{
//printf("*****队列已满不能入队***** \r\n");
return 1;
}
}
void prvCopyDataFromQueue(Queue_t *const pxQueue, void *const pvBuffer)
{
if (pxQueue->uxItemSize != (uint32_t)0)
{
pxQueue->pcReadFrom += pxQueue->uxItemSize;
if (pxQueue->pcReadFrom >= pxQueue->pcTail) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */
{
pxQueue->pcReadFrom = pxQueue->pcHead;
}
(void)memcpy((void *)pvBuffer, (void *)pxQueue->pcReadFrom, (size_t)pxQueue->uxItemSize); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */
}
}
int xQueueGenericReceive(Queue_t * xQueue, void *const pvBuffer)
{
Queue_t *const pxQueue = (Queue_t *)xQueue;
const uint32_t uxMessagesWaiting = pxQueue->uxMessagesWaiting;
//printf("xQueueGenericReceive**** \r\n");
/* Is there data in the queue now? To be running the calling task
must be the highest priority task wanting to access the queue. */
if (uxMessagesWaiting > (uint32_t)0)
{
/* Remember the read position in case the queue is only being
peeked. */
prvCopyDataFromQueue(pxQueue, pvBuffer);
pxQueue->uxMessagesWaiting = uxMessagesWaiting - 1;
//printf("pxQueue->pcHead= %#x pxQueue->pcTail = %#x pxQueue->pcWriteTo= %#x pxQueue->pcReadFrom=%#x \r\n",pxQueue->pcHead,pxQueue->pcTail,pxQueue->pcWriteTo,pxQueue->pcReadFrom);
return 0;
}else{
//printf("队列为空,出队失败 \r\n");
return 1;
}
}
int buffer[160];
int _tmain(int argc, _TCHAR *argv[])
{
Queue_t queue_com;
xQueueGenericCreateStatic(&queue_com,4,16,(uint8_t*)&buffer[0]);
int buf_0[4];
int buf_read[4];
int ret;
int i;
for(i=0;i<4;i++){
buf_0[i]=123+i;
}
xQueueGenericSend(&queue_com,buf_0);
xQueueGenericSend(&queue_com,buf_0);
xQueueGenericSend(&queue_com,buf_0);
xQueueGenericSend(&queue_com,buf_0);
xQueueGenericSend(&queue_com,buf_0);
for (i=0;i<10;i++){
ret = xQueueGenericReceive(&queue_com,buf_read);
if (ret == 0){
for(int j=0;j<4;j++){
printf("buf_read[%d]= %d \r\n",j,buf_read[j]);
}
}else{
break;
}
}
return 0;
}
最终的流程打印如下:
xQueueGenericCreate uxQueueLength=4 uxItemSize=16 *****
pxNewQueue->pcHead= 0x658138 pxNewQueue->pcTail = 0x658178 pxNewQueue->pcWriteTo= 0x658138 pxNewQueue->pcReadFrom=0x658168
xQueueGenericSend******
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658148 pxQueue->pcReadFrom=0x658168
xQueueGenericSend******
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658158 pxQueue->pcReadFrom=0x658168
xQueueGenericSend******
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658168 pxQueue->pcReadFrom=0x658168
xQueueGenericSend******
pxQueue->pcWriteTo >= pxQueue->pcTail 从头开始
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658138 pxQueue->pcReadFrom=0x658168
xQueueGenericSend******
队列已满不能入队
xQueueGenericReceive****
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658138 pxQueue->pcReadFrom=0x658138
buf_read[0]= 123
buf_read[1]= 124
buf_read[2]= 125
buf_read[3]= 126
xQueueGenericReceive****
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658138 pxQueue->pcReadFrom=0x658148
buf_read[0]= 123
buf_read[1]= 124
buf_read[2]= 125
buf_read[3]= 126
xQueueGenericReceive****
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658138 pxQueue->pcReadFrom=0x658158
buf_read[0]= 123
buf_read[1]= 124
buf_read[2]= 125
buf_read[3]= 126
xQueueGenericReceive****
pxQueue->pcHead= 0x658138 pxQueue->pcTail = 0x658178 pxQueue->pcWriteTo= 0x658138 pxQueue->pcReadFrom=0x658168
buf_read[0]= 123
buf_read[1]= 124
buf_read[2]= 125
buf_read[3]= 126
xQueueGenericReceive****
队列为空,出队失败