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

头文件

  1. #ifndef __FIFO_H_  
  2. #define __FIFO_H_  
  3.   
  4. #pragma pack(4)  
  5. typedef struct FIFO_Type_STRU  
  6. {  
  7.     unsigned int            Depth;          // Fifo深度  
  8.     volatile unsigned int   Head;           // Head为起始元素  
  9.     volatile unsigned int   Tail;           // Tail-1为最后一个元素  
  10.     volatile unsigned int   Counter;        // 元素个数  
  11.     unsigned int            ElementBytes;   // 每个元素的字节数element  
  12.     void                    *Buff;          // 缓存区  
  13. }FIFO_Type;  
  14. #pragma pack()  
  15.   
  16. /********************************************************************//** 
  17.  * @brief       FIFO初始化 
  18.  * @param[in]   pFIFO: FIFO指针 
  19.  * @param[in]   pBuff: FIFO中缓存 
  20.  * @param[in]   elementBytes:FIFO每个元素的字节数 
  21.  * @param[in]   depth: FIFO深度 
  22.  * @return      None 
  23.  *********************************************************************/  
  24. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth);  
  25.   
  26. /********************************************************************//** 
  27.  * @brief       向FIFO添加一个元素 
  28.  * @param[in]   pFIFO: FIFO指针 
  29.  * @param[in]   pValue: 要添加的元素 
  30.  * @return      1-TRUE or 0-FALSE 
  31.  *********************************************************************/  
  32. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue);  
  33.   
  34. /********************************************************************//** 
  35.  * @brief       向FIFO添加多个元素 
  36.  * @param[in]   pFIFO: FIFO指针 
  37.  * @param[in]   pValues: 要添加的元素指针 
  38.  * @param[in]   bytesToAdd: 要添加元素的长度 
  39.  * @return      实际添加的元素个数 
  40.  *********************************************************************/  
  41. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd);  
  42.   
  43. /********************************************************************//** 
  44.  * @brief       从FIFO读取一个元素 
  45.  * @param[in]   pFIFO: FIFO指针 
  46.  * @param[in]   pValue: 存放要读取的元素指针 
  47.  * @return      1-TRUE or 0-FALSE 
  48.  *********************************************************************/  
  49. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue);  
  50.   
  51. /********************************************************************//** 
  52.  * @brief       从FIFO读取多个元素 
  53.  * @param[in]   pFIFO: FIFO指针 
  54.  * @param[out]  pValues: 存放要读取的元素指针 
  55.  * @param[in]   bytesToRead: 要读取的元素长度 
  56.  * @return      实际读取的元素个数 
  57.  *********************************************************************/  
  58. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead);  
  59.   
  60.   
  61. /********************************************************************//** 
  62.  * @brief       清空FIFO 
  63.  * @param[in]   pFIFO: FIFO指针 
  64.  * @return      None 
  65.  *********************************************************************/  
  66. void FIFO_Clear(FIFO_Type *pFIFO);  
  67.   
  68.   
  69. #endif  


程序主体

  1. /******************************************************************************* 
  2. 文件名称:fifo.c 
  3. 作    者:启岩 QQ516409354      
  4. 版    本:P1.0        
  5. 日    期:2014/2/20 
  6. 文件描述: 
  7.         使用ringbuffer实现的FIFO 
  8. 函数列表: 
  9.         略 
  10. 修改历史: 
  11.    <版本>  <日    期>  <作 者>  <改动内容和原因> 
  12.    ---------------------------------------------------- 
  13.     1.0    2014/2/20   启岩  基本的功能完成 
  14.     1.1    2015/1/29   启岩  1、增加FIFO_Clear()函数 
  15.                                2、优化FIFO结构体成员类型 
  16. *******************************************************************************/  
  17.   
  18. #include <string.h>  
  19. #include "fifo.h"  
  20.   
  21.   
  22. /********************************************************************//** 
  23.  * @brief       FIFO初始化 
  24.  * @param[in]   pFIFO: FIFO指针 
  25.  * @param[in]   pBuff: FIFO中缓存 
  26.  * @param[in]   elementBytes:FIFO每个元素的字节数 
  27.  * @param[in]   depth: FIFO深度 
  28.  * @return      None 
  29.  *********************************************************************/  
  30. void FIFO_Init(FIFO_Type *pFIFO, void *pBuff, unsigned int elementBytes, unsigned int depth)  
  31. {  
  32.     pFIFO->Buff = pBuff;  
  33.     pFIFO->ElementBytes = elementBytes;  
  34.     pFIFO->Depth = depth;  
  35.     pFIFO->Head = 0;  
  36.     pFIFO->Tail = 0;  
  37.     pFIFO->Counter = 0;  
  38. }  
  39.   
  40. /********************************************************************//** 
  41.  * @brief       判断FIFO是否为空 
  42.  * @param[in]   pFIFO: FIFO指针 
  43.  * @return      1-TRUE or 0-FALSE 
  44.  *********************************************************************/  
  45. unsigned char FIFO_IsEmpty(FIFO_Type *pFIFO)  
  46. {  
  47.     return (pFIFO->Counter == 0);  
  48. }  
  49.   
  50. /********************************************************************//** 
  51.  * @brief       判断FIFO是否已满 
  52.  * @param[in]   pFIFO: FIFO指针 
  53.  * @return      TRUE or FALSE 
  54.  *********************************************************************/  
  55. unsigned char FIFO_IsFull(FIFO_Type *pFIFO)  
  56. {  
  57.     return (pFIFO->Counter == pFIFO->Depth);  
  58. }  
  59.   
  60. /********************************************************************//** 
  61.  * @brief       向FIFO添加一个元素 
  62.  * @param[in]   pFIFO: FIFO指针 
  63.  * @param[in]   pValue: 要添加的元素 
  64.  * @return      1-TRUE or 0-FALSE 
  65.  *********************************************************************/  
  66. unsigned char FIFO_AddOne(FIFO_Type *pFIFO, void *pValue)  
  67. {  
  68.     unsigned char *p;  
  69.   
  70.     if (FIFO_IsFull(pFIFO))  
  71.     {  
  72.         return 0;  
  73.     }  
  74.   
  75.     p = (unsigned char *)pFIFO->Buff;  
  76.     memcpy(p + pFIFO->Tail * pFIFO->ElementBytes, (unsigned char *)pValue, pFIFO->ElementBytes);  
  77.       
  78.     pFIFO->Tail ++;  
  79.     if (pFIFO->Tail >= pFIFO->Depth)  
  80.     {  
  81.         pFIFO->Tail = 0;  
  82.     }  
  83.     pFIFO->Counter ++;  
  84.     return 1;  
  85. }  
  86.   
  87. /********************************************************************//** 
  88.  * @brief       向FIFO添加多个元素 
  89.  * @param[in]   pFIFO: FIFO指针 
  90.  * @param[in]   pValues: 要添加的元素指针 
  91.  * @param[in]   bytesToAdd: 要添加元素的长度 
  92.  * @return      实际添加的元素个数 
  93.  *********************************************************************/  
  94. unsigned int FIFO_Add(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToAdd)  
  95. {  
  96.     unsigned char *p;  
  97.     unsigned int cnt = 0;  
  98.   
  99.     p = (unsigned char *)pValues;  
  100.     while(bytesToAdd --)  
  101.     {  
  102.         if (FIFO_AddOne(pFIFO, p))  
  103.         {  
  104.             p += pFIFO->ElementBytes;  
  105.             cnt++;  
  106.         }  
  107.         else  
  108.         {  
  109.             break;  
  110.         }  
  111.     }  
  112.   
  113.     return cnt;  
  114. }  
  115.   
  116. /********************************************************************//** 
  117.  * @brief       从FIFO读取一个元素 
  118.  * @param[in]   pFIFO: FIFO指针 
  119.  * @param[in]   pValue: 存放要读取的元素指针 
  120.  * @return      1-TRUE or 0-FALSE 
  121.  *********************************************************************/  
  122. unsigned char FIFO_GetOne(FIFO_Type *pFIFO, void *pValue)  
  123. {  
  124.     unsigned char *p;  
  125.     if (FIFO_IsEmpty(pFIFO))  
  126.     {  
  127.         return 0;  
  128.     }  
  129.   
  130.     p = (unsigned char *)pFIFO->Buff;  
  131.     memcpy(pValue, p + pFIFO->Head * pFIFO->ElementBytes, pFIFO->ElementBytes);  
  132.   
  133.     pFIFO->Head ++;  
  134.     if (pFIFO->Head >= pFIFO->Depth)  
  135.     {  
  136.         pFIFO->Head = 0;  
  137.     }  
  138.     pFIFO->Counter --;  
  139.   
  140.     return 1;  
  141. }  
  142.   
  143. /********************************************************************//** 
  144.  * @brief       从FIFO读取多个元素 
  145.  * @param[in]   pFIFO: FIFO指针 
  146.  * @param[out]  pValues: 存放要读取的元素指针 
  147.  * @param[in]   bytesToRead: 要读取的元素长度 
  148.  * @return      实际读取的元素个数 
  149.  *********************************************************************/  
  150. unsigned int FIFO_Get(FIFO_Type *pFIFO, void *pValues, unsigned int bytesToRead)  
  151. {  
  152.     unsigned int cnt = 0;  
  153.     unsigned char *p;  
  154.   
  155.     p = pValues;  
  156.     while(bytesToRead--)  
  157.     {  
  158.         if (FIFO_GetOne(pFIFO, p))  
  159.         {  
  160.             p += pFIFO->ElementBytes;  
  161.             cnt++;  
  162.         }  
  163.         else  
  164.         {  
  165.             break;  
  166.         }  
  167.     }  
  168.   
  169.     return cnt;  
  170. }  
  171.   
  172. /********************************************************************//** 
  173.  * @brief       清空FIFO 
  174.  * @param[in]   pFIFO: FIFO指针 
  175.  * @return      None 
  176.  *********************************************************************/  
  177. void FIFO_Clear(FIFO_Type *pFIFO)  
  178. {  
  179.     pFIFO->Counter = 0;  
  180.     pFIFO->Head = 0;  
  181.     pFIFO->Tail = 0;  
  182. }  

测试代码
  1. void Tester(void)  
  2. {  
  3.     int i;  
  4.     FIFO_Type   fifo;  
  5.     FIFO_Type   *pfifo;  
  6.     int         index;  
  7.     float       fArray[10];  
  8.     float       fValue;  
  9.   
  10.     char        cArray[10];  
  11.     char        cValue;  
  12.   
  13.     pfifo = &fifo;  
  14.   
  15.     printf("测试FIFO元素为float型的数据\r\n");  
  16.     printf("初始化FIFO值。\r\n");  
  17.     FIFO_Init(pfifo, fArray, sizeof(float), 10);  
  18.     for (i = 0; i < 10; i++)  
  19.     {  
  20.         fValue = (100.0f+i*i);  
  21.         FIFO_AddOne(pfifo, &fValue);  
  22.     }  
  23.     printf("当前元数个数:%d\r\n", pfifo->Counter);  
  24.     index = 0;  
  25.     while(FIFO_GetOne(pfifo, &fValue))  
  26.     {  
  27.         index ++;  
  28.         printf("第%d个元素fValue = %0.3f\r\n",index, fValue);  
  29.         if (index == 5)  
  30.         {  
  31.             printf("插入3个值。\r\n");  
  32.             fValue = 1.23f;  
  33.             FIFO_AddOne(pfifo, &fValue);  
  34.   
  35.             fValue = 2.34f;  
  36.             FIFO_AddOne(pfifo, &fValue);  
  37.   
  38.             fValue = 3.45f;  
  39.             FIFO_AddOne(pfifo, &fValue);  
  40.         }  
  41.     }  
  42.   
  43.     printf("\r\n\r\n");  
  44.     printf("测试FIFO元素为char型的数据\r\n");  
  45.     FIFO_Init(pfifo, cArray, sizeof(char), 10);  
  46.     printf("初始化FIFO值。\r\n");  
  47.     FIFO_Add(pfifo, "ABCDEFGHIJ", 10);  
  48.     printf("当前元数个数:%d\r\n", pfifo->Counter);  
  49.     index = 0;  
  50.     while(FIFO_GetOne(pfifo, &cValue))  
  51.     {  
  52.         index ++;  
  53.         printf("第%d个元素cValue = %c\r\n",index, cValue);  
  54.         if (index == 5)  
  55.         {  
  56.             printf("插入3个值。\r\n");  
  57.             cValue = 'X';  
  58.             FIFO_AddOne(pfifo, &cValue);  
  59.   
  60.             cValue = 'Y';  
  61.             FIFO_AddOne(pfifo, &cValue);  
  62.   
  63.             cValue = 'Z';  
  64.             FIFO_AddOne(pfifo, &cValue);  
  65.         }  
  66.     }  
  67.   
  68. }  




阅读更多
换一批

没有更多推荐了,返回首页