Note:
本代码用C语言编写,已经用于实际的项目中,在队列的申请过程中,也进行错误判断,可通过错误判断函数中枚举类型的值来判断,队列哪个过程出现错误。此外对于使用c++的朋友,本人建议将该数据结构封装成一个类来使用,将其操作函数变成成员函数,变量改为私有变量。(并发操作过程中,应给队列加锁,如在结构体或类中定义锁机制)
头文件queue.h
#ifndef _QUEUE_H
#define _QUEUE_H
typedef unsigned char Q_U8Data;
typedef unsigned short Q_U16Data;
typedef unsigned int Q_U32Data;
typedef struct _tQueueInfo
{
Q_U8Data *pDataBuf;
Q_U16Data MaxQueueSize;
Q_U32Data Front;
Q_U32Data Rear;
Q_U32Data QueueLength;
}QueueInfo, *pQueueInfo;
void Queue_Init(pQueueInfo pQInfo,Q_U16Data MaxSize);
void Queue_ClearData(pQueueInfo pQInfo);
Q_U32Data Queue_GetLength(pQueueInfo pQInfo);
void Queue_AddData(Q_U8Data *pSrcBuf, pQueueInfo pQInfo, Q_U16Data DataCnt);
void Queue_AddOneData(Q_U8Data SrcData, pQueueInfo pQInfo);
void Queue_GetData(Q_U8Data *pBuf, pQueueInfo pQInfo, Q_U32Data DataCnt);
void Queue_GetOneData(Q_U8Data *DestData, pQueueInfo pQInfo);
void Queue_DummyRead(pQueueInfo pQInfo,Q_U16Data DataCnt);
#endif
源文件queue.c
#include "queue.h"
#include "malloc.h"
#include "delay.h"
#include <stdio.h>
#include <string.h>
#include "comm.h"
//*****************************错误处理部分*****************
enum ERROR_CODE
{
ERR_QUEUE_MALLOC_FAIL = 1,
ERR_QUEUE_DATA_FULL,
ERR_QUEUE_DATA_NULL,
ERR_MALLOC_FAIL,
ERR_COMM_MALLOC_FAIL,
ERR_NAND_MALLOC_FAIL,
ERR_UPAN_WRITE_FAIL,
ERR_UPAN_CLOSE_FAIL,
ERR_UPAN_OPEN_FAIL,
ERR_NAND_BADBLOCK_FULL,
ERR_MAINPROC_FAIL,
ERR_BBM_MALLOC_FAIL,
};
void ErrorHandle(U32 u32ErrCode)
{
while(1)
{
// Led_Error();
printf("error code = %x \r\n", u32ErrCode);
DelayMs(500);
// COMM_WriteCmd(COMM_MAINCMD_CONTROL,COMM_SUBCMD_CONTROL_ERROR);
DelayMs(500);
}
}
//*****************************错误处理部分*****************
void Queue_Init(pQueueInfo pQInfo,Q_U16Data MaxSize)
{
Q_U8Data *pBuf;
pBuf = mymalloc(SRAMIN,MaxSize);
if(pBuf == NULL)
{
ErrorHandle(ERR_QUEUE_MALLOC_FAIL);
}
pQInfo->pDataBuf = pBuf;
pQInfo->MaxQueueSize = MaxSize;
pQInfo->Front = 0;
pQInfo->Rear = 0;
pQInfo->QueueLength = 0;
}
void Queue_ClearData(pQueueInfo pQInfo)
{
pQInfo->Front = 0;
pQInfo->Rear = 0;
pQInfo->QueueLength = 0;
}
Q_U32Data Queue_GetLength(pQueueInfo pQInfo)
{
Q_U32Data Ret;
Ret = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize); //取余是当Real < Front时
return Ret;
}
/******************数据空间************************
| ---------- | ------------- | ---------------- |
0 Front Rear 256
该数据空间大小申请的是256,数据以头尾相连的方式进行存取,
函数首先判断的是存入的空间是否足够,即除开front--rear段,
剩下的空间是否足够存入buf,其次开始存入时,先按顺序存入
在rear到256的数据段,最后存入的是0--front的数据段。
****************************************************/
void Queue_AddData(Q_U8Data *pAddBuf, pQueueInfo pQInfo, Q_U16Data DataCnt)
{
Q_U16Data u16QCnt;
Q_U16Data u16QLen;
u16QLen = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize);
if(u16QLen + DataCnt > pQInfo->MaxQueueSize)//判断是否超出256
{
while(1)
{
printf("Queue Size is overflow!In src:%s Line:%d\r\n",__FILE__,__LINE__);
DelayMs(100);
}
}
else
{
u16QCnt = (pQInfo->MaxQueueSize) - pQInfo->Rear;//计算Rear后可存空间(剩余的就是Front前可存空间)
if(u16QCnt >= DataCnt)//front--rear段足够存下
{
memcpy(pQInfo->pDataBuf + pQInfo->Rear, pAddBuf, DataCnt);
}
else//分两段存,先是front--rear段,然后是0--front段
{
memcpy(pQInfo->pDataBuf + pQInfo->Rear, pAddBuf, u16QCnt);
memcpy(pQInfo->pDataBuf, pAddBuf + u16QCnt, DataCnt - u16QCnt);
}
pQInfo->Rear = (pQInfo->Rear + DataCnt)%(pQInfo->MaxQueueSize);
pQInfo->QueueLength += DataCnt;
}
}
void Queue_GetData(Q_U8Data *pSaveBuf, pQueueInfo pQInfo, Q_U32Data DataCnt)
{
Q_U16Data u16QCnt;
Q_U16Data u16QLen;
u16QLen = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize);
if(u16QLen < DataCnt)
{
while(1)
{
printf("Queue is not enough data to read!In src:%s Line:%d\r\n",__FILE__,__LINE__);
DelayMs(100);
}
}
else
{
u16QCnt = (pQInfo->MaxQueueSize) - pQInfo->Front;
if(u16QCnt >= DataCnt)
{
memcpy(pSaveBuf, pQInfo->pDataBuf + pQInfo->Front, DataCnt);
}
else
{
memcpy(pSaveBuf, pQInfo->pDataBuf + pQInfo->Front, u16QCnt);
memcpy(pSaveBuf + u16QCnt, pQInfo->pDataBuf, DataCnt - u16QCnt);
}
}
pQInfo->Front = (pQInfo->Front + DataCnt)%(pQInfo->MaxQueueSize);
pQInfo->QueueLength -= DataCnt;
}
//丢弃数据函数
//在队列里移动Front,模拟读出的过程移动Front,但是没有Buf接收,形成丢弃
void Queue_DummyRead(pQueueInfo pQInfo,Q_U16Data DataCnt)
{
Q_U16Data u16QLen;
u16QLen = (pQInfo->Rear - pQInfo->Front + (pQInfo->MaxQueueSize)) % (pQInfo->MaxQueueSize);
if(u16QLen < DataCnt)
{
while(1)
{
printf("Queue is not enough data to read!In src:%s Line:%d\r\n",__FILE__,__LINE__);
DelayMs(100);
}
else
{
pQInfo->Front = (pQInfo->Front + DataCnt)%(pQInfo->MaxQueueSize);
pQInfo->QueueLength -= DataCnt;
}
}
函数调用方法
QueueInfo Q_UART1Info; //定义一个队列结构体
Queue_Init(&Q_UART1Info, 256); //初始化队列结构体,并设置其最大为256个字节
if(Queue_GetLength(&Q_UART1Info) > 100)
{
//队列中的数据长度 > 100个字节时才进行处理
Queue_GetData(...);
}