文件功能:实现简单的FIFO功能
策 略:PUT时,若FIFO满,则不能载入后来的数据。
GUT时,按先入先出原则
/***************************************************************************************************
filename:uartfifo.h
文件功能:实现简单的FIFO功能
策 略:PUT时,若FIFO满,则不能载入后来的数据。
GUT时,按先入先出原则
编 者:张永辉 2012年11月28日
***************************************************************************************************/
#ifndef __UART_FIFO_H
#define __UART_FIFO_H
/**************************************************************************************************/
#define UART_FIFO_LEN 20 //FIFO长度 字节
#define UART_FIFO_TYPE unsigned char //FIFO数据类型
void UartFifoInit(void);
void UartFifoTest(void);
unsigned int UartFifoPut (UART_FIFO_TYPE* buff, unsigned int len);
unsigned int UartFifoGet (UART_FIFO_TYPE* buff, unsigned int len);
unsigned int UartFifoPutByte(UART_FIFO_TYPE buff);
unsigned int UartFifoGetByte(UART_FIFO_TYPE* buff);
/**************************************************************************************************/
#endif
/***************************************************************************************************
filename:uartfifo.c
文件功能:实现简单的FIFO功能
策 略:PUT时,若FIFO满,则不能载入后来的数据。
GUT时,按先入先出原则
***************************************************************************************************/
#include "uartfifo.h"
struct fifo
{
UART_FIFO_TYPE buffer[UART_FIFO_LEN];
unsigned int size;
unsigned int in; //指向下次要放入数据的地方。
unsigned int out; //指向下次要取出数据的地方。
bool iffull; //当in==out时: =1满 ==0空
//bool lockput; //多线程使用
//bool lockget;
};
static fifo UartFifo;
#define LOCK_PUT()
#define UNLOCK_PUT()
#define LOCK_GET()
#define UNLOCK_GET()
//多线程使用 不能用于多核。
//#define LOCK_PUT() while(UartFifo.lockput){CUPDELAY(1);} UartFifo.lockput = 1
//#define LOCK_PUT() while(UartFifo.lockput){;} UartFifo.lockput = 1
//#define UNLOCK_PUT() UartFifo.lockput = 0
//
//#define LOCK_GET() while(UartFifo.lockget){CUPDELAY(1);} UartFifo.lockget = 1
//#define LOCK_GET() while(UartFifo.lockget){;} UartFifo.lockget = 1
//#define UNLOCK_GET() UartFifo.lockget = 0
/***************************************************************************************************
函数功能: 测试函数
***************************************************************************************************/
void UartFifoTest(void)
{
UART_FIFO_TYPE a;
UartFifoInit();
UART_FIFO_TYPE b[] = "abcdefghijklmn";
UartFifoPut(b,3);
UartFifoPut(b,3);
UART_FIFO_TYPE e[10];
UartFifoGet(e,2);
UartFifoGet(e,2);
UartFifoGet(e,2);
UartFifoPutByte('1');
UartFifoPutByte('2');
UartFifoPutByte('3');
UartFifoPutByte('4');
UartFifoPutByte('5');
UartFifoPutByte('6');
UartFifoGetByte(&a);
UartFifoPutByte('a');
UartFifoPutByte('b');
UartFifoGetByte(&a);
UartFifoGetByte(&a);
}
/***************************************************************************************************
函数功能: 初始化函数
使用前,先调用此函数
***************************************************************************************************/
void UartFifoInit(void)
{
//初始化
UartFifo.size = UART_FIFO_LEN;
UartFifo.in = 0;
UartFifo.out = 0;
UartFifo.iffull = 0;
}
/***************************************************************************************************
函数功能: 向FIFO存入数据
UartFifoPut
输入: buff 要存入数据的指针
len 最大长度
返回: 存入数据的个数。
UartFifoPutByte
输入: 要存入的一个元素
返回: 存入数据的个数。
***************************************************************************************************/
unsigned int UartFifoPut(UART_FIFO_TYPE* buff,unsigned int len)
{
unsigned int i;
LOCK_PUT();
if( UartFifo.iffull == 1)
{ //满了,直接返回
UNLOCK_PUT();
return 0;
}
//剩余空间长度
i = (UartFifo.in >= UartFifo.out) ? (UartFifo.size - UartFifo.in + UartFifo.out) : (UartFifo.out - UartFifo.in);
//本次将复制的长度
len = (i < len) ? i : len;
i = 0;
while(len--)
{
UartFifo.buffer[UartFifo.in++] = buff[i++];
if(UartFifo.in >= UartFifo.size)
{
UartFifo.in = 0;
}
}
if(UartFifo.in == UartFifo.out)
{
UartFifo.iffull = 1; //FIFO满了
}
UNLOCK_PUT();
return i;
}
unsigned int UartFifoPutByte( UART_FIFO_TYPE buff)
{
LOCK_PUT();
if( UartFifo.iffull == 1) //若此处无锁,若2线程同时 达到此处,都判断到未,同时加入数据则出问题了。
{ //满了,直接返回
UNLOCK_PUT();
return 0;
}
UartFifo.buffer[UartFifo.in++] = buff;
if(UartFifo.in >= UartFifo.size)
{
UartFifo.in = 0;
}
if(UartFifo.in == UartFifo.out)
{
UartFifo.iffull = 1; //FIFO满了
}
UNLOCK_PUT();
return 1;
}
/***************************************************************************************************
函数功能: 向FIFO获取数据
UartFifoGet
输入: buff 要获取数据的指针
len 最大长度
返回: 存入数据的个数。
UartFifoGetByte
输入: 要获取的数据将存放的指针
返回: 存入数据的个数。
***************************************************************************************************/
unsigned int UartFifoGet(UART_FIFO_TYPE *buff , unsigned int len)
{
unsigned int i;
LOCK_GET();
//空的,直接返回
if(UartFifo.in == UartFifo.out && UartFifo.iffull == 0)
{
UNLOCK_GET();
return 0;
}
//已有数据数目
i = (UartFifo.in > UartFifo.out) ? (UartFifo.in - UartFifo.out) : (UartFifo.size - UartFifo.out + UartFifo.in);
//最大复制的长度
len = len < i ? len : i;
i = 0;
while(len--)
{
buff[i++] = UartFifo.buffer[UartFifo.out++];
if(UartFifo.out >= UartFifo.size)
{
UartFifo.out = 0;
}
}
if(i != 0)
{
UartFifo.iffull = 0; //FIFO不满了
}
UNLOCK_GET();
return i;
}
unsigned int UartFifoGetByte(UART_FIFO_TYPE *buff)
{
LOCK_GET();
//空的,直接返回
if(UartFifo.in == UartFifo.out && UartFifo.iffull == 0)
{
UNLOCK_GET();
return 0;
}
*buff = UartFifo.buffer[UartFifo.out];
UartFifo.out++;
if(UartFifo.out >= UartFifo.size)
{
UartFifo.out = 0;
}
UartFifo.iffull = 0; //FIFO不满了
UNLOCK_GET();
return 1;
}