FIFO实现2_基本模型

来源:互联网 发布:网站数据分析 编辑:程序博客网 时间:2024/06/01 09:57

/*****************************************************************************************
filename: modfifo.h
文件功能:实现简单的FIFO功能
策    略:PUT时,若FIFO满,则不能载入后来的数据。
          GUT时,按先入先出原则
编译环境:VS2005 keil V4.14
编    者:张永辉 2012年11月28日
修    改:张永辉 2013年03月04日
修    改:张永辉 2013年03月07日 ModFifoDataNumGet()函数
*****************************************************************************************/
#ifndef __MOD_FIFO_H
#define __MOD_FIFO_H
/****************************************************************************************/
#define MOD_FIFO_LEN   5                        //FIFO长度 字节
#define MOD_FIFO_TYPE       unsigned char       //FIFO数据类型
#define MOD_FIFO_NUM_TYPE   unsigned int        //FIFO数据计数器类型
void              ModFifoInit(void);
void              ModFifoTest(void);
MOD_FIFO_NUM_TYPE ModFifoPut    (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len);
MOD_FIFO_NUM_TYPE ModFifoGet    (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len);
MOD_FIFO_NUM_TYPE ModFifoPutByte(MOD_FIFO_TYPE  buff);
MOD_FIFO_NUM_TYPE ModFifoGetByte(MOD_FIFO_TYPE* buff);
MOD_FIFO_NUM_TYPE ModFifoDataNumGet(void);
/*****************************************************************************************/
#endif

/*****************************************************************************************
filename:modfifo.c
文件功能:实现简单的FIFO功能
策    略:PUT时,若FIFO满,则不能载入后来的数据。
          GUT时,按先入先出原则
*****************************************************************************************/
#include "modfifo.h"
struct fifo
{
    MOD_FIFO_TYPE FifoBuffer[MOD_FIFO_LEN];
    MOD_FIFO_NUM_TYPE  FifoNum;             //FIFO未取走的数据个数
    MOD_FIFO_NUM_TYPE  FifoIn;              //指向下次要放入数据的地方。
    MOD_FIFO_NUM_TYPE  FifoOut;             //指向下次要取出数据的地方。
}ModFifo;

/*****************************************************************************************
函数功能:                              测试函数
*****************************************************************************************/
void ModFifoTest(void)
{
    MOD_FIFO_TYPE inp[MOD_FIFO_LEN+1] = {'1','2','3','4','5'};
    MOD_FIFO_TYPE oup[MOD_FIFO_LEN+1];
    MOD_FIFO_TYPE out;
    MOD_FIFO_TYPE i = 0;
    ModFifoInit();
    for (i = 0;i < MOD_FIFO_LEN + 2;i++)
    {
        ModFifoPutByte(i);
    }
    for (i = 0;i < MOD_FIFO_LEN + 2;i++)
    {
        ModFifoGetByte(&out);
    }
    ModFifoPutByte(99);
    ModFifoPutByte(23);
    ModFifoGetByte(&out);
    ModFifoGetByte(&out);
    ModFifoGetByte(&out);
    ModFifoPut(inp,3);
    ModFifoGetByte(&out);
    ModFifoPut(inp,5);
    ModFifoGet(oup,5);
    while(1);
}
/*****************************************************************************************
函数功能:                              初始化函数
使用前,先调用此函数
*****************************************************************************************/
void ModFifoInit(void)
{
    //初始化
    ModFifo.FifoNum = 0;
    ModFifo.FifoIn = 0;
    ModFifo.FifoOut = 0;
}
/*****************************************************************************************
                    向FIFO存入一串数据
参数:buff  要存的数据的地址
      len   数据长度
返回:成功存入数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoPut    (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len)
{
    MOD_FIFO_NUM_TYPE i;
    if(ModFifo.FifoNum >= MOD_FIFO_LEN)
    {
        return 0;
    }
    i = MOD_FIFO_LEN - ModFifo.FifoNum;
    len = (len < i)?len:i;  //取最小值

    for (i = 0;i<len;i++)
    {
        ModFifo.FifoBuffer[ModFifo.FifoIn] = *buff++;

        if (++ModFifo.FifoIn >= MOD_FIFO_LEN)
        {
            ModFifo.FifoIn = 0;
        }
    }
    ModFifo.FifoNum += len;
    return len;
}
/*****************************************************************************************
                    从FIFO获取一个数据
参数:buff  要存数据的地址
返回:取得数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoGet    (MOD_FIFO_TYPE* buff, MOD_FIFO_NUM_TYPE len)
{
    MOD_FIFO_NUM_TYPE i;
    //LOCK
    if(ModFifo.FifoNum <= 0)
    {   //UNLOCK
        return 0;                                       //空的,直接返回
    }
    len = (len < ModFifo.FifoNum)?len:ModFifo.FifoNum;  //取最小值
    for (i = 0;i<len;i++)
    {
        *buff++ = ModFifo.FifoBuffer[ModFifo.FifoOut];

        if (++ModFifo.FifoOut >= MOD_FIFO_LEN)
        {
            ModFifo.FifoOut = 0;
        }
    }
    ModFifo.FifoNum -= len;
    return len;
}
/*****************************************************************************************
                    向FIFO存入一个数据
参数:buff  要存的数据
返回:成功存入数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoPutByte(MOD_FIFO_TYPE  buff)
{
    //LOCK
    //若此处无锁,若2线程同时 达到此处,都判断到未,同时加入数据则出问题了。
    if(ModFifo.FifoNum >= MOD_FIFO_LEN)
    {
        return 0;
    }
    //UNLOCK
    ModFifo.FifoBuffer[ModFifo.FifoIn] = buff;

    if (++ModFifo.FifoIn >= MOD_FIFO_LEN)
    {
        ModFifo.FifoIn = 0;
    }

    ModFifo.FifoNum++;
    return 1;
}
/*****************************************************************************************
                    从FIFO获取一个数据
参数:buff  要存数据的地址
返回:取得数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoGetByte(MOD_FIFO_TYPE* buff)
{
    //LOCK
    if(ModFifo.FifoNum <= 0)
    {   //UNLOCK
        return 0;                                       //空的,直接返回
    }
    *buff = ModFifo.FifoBuffer[ModFifo.FifoOut];
    if (++ModFifo.FifoOut >= MOD_FIFO_LEN)
    {
        ModFifo.FifoOut = 0;
    }

    ModFifo.FifoNum--;
    return 1;
}
/*****************************************************************************************
                    查询FIFO中已有数据个数
参数:无
返回:数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoDataNumGet(void)
{
    return ModFifo.FifoNum;
}

 

原创粉丝点击