リングバッファ

今回は、リングバッファについてです。
Ring Buffer モジュールは、utils/ringbuf.c、utils/ringbuf.h に含まれています。
しかしながら、リードポインタのライトポインタ追い越しとか、1byte毎にポインタを
割り込み抑止して更新するとか、ちょっといただけないなと思い、リングバッファは、
自分で実装することにしました。

コードを貼ります。
今回の用途は、FIFOのみ、リード/ライトポインタとも自動インクリメントで事足りる
のでこのようになっています。

typedef struct {
    uint8_t *buff;
    uint32_t size;    // size must be exponent of 2
    uint32_t rPtr;
    uint32_t wPtr;
    uint32_t mask;
} ringbuff_if_t;

void init_buff(ringbuff_if_t *rb)
{
    rb->rPtr = 0;
    rb->wPtr = 0;
    rb->mask = rb->size - 1;
}

int putc_buff(ringbuff_if_t *rb, uint8 c)
{
    if (rb->wPtr < rb->rPtr + rb->size) {
        rb->buff[(rb->wPtr++) & rb->mask] = c;
        return 1;
    } else {
        return 0;
    }
}

uint8_t getc_buff(ringbuff_if_t *rb)
{
    if (rb->rPtr < rb->wPtr)
        return rb->buff[(rb->rPtr++) & rb->mask];
    else
        return rb->buff[(rb->rPtr - 1) & rb->mask];
}

int read_buff(ringbuff_if_t *rb, uint8_t *obuff, int len)
{
    int i;

    for (i = 0; i < len; i++) {
        if ((rb->rPtr + i) < rb->wPtr)
            obuff[i] = rb->buff[(rb->rPtr + i) & rb->mask];
        else
            break;
    }
    rb->rPtr += i;

    return i;
}

int write_buff(ringbuff_if_t *rb, uint8_t *ibuff, int len)
{
    int i;

    for (i = 0; i < len; i++) {
        if (putc_buff(rb, ibuff[i]) == 0)
            break;
    }

    return i;
}