循环缓冲队列(ringbuf)

#ifndef _RINGBUF_H_
#define _RINGBUF_H_

#define MAX_RINGBUF_SIZE_UART       (170 + 1)
#define RW_SIZE 8

typedef unsigned char   u8;
typedef unsigned short  u16;
typedef unsigned long   u32;

typedef signed char err_t;

#define FULL    -1
#define EMPTY   -2
#define FREE    -3
#define USED    -4

typedef struct {
    u32 head;   //出队列 - 写指针
    u32 tail;   //入队列 - 读指针
    u32 size;   //队列总长度

    u8 *space;  //队列空间
} RINGBUF_Typedef;

#define RINGBUF_IS_EMPTY(ringbuf)   ringbuf_is_empty(ringbuf)
#define RINGBUF_IS_FULL(ringbuf)    ringbuf_is_full(ringbuf)
#define RINGBUF_FREE(ringbuf)       ringbuf_free(ringbuf)
#define RINGBUF_USED(ringbuf)       ringbuf_used(ringbuf)

extern err_t ringbuf_init(RINGBUF_Typedef *ringbuf, u8 *space, u32 size);
extern err_t ringbuf_push(RINGBUF_Typedef *ringbuf, u8 data);
extern err_t ringbuf_pop(RINGBUF_Typedef *ringbuf, u8 *buf);
extern err_t ringbuf_write(RINGBUF_Typedef *ringbuf, u8 *data, u32 size);
extern err_t ringbuf_read(RINGBUF_Typedef *ringbuf, u8 *buf, u32 size);

extern u32 ringbuf_is_empty(RINGBUF_Typedef *ringbuf);
extern u32 ringbuf_is_full(RINGBUF_Typedef *ringbuf);
extern u32 ringbuf_free(RINGBUF_Typedef *ringbuf);
extern u32 ringbuf_used(RINGBUF_Typedef *ringbuf);

#endif /* ringbuf.h */
#include "ringbuf.h"

RINGBUF_Typedef ringbuf_uart;
u8 space_uart[MAX_RINGBUF_SIZE_UART];

err_t ringbuf_init(RINGBUF_Typedef *ringbuf, u8 *space, u32 size)
{
    ringbuf->head = 0;
    ringbuf->tail = 0;
    ringbuf->size = size;
    ringbuf->space = space;

    return 0;
}

err_t ringbuf_push(RINGBUF_Typedef *ringbuf, u8 data)
{
    if (RINGBUF_IS_FULL(ringbuf)) {
#ifdef DEBUG
        printf("ringbuf is full\n");
#endif
        return FULL;
    }

    ringbuf->space[ringbuf->tail] = data;
    ringbuf->tail = (ringbuf->tail + 1) % ringbuf->size;

    if ((ringbuf->tail + 1) % ringbuf->size == ringbuf->head) {
#ifdef DEBUG
        printf("ringbuf is full\n");
#endif
    }

    return 0;
}

err_t ringbuf_pop(RINGBUF_Typedef *ringbuf, u8 *buf)
{
    if (RINGBUF_IS_EMPTY(ringbuf)) {
#ifdef DEBUG
        printf("ringbuf is empty\n");
#endif
        return EMPTY;
    }

    *buf = ringbuf->space[ringbuf->head];

    ringbuf->head = (ringbuf->head + 1) % ringbuf->size;

    if (ringbuf->tail == ringbuf->head) {
#ifdef DEBUG
        printf("ringbuf is empty\n");
#endif
    }

    return 0;
}

err_t ringbuf_write(RINGBUF_Typedef *ringbuf, u8 *data, u32 size)
{
    if (RINGBUF_FREE(ringbuf) < size) {
#ifdef DEBUG
        printf("ringbuf is free < %d\n", size);
#endif
        return FREE;
    }

    if (size > 0 && size <= RW_SIZE) {
        while (size --) {
            ringbuf_push(ringbuf, data[RW_SIZE - (size + 1)]);
        } 
    } else{
#ifdef DEBUG
        printf("size is out of range\n");
#endif
    }

    return 0;
}

err_t ringbuf_read(RINGBUF_Typedef *ringbuf, u8 *buf, u32 size)
{
    if (RINGBUF_USED(ringbuf) < size) {
#ifdef DEBUG
        printf("ringbuf is used < %d\n", size);
#endif
        return USED;
    }

    if (size > 0 && size <= RW_SIZE) {
        while (size --) {
            ringbuf_pop(ringbuf, &buf[RW_SIZE - (size + 1)]);
        }
    } else {
#ifdef DEBUG
        printf("size is out of range\n");
#endif
    }

    return 0;
}

u32 ringbuf_is_empty(RINGBUF_Typedef *ringbuf)
{
    return (ringbuf->head == ringbuf->tail);
}

u32 ringbuf_is_full(RINGBUF_Typedef *ringbuf)
{
    return ((ringbuf->tail + 1) % ringbuf->size == ringbuf->head);
}

u32 ringbuf_free(RINGBUF_Typedef *ringbuf)
{
    return ((ringbuf->head) > (ringbuf->tail) ? ((ringbuf->size) - (ringbuf->head) - (ringbuf->tail)) : ((ringbuf->size) - ((ringbuf->tail) - (ringbuf->head))));
}

u32 ringbuf_used(RINGBUF_Typedef *ringbuf)
{
    return ((ringbuf->head) > (ringbuf->tail) ? ((ringbuf->size) - (ringbuf->head) + (ringbuf->tail)) : ((ringbuf->tail) - (ringbuf->head)));
}

猜你喜欢

转载自blog.csdn.net/u011958166/article/details/81110502
今日推荐