简单UARTFIFO的实现,此方法不限于UART

文件功能:实现简单的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;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值