FREERTOS-简化版消息队列

此处消息队列源自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****
队列为空,出队失败

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值