背景
在C语言编程场景中,常常需要对一段不定长数据进行缓存。这里提出一种基于数组的环形缓冲队列,解决上述场景的问题。
原理
如下图所示,首先定义数据长度为buf[8],初始化指针为in/out
其中in为缓冲数据的输入指针
out为缓冲数据的输出指针
缓存内写入一个数据
in++
如下图所示
缓存内读出一个数据
out++
如下图所示
这时判断in==out为true,所以表明缓存内没有数据。
如果把上述缓冲数组换成二维数组,代码可以编写如下
代码
buf_queue.c
/******************************************************************************
* 锟斤拷权锟斤拷锟斤拷 (c) 2009
*
* 锟侥硷拷锟斤拷锟狡o拷queue.c
* 锟斤拷锟斤拷摘要锟斤拷锟斤拷锟斤拷通锟斤拷专锟矫伙拷锟斤拷循锟斤拷锟斤拷锟叫匡拷锟斤拷
* 锟斤拷 锟斤拷 锟脚o拷1.0
* 锟斤拷 锟竭o拷
* 锟斤拷锟斤拷锟斤拷冢锟�2012-01-01
*
* 锟睫改硷拷录1锟斤拷
* 锟睫革拷锟斤拷锟节o拷
* 锟斤拷 锟斤拷 锟脚o拷
* 锟斤拷 锟斤拷 锟剿o拷
* 锟睫革拷锟斤拷锟捷o拷
*******************************************************************************/
#include "buf_queue.h"
#include "stdio.h"
#include "string.h"
/******************************************************************************
* 全锟街猴拷锟斤拷锟斤拷锟斤拷 *
******************************************************************************/
BUF_QUEUE bufQueue;
void InitQueue(BUF_QUEUE *pBufQueue)
{
INT16U i;
INT32U tmp;
INT8U *p;
p = (INT8U *)pBufQueue;
tmp = sizeof(BUF_QUEUE) / sizeof(INT8U);
for (i = 0; i < tmp; i++)
{
*p++ = 0;
}
}
INT16U RxFromQueue(BUF_QUEUE *pBufQueue, INT8U *dst, INT16U len, INT8U *type)
{
INT16U i;
if (pBufQueue->In != pBufQueue->Out)
{
for(i = 0; i < len; i++)
{
*(dst + i) = pBufQueue->datBuf[pBufQueue->Out].buf[i];
}
*type = pBufQueue->datBuf[pBufQueue->Out].buf_type;
pBufQueue->Out++;
pBufQueue->Out &= (RX_SIZE_LEN-1);
return 0;
}
return 1;
}
INT16U WxToQueue(BUF_QUEUE *pBufQueue, INT8U *dat, INT16U len, INT8U type)
{
INT16U tmp, i;
tmp = (pBufQueue->In+1) & (RX_SIZE_LEN-1);
if (tmp != pBufQueue->Out)
{
memset(pBufQueue->datBuf[pBufQueue->In].buf, 0, sizeof(pBufQueue->datBuf[pBufQueue->In].buf));
for(i = 0; i < len; i++)
{
pBufQueue->datBuf[pBufQueue->In].buf[i] = *(dat + i);
}
pBufQueue->datBuf[pBufQueue->In].buf_type = type;
pBufQueue->In++;
pBufQueue->In &= (RX_SIZE_LEN - 1);
return 0;
}
return 1;//
}
void clearQueue(BUF_QUEUE *pBufQueue)
{
InitQueue(pBufQueue);
}
//---------------------------------------------------------------------------
buf_queue.h
/******************************************************************************
* 锟斤拷权锟斤拷锟斤拷(c) 2013
*
* 锟侥硷拷锟斤拷锟狡o拷queue.h
* 锟斤拷锟斤拷摘要锟斤拷锟斤拷锟斤拷专锟矫伙拷锟斤拷锟斤拷锟�
* 锟斤拷锟斤拷说锟斤拷锟斤拷
* 锟斤拷 锟斤拷 锟脚o拷V1.0.0.0
* 锟斤拷 锟竭o拷
* 锟斤拷锟斤拷锟斤拷冢锟�
*
* 锟睫改硷拷录锟斤拷
* 锟睫革拷锟斤拷锟节o拷
* 锟斤拷 锟斤拷 锟脚o拷
* 锟斤拷 锟斤拷 锟剿o拷
* 锟睫革拷锟斤拷锟捷o拷
******************************************************************************/
#ifndef _DEF_QUEUE_CLASS_H_
#define _DEF_QUEUE_CLASS_H_
/******************************************************************************
* 锟斤拷锟斤拷锟斤拷头锟侥硷拷 *
******************************************************************************/
#include "stm32f4xx_hal.h"
#include "common.h"
/******************************************************************************
* 锟疥定锟斤拷 *
******************************************************************************/
#define RX_SIZE_LEN 32
#define MAX_BUF_LEN 100
#define BUF_TYPE_FROM_NB 1
#define BUF_TYPE_FROM_SENSOR 2
/******************************************************************************
* 锟斤拷锟斤拷锟斤拷锟酵讹拷锟斤拷 *
******************************************************************************/
typedef struct
{
INT8U buf_type;
INT8U buf[MAX_BUF_LEN];
} DAT_BUF;
// 锟斤拷锟秸凤拷锟斤拷锟街节讹拷锟斤拷
typedef struct
{
INT16U In;
INT16U Out;
DAT_BUF datBuf[RX_SIZE_LEN];
} BUF_QUEUE;
/******************************************************************************
* 锟解部锟斤拷锟斤拷锟斤拷锟斤拷 *
******************************************************************************/
// 锟斤拷始锟斤拷锟斤拷锟斤拷
extern void InitQueue(BUF_QUEUE *pBufQueue);
extern INT16U RxFromQueue(BUF_QUEUE *pBufQueue, INT8U *dst, INT16U len, INT8U *type);
extern INT16U WxToQueue(BUF_QUEUE *pBufQueue, INT8U *dat, INT16U len, INT8U type);
extern void clearQueue(BUF_QUEUE *pBufQueue);
extern BUF_QUEUE bufQueue;
#endif