/*****************************************************************************************
filename: modfifo.h
文件功能:实现简单的FIFO功能
策 略:PUT时,若FIFO满,则不能载入后来的数据。
GUT时,按先入先出原则
编译环境:VS2005 keil V4.14
编 者:张永辉 2012年11月28日
修 改:张永辉 2013年03月04日
修 改:张永辉 2013年03月07日 ModFifoDataNumGet()函数
修 改:张永辉 2013年03月08日 使用指针形式,注意需要支持函数重载。
*****************************************************************************************/
#ifndef __MOD_FIFO_H
#define __MOD_FIFO_H
/****************************************************************************************/
typedef struct st //自定义FIFO的单个元素类型
{ int a;
int b;
int c;
}SST;
#define MOD_FIFO_TYPE SST //FIFO数据类型,可以是static 或 char 或 long等
#define MOD_FIFO_NUM_TYPE unsigned int //FIFO数据计数器类型
typedef struct g_modfifo //FIFO控制模块
{
MOD_FIFO_TYPE *FifoBuffer;
MOD_FIFO_NUM_TYPE FifoLen;
MOD_FIFO_NUM_TYPE FifoNum; //FIFO未取走的数据个数
MOD_FIFO_NUM_TYPE FifoIn; //指向下次要放入数据的地方。
MOD_FIFO_NUM_TYPE FifoOut; //指向下次要取出数据的地方。
}ModFifo;
//*******************************函数声明*************************************************
void ModFifoTest(void);
void ModFifoInit(ModFifo * MF);
MOD_FIFO_NUM_TYPE ModFifoPutByte (ModFifo * MF,MOD_FIFO_TYPE * buff);
MOD_FIFO_NUM_TYPE ModFifoGetByte (ModFifo * MF,MOD_FIFO_TYPE * buff);
MOD_FIFO_NUM_TYPE ModFifoDataNumGet(ModFifo * MF);
/*****************************************************************************************/
#endif
/*****************************************************************************************
filename:modfifo.c
文件功能:实现简单的FIFO功能
策 略:PUT时,若FIFO满,则不能载入后来的数据。
GUT时,按先入先出原则
*****************************************************************************************/
#include "modfifo.h"
static void ModFifoMemCoy(char * a,char *b,MOD_FIFO_NUM_TYPE len);
/*****************************************************************************************
函数功能: 测试函数
*****************************************************************************************/
void ModFifoTest(void)
{
MOD_FIFO_TYPE tmp; //临时变量
MOD_FIFO_TYPE tmn; //临时变量
MOD_FIFO_TYPE a[5]; //FIFO
ModFifo f1; //FIFO的控制模块
f1.FifoBuffer = a; //将FIFO与控制模块建立联系
f1.FifoLen = 5;
ModFifoInit(&f1); //初始化FIFO
tmp.a = 99; //初始化临时变量
tmp.b = 17;
tmp.c = -12;
ModFifoPutByte(&f1,&tmp); //存
ModFifoPutByte(&f1,&tmp);
ModFifoGetByte(&f1,&tmn); //取
ModFifoGetByte(&f1,&tmn); //取
ModFifoGetByte(&f1,&tmn); //取
ModFifoPutByte(&f1,&tmp);
ModFifoPutByte(&f1,&tmp);
ModFifoPutByte(&f1,&tmp);
ModFifoDataNumGet(&f1);
while(1);
}
/*****************************************************************************************
函数功能: 初始化函数
使用前,先调用此函数
*/
void ModFifoInit(ModFifo * MF)
{
//初始化
MF->FifoNum = 0;
MF->FifoIn = 0;
MF->FifoOut = 0;
}
/*****************************************************************************************
向FIFO存入一个数据
参数:*MF *buff要存的数据指针
返回:成功存入数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoPutByte(ModFifo * MF,MOD_FIFO_TYPE * buff)
{
//LOCK
//若此处无锁,若2线程同时 达到此处,都判断到未,同时加入数据则出问题了。
if(MF->FifoNum >= MF->FifoLen)
{
return 0;
}
//UNLOCK
ModFifoMemCoy((char *)(&MF->FifoBuffer[MF->FifoIn]),(char *)buff,sizeof(MOD_FIFO_TYPE));
if (++MF->FifoIn >= MF->FifoLen)
{
MF->FifoIn = 0;
}
MF->FifoNum++;
return 1;
}
/*****************************************************************************************
从FIFO获取一个数据
参数:*MF *buff要存的数据指针
返回:取得数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoGetByte(ModFifo * MF,MOD_FIFO_TYPE * buff)
{
//LOCK
if(MF->FifoNum <= 0)
{ //UNLOCK
return 0; //空的,直接返回
}
ModFifoMemCoy((char *)buff,(char *)(&MF->FifoBuffer[MF->FifoOut]),sizeof(MOD_FIFO_TYPE));
if (++MF->FifoOut >= MF->FifoLen)
{
MF->FifoOut = 0;
}
MF->FifoNum--;
return 1;
}
/*****************************************************************************************
查询FIFO中已有数据个数
参数:*MF 结构指针
返回:数据的个数
*/
MOD_FIFO_NUM_TYPE ModFifoDataNumGet(ModFifo * MF)
{
return MF->FifoNum;
}
/*****************************************************************************************
MEMCOPY
参数:....
返回:无 此处为了执行速度快,未做其他判断。
*/
static void ModFifoMemCoy(char * a,char *b,MOD_FIFO_NUM_TYPE len)
{
while(len--)
{
*a ++ = *b++;
}
}