C语言下使用ringbuffer实现任意数据类型的FIFO

头文件

#ifndef	__FIFO_H_
#define	__FIFO_H_

#pragma pack(4)
typedef struct FIFO_Type_STRU
{
	unsigned int			Depth;			// Fifo深度
	volatile unsigned int	Head;			// Head为起始元素
	volatile unsigned int	Tail;			// Tail-1为最后一个元素
	volatile unsigned int	Counter;		// 元素个数
	unsigned int			ElementBytes;	// 每个元素的字节数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 <string.h>
#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_Type	fifo;
	FIFO_Type	*pfifo;
	int			index;
	float		fArray[10];
	float		fValue;

	char		cArray[10];
	char		cValue;

	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);
		}
	}

}

运行结果







  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值