FIFO in C

/*
fifo.c 
Description: Implements a FIFO buffer

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainer: Miguel Luis and Gregory Cristian
*/

#include "fifo.h"

static uint16_t FifoNext( Fifo_t *fifo, uint16_t index )
{
    return ( index + 1 ) % fifo->Size;
}

void FifoInit( Fifo_t *fifo, uint8_t *buffer, uint8_t queueCapcity, uint16_t size )
{
    fifo->Begin = 0;
    fifo->End = 0;
    fifo->Data = buffer;
    fifo->Size = size;
    fifo->Count = 0;
    fifo->QueueCapcity = queueCapcity;
}


uint8_t FifoPush( Fifo_t *fifo, uint8_t buf[] )
{
    bool rv = IsFifoFull(fifo);
    if (rv){
        //cm_printf("fifo full, cmd %02x\n", buf[6]);
        return false;
    }
    
    fifo->End = FifoNext( fifo, fifo->End );
    
    memcpy(fifo->Data + fifo->End * fifo->QueueCapcity, buf, buf[0] + 1 );
    fifo->Count++;
    
    return true;
}


uint8_t FifoPop( Fifo_t *fifo , uint8_t *out_data)
{
    uint8_t *p_data = NULL;
    uint8_t ret = IsFifoEmpty(fifo);
    
    if (ret){        
        return false;
    }
            
    p_data = fifo->Data + FifoNext( fifo, fifo->Begin ) * fifo->QueueCapcity;
    
    memcpy(out_data, p_data, p_data[0] + 1);

    fifo->Begin = FifoNext( fifo, fifo->Begin );
    
    fifo->Count--;    
    
    return true;
}


void FifoFlush( Fifo_t *fifo )
{
    fifo->Begin = 0;
    fifo->End = 0;
    fifo->Count = 0;
}

bool IsFifoEmpty( Fifo_t *fifo )
{
    
    return (fifo->Count == 0);
}

bool IsFifoFull( Fifo_t *fifo )
{    
    return (fifo->Count == fifo->Size);
}

fifo.c 

fifo.h

/*
fifo.h
Description: Implements a FIFO buffer

License: Revised BSD License, see LICENSE.TXT file include in the project

Maintainer: Miguel Luis and Gregory Cristian
*/
#ifndef __FIFO_H__
#define __FIFO_H__

#include <stdbool.h>
#include <stdint.h>
#include <string.h>

/*!
 * FIFO structure
 */
typedef struct Fifo_s
{
    uint16_t Begin;
    uint16_t End;
    uint8_t *Data;
    uint8_t  QueueCapcity;
    uint16_t Size;
    uint16_t Count;
}Fifo_t;

/*!
 * Initializes the FIFO structure
 *
 * \param [IN] fifo   Pointer to the FIFO object
 * \param [IN] buffer Buffer to be used as FIFO
 * \param [IN] size   Size of the buffer
 */
void FifoInit( Fifo_t *fifo, uint8_t *buffer, uint8_t queueCapcity, uint16_t size );

/*!
 * Pushes data to the FIFO
 *
 * \param [IN] fifo Pointer to the FIFO object
 * \param [IN] data Data to be pushed into the FIFO
 */
uint8_t FifoPush( Fifo_t *fifo, uint8_t buf[] );

/*!
 * Pops data from the FIFO
 *
 * \param [IN] fifo Pointer to the FIFO object
 * \retval data     Data popped from the FIFO
 */
uint8_t FifoPop( Fifo_t *fifo , uint8_t *out_data);

/*!
 * Flushes the FIFO
 *
 * \param [IN] fifo   Pointer to the FIFO object
 */
void FifoFlush( Fifo_t *fifo );

/*!
 * Checks if the FIFO is empty
 *
 * \param [IN] fifo   Pointer to the FIFO object
 * \retval isEmpty    true: FIFO is empty, false FIFO is not empty
 */
bool IsFifoEmpty( Fifo_t *fifo );

/*!
 * Checks if the FIFO is full
 *
 * \param [IN] fifo   Pointer to the FIFO object
 * \retval isFull     true: FIFO is full, false FIFO is not full
 */
bool IsFifoFull( Fifo_t *fifo );

#endif // __FIFO_H__

 

#define FIFO_SIZE    16
#define FIFO_QUE_CAPCAITY   255
   
static uint8_t g_fifo_buffer[FIFO_SIZE][FIFO_QUE_CAPCAITY] = {0};

uint8_t *p_fifo_data = g_fifo_buffer[0];

Fifo_t g_fifo = {0};
Fifo_t *p_fifo = &g_fifo;

static uint8_t g_trade_log[PORT_TOTAL_NUM][FIFO_QUE_CAPCAITY] = {0};


void fifo_init(void){
    
    FifoInit(p_fifo, p_fifo_data, FIFO_QUE_CAPCAITY, FIFO_SIZE);
}


void msg_enqueue(uint8_t port){
    
    //cm_printf("trade log enqueue %d\n", port);
    
    FifoPush(p_fifo, g_trade_log[port - 1]);
}


uint8_t msg_dequeue(uint8_t out_buf[], uint8_t *out_len){

   uint8_t rv = 0;
   
   rv = FifoPop(p_fifo, out_buf);
   if (rv){ 
       
       *out_len = out_buf[0];
       memcpy(out_buf, out_buf + 1, *out_len);
   }
   
   return rv;   
}

 

posted on 2024-06-20 11:58  wallywl  阅读(32)  评论(0)    收藏  举报