循环队列
头文件queue.h源文件queue.c函数调用方法
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)
{
printf("error code = %x \r\n", u32ErrCode
);
DelayMs(500);
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
);
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
)
{
while(1)
{
printf("Queue Size is overflow!In src:%s Line:%d\r\n",__FILE__,__LINE__);
DelayMs(100);
}
}
else
{
u16QCnt
= (pQInfo
->MaxQueueSize
) - pQInfo
->Rear
;
if(u16QCnt
>= DataCnt
)
{
memcpy(pQInfo
->pDataBuf
+ pQInfo
->Rear
, pAddBuf
, DataCnt
);
}
else
{
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
;
}
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);
if(Queue_GetLength(&Q_UART1Info
) > 100)
{
Queue_GetData(...);
}