リングバッファ
今回は、リングバッファについてです。
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; }