C语言下使用ringbuffer实现任意数据类型的FIFO
2020-05-28 17:41 dreamboy2000 阅读(918) 评论(0) 编辑 收藏 举报头文件
#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); } } }
运行结果
转载自:https://blog.csdn.net/xmxqiyan/article/details/43408291?utm_source=itdadao&utm_medium=referral