C语言下使用ringbuffer实现任意数据类型的FIFO
来源:互联网
作者:佚名
时间:2015-02-02 14:50
头文件#ifndef__FIFO_H_#define__FIFO_H_#pragma pack(4)typedef struct FIFO_Type_STRU{unsigned intDepth;// Fifo深度volatile unsigned intHead;// Head为起
头文件
#ifndef__FIFO_H_
#define__FIFO_H_
#pragma pack(4)
typedef struct FIFO_Type_STRU
{
unsigned intDepth;// Fifo深度
volatile unsigned intHead;// Head为起始元素
volatile unsigned intTail;// Tail-1为最后一个元素
volatile unsigned intCounter;// 元素个数
unsigned intElementBytes;// 每个元素的字节数element
void
*Buff;// 缓存区
}FIFO_Type;
#pragma pack()
/********************************************************************//**
* @brief
FIFO初始化
* @param[in] pFIFO: FIFO指针
* @param[in]pBuff: FIFO中缓存
* @param[in]elementBytes:FIFO每个元素的字节数
* @param[in]depth: FIFO深度
* @return
None
*********************************************************************/
void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);
/********************************************************************//**
* @brief
向FIFO添加一个元素
* @param[in] pFIFO: FIFO指针
* @param[in]pValue: 要添加的元素
* @return
1-TRUE or 0-FALSE
*********************************************************************/
unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);
/********************************************************************//**
* @brief
向FIFO添加多个元素
* @param[in] pFIFO: FIFO指针
* @param[in]pValues: 要添加的元素指针
* @param[in]bytesToAdd: 要添加元素的长度
* @return
实际添加的元素个数
*********************************************************************/
unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);
/********************************************************************//**
* @brief
从FIFO读取一个元素
* @param[in] pFIFO: FIFO指针
* @param[in]pValue: 存放要读取的元素指针
* @return
1-TRUE or 0-FALSE
*********************************************************************/
unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);
/********************************************************************//**
* @brief
从FIFO读取多个元素
* @param[in] pFIFO: FIFO指针
* @param[out]pValues: 存放要读取的元素指针
* @param[in]bytesToRead: 要读取的元素长度
* @return
实际读取的元素个数
*********************************************************************/
unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);
/********************************************************************//**
* @brief
清空FIFO
* @param[in] pFIFO: FIFO指针
* @return
None
*********************************************************************/
void FIFO_Clear(FIFO_Type *pFIFO);
#endif
程序主体
/*******************************************************************************
文件名称:fifo.c
作 者:启岩 QQ516409354
版 本:P1.0
日 期:2014/2/20
文件描述:
使用ringbuffer实现的FIFO
函数列表:
略
修改历史:
----------------------------------------------------
1.0 2014/2/20 启岩 基本的功能完成
1.1 2015/1/29 启岩 1、增加FIFO_Clear()函数
2、优化FIFO结构体成员类型
*******************************************************************************/
#include
#include "fifo.h"
/********************************************************************//**
* @brief
FIFO初始化
* @param[in] pFIFO: FIFO指针
* @param[in]pBuff: FIFO中缓存
* @param[in]elementBytes:FIFO每个元素的字节数
* @param[in]depth: FIFO深度
* @return
None
*********************************************************************/
void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)
{
pFIFO->Buff = pBuff;
pFIFO->ElementBytes = elementBytes;
pFIFO->Depth = depth;
pFIFO->Head = 0;
pFIFO->Tail = 0;
pFIFO->Counter = 0;
}
/********************************************************************//**
* @brief
判断FIFO是否为空
* @param[in] pFIFO: FIFO指针
* @return
1-TRUE or 0-FALSE
*********************************************************************/
unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)
{
return (pFIFO->Counter == 0);
}
/********************************************************************//**
* @brief
判断FIFO是否已满
* @param[in] pFIFO: FIFO指针
* @return
TRUE or FALSE
*********************************************************************/
unsigned char FIFO_IsFull(FIFO_Type *pFIFO)
{
return (pFIFO->Counter == pFIFO->Depth);
}
/********************************************************************//**
* @brief
向FIFO添加一个元素
* @param[in] pFIFO: FIFO指针
* @param[in]pValue: 要添加的元素
* @return
1-TRUE or 0-FALSE
*********************************************************************/
unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)
{
unsigned char *p;
if (FIFO_IsFull(pFIFO))
{
return 0;
}
p = (unsigned char *)pFIFO->Buff;
memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);
pFIFO->Tail ++;
if (pFIFO->Tail >= pFIFO->Depth)
{
pFIFO->Tail = 0;
}
pFIFO->Counter ++;
return 1;
}
/********************************************************************//**
* @brief
向FIFO添加多个元素
* @param[in] pFIFO: FIFO指针
* @param[in]pValues: 要添加的元素指针
* @param[in]bytesToAdd: 要添加元素的长度
* @return
实际添加的元素个数
*********************************************************************/
unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)
{
unsigned char *p;
unsigned int cnt = 0;
p = (unsigned char *)pValues;
while(bytesToAdd --)
{
if (FIFO_AddOne(pFIFO, p))
{
p += pFIFO->ElementBytes;
cnt++;
}
else
{
break;
}
}
return cnt;
}
/********************************************************************//**
* @brief
从FIFO读取一个元素
* @param[in] pFIFO: FIFO指针
* @param[in]pValue: 存放要读取的元素指针
* @return
1-TRUE or 0-FALSE
*********************************************************************/
unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)
{
unsigned char *p;
if (FIFO_IsEmpty(pFIFO))
{
return 0;
}
p = (unsigned char *)pFIFO->Buff;
memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);
pFIFO->Head ++;
if (pFIFO->Head >= pFIFO->Depth)
{
pFIFO->Head = 0;
}
pFIFO->Counter --;
return 1;
}
/********************************************************************//**
* @brief
从FIFO读取多个元素
* @param[in] pFIFO: FIFO指针
* @param[out]pValues: 存放要读取的元素指针
* @param[in]bytesToRead: 要读取的元素长度
* @return
实际读取的元素个数
*********************************************************************/
unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)
{
unsigned int cnt = 0;
unsigned char *p;
p = pValues;
while(bytesToRead--)
{
if (FIFO_GetOne(pFIFO, p))
{
p += pFIFO->ElementBytes;
cnt++;
}
else
{
break;
}
}
return cnt;
}
/********************************************************************//**
* @brief
清空FIFO
* @param[in] pFIFO: FIFO指针
* @return
None
*********************************************************************/
void FIFO_Clear(FIFO_Type *pFIFO)
{
pFIFO->Counter = 0;
pFIFO->Head = 0;
pFIFO->Tail = 0;
}
测试代码
void Tester(void)
{
int i;
FIFO_Typefifo;
FIFO_Type*pfifo;
intindex;
floatfArray[10];
floatfValue;
charcArray[10];
charcValue;
pfifo = &fifo;
printf("测试FIFO元素为float型的数据\r\n");
printf("初始化FIFO值。\r\n");
FIFO_Init(pfifo, fArray, sizeof(float), 10);
for (i = 0; i < 10; i++)
{
fValue = (100.0f+i*i);
FIFO_AddOne(pfifo, &fValue);
}
printf("当前元数个数:%d\r\n", pfifo->Counter);
index = 0;
while(FIFO_GetOne(pfifo, &fValue))
{
index ++;
printf("第%d个元素fValue = %0.3f\r\n",index, fValue);
if (index == 5)
{
printf("插入3个值。\r\n");
fValue = 1.23f;
FIFO_AddOne(pfifo, &fValue);
fValue = 2.34f;
FIFO_AddOne(pfifo, &fValue);
fValue = 3.45f;
FIFO_AddOne(pfifo, &fValue);
}
}
printf("\r\n\r\n");
printf("测试FIFO元素为char型的数据\r\n");
FIFO_Init(pfifo, cArray, sizeof(char), 10);
printf("初始化FIFO值。\r\n");
FIFO_Add(pfifo, "ABCDEFGHIJ", 10);
printf("当前元数个数:%d\r\n", pfifo->Counter);
index = 0;
while(FIFO_GetOne(pfifo, &cValue))
{
index ++;
printf("第%d个元素cValue = %c\r\n",index, cValue);
if (index == 5)
{
printf("插入3个值。\r\n");
cValue = 'X';
FIFO_AddOne(pfifo, &cValue);
cValue = 'Y';
FIFO_AddOne(pfifo, &cValue);
cValue = 'Z';
FIFO_AddOne(pfifo, &cValue);
}
}
}
运行结果