fifo在很多场景下都能用到,例如在串口中断中来不及接受数据,可以将数据先缓存起来,在线程中再进行处理
fifo也可以称为环形队列,填入数据时在头部填入,取数据从尾部取出

FIFO.c

#include "fifo.h"
#include "stdio.h"
void fifo_init(fifo_t *obj, uint8_t *data_buffer, uint32_t buffer_size)
{
    obj->data = data_buffer;
    obj->size = buffer_size;
    obj->head = 0;
    obj->tail = 0;
    obj->remain = 0;
    memset(obj->data, 0, buffer_size);
}
uint8_t fifo_empty(fifo_t *obj)
{
    return (obj->remain == 0);
}
uint8_t fifo_full(fifo_t *obj)
{
    return (obj->remain == obj->size);
}
void fifo_put(fifo_t *obj, uint8_t data)
{
    if (obj->head >= obj->size)
    {
        obj->head = 0;
    }

    if (obj->remain < obj->size)
    {
        ++obj->remain;
        obj->data[obj->head] = data;
        obj->head++;
    }
}
uint32_t fifo_puts(fifo_t *obj, uint8_t *data, uint32_t lenth)
{
    uint32_t put_lenth = 0;
    for (int i = 0; i < lenth; i++)
    {
        if (obj->remain >= obj->size)
        {
            break;
        }

        if (obj->head >= obj->size)
        {
            obj->head = 0;
        }

        obj->data[obj->head++] = data[i];
        ++obj->remain;
        ++put_lenth;
    }
    return put_lenth;
}
uint8_t fifo_get(fifo_t *obj)
{
    uint8_t data;
    if (obj->tail >= obj->size)
    {
        obj->tail = 0;
    }

    if (obj->remain > 0)
    {
        --obj->remain;
        data = obj->data[obj->tail++];
    }
    return data;
}
uint32_t fifo_gets(fifo_t *obj, uint8_t *data, uint32_t lenth)
{
    uint32_t get_cnt = 0;

    for (int i = 0; i < lenth; ++i)
    {
        if (obj->remain == 0)
        {
            break;
        }

        if (obj->tail >= obj->size)
        {
            obj->tail = 0;
        }

        data[i] = obj->data[obj->tail++];
        --obj->remain;
        ++get_cnt;
    }
    return get_cnt;
}
void fifo_log(fifo_t *obj)
{
    printf("\n");
    for (int i = 0; i < obj->size; i++)
    {
        printf(" %d ", obj->data[i]);
    }
    printf("\n");
}

FIFO.h

#ifndef _FIFO_H
#define _FIFO_H

#include <stdint.h>
#include <string.h>
typedef struct fifo
{
    uint8_t *data;
    uint8_t size;
    uint8_t head;
    uint8_t tail;
    uint8_t remain;
    uint8_t index;
} fifo_t;

void fifo_init(fifo_t *obj, uint8_t *data_buffer, uint32_t buffer_size);
uint8_t fifo_empty(fifo_t *obj);
uint8_t fifo_full(fifo_t *obj);
void fifo_put(fifo_t *obj, uint8_t data);
uint32_t fifo_puts(fifo_t *obj, uint8_t *data, uint32_t lenth);
uint8_t fifo_get(fifo_t *obj);
uint32_t fifo_gets(fifo_t *obj, uint8_t *data, uint32_t lenth);
void fifo_log(fifo_t *obj);
#endif

main.c (for test)

#include "fifo.h"
#include "stdio.h"
#define FIFO_LEN 16
static uint8_t fifo_buffer[FIFO_LEN];
fifo_t test_fifo;

int main(void)
{
    uint8_t data = 0;
    uint8_t read_buffer[20];
    fifo_init(&test_fifo, &fifo_buffer[0], FIFO_LEN);

    fifo_puts(&test_fifo, "hello world", strlen("hello world"));

    fifo_log(&test_fifo);

    fifo_gets(&test_fifo, read_buffer, strlen("hello world"));
    for (int i = 0; i < strlen("hello world"); i++)
    {
        data = fifo_get(&test_fifo);
        printf("get :%c\n", read_buffer[i]);
    }
    fifo_log(&test_fifo);
}
文章目录