|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define cb_item_t uint8_t // item type
|
|
|
|
|
|
|
|
|
|
#define CB_ITEM_N 1024 // item number,实际可存入数据少一个,留一个空位表示满,以区别于空
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
cb_item_t buf[CB_ITEM_N];
|
|
|
|
|
int wrptr; // 写指针
|
|
|
|
|
int rdptr; // 读指针
|
|
|
|
|
} CircleBuffer_t;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Element Count in buffer */
|
|
|
|
|
static int CirBuf_Count(CircleBuffer_t *cirbuf)
|
|
|
|
|
{
|
|
|
|
|
return (cirbuf->wrptr - cirbuf->rdptr) & (CB_ITEM_N - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Space available in buffer */
|
|
|
|
|
static int CirBuf_Space(CircleBuffer_t *cirbuf)
|
|
|
|
|
{
|
|
|
|
|
return (cirbuf->rdptr - cirbuf->wrptr - 1) & (CB_ITEM_N - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int CirBuf_Empty(CircleBuffer_t *cirbuf)
|
|
|
|
|
{
|
|
|
|
|
return CirBuf_Count(cirbuf) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int CirBuf_Full(CircleBuffer_t *cirbuf)
|
|
|
|
|
{
|
|
|
|
|
return CirBuf_Space(cirbuf) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CirBuf_Clear(CircleBuffer_t *cirbuf)
|
|
|
|
|
{
|
|
|
|
|
cirbuf->rdptr = cirbuf->wrptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int CirBuf_Write(CircleBuffer_t *cirbuf, cb_item_t *buf, int num)
|
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
if(cirbuf->wrptr >= cirbuf->rdptr)
|
|
|
|
|
{
|
|
|
|
|
n = CB_ITEM_N - cirbuf->wrptr;
|
|
|
|
|
if(cirbuf->rdptr == 0)
|
|
|
|
|
n -= 1;
|
|
|
|
|
|
|
|
|
|
n = (n >= num) ? num : n;
|
|
|
|
|
|
|
|
|
|
memcpy(&cirbuf->buf[cirbuf->wrptr], buf, n * sizeof(cb_item_t));
|
|
|
|
|
|
|
|
|
|
cirbuf->wrptr = (cirbuf->wrptr + n) % CB_ITEM_N;
|
|
|
|
|
|
|
|
|
|
if((n == num) || CirBuf_Full(cirbuf))
|
|
|
|
|
return n;
|
|
|
|
|
else
|
|
|
|
|
return n + CirBuf_Write(cirbuf, &buf[n], num - n);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
n = CirBuf_Space(cirbuf);
|
|
|
|
|
|
|
|
|
|
n = (n >= num) ? num : n;
|
|
|
|
|
|
|
|
|
|
memcpy(&cirbuf->buf[cirbuf->wrptr], buf, n * sizeof(cb_item_t));
|
|
|
|
|
|
|
|
|
|
cirbuf->wrptr += n;
|
|
|
|
|
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int CirBuf_Read(CircleBuffer_t *cirbuf, cb_item_t *buf, int num)
|
|
|
|
|
{
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
if(cirbuf->wrptr >= cirbuf->rdptr)
|
|
|
|
|
{
|
|
|
|
|
n = CirBuf_Count(cirbuf);
|
|
|
|
|
|
|
|
|
|
n = (n >= num) ? num : n;
|
|
|
|
|
|
|
|
|
|
memcpy(buf, &cirbuf->buf[cirbuf->rdptr], n * sizeof(cb_item_t));
|
|
|
|
|
|
|
|
|
|
cirbuf->rdptr += n;
|
|
|
|
|
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
n = CB_ITEM_N - cirbuf->rdptr;
|
|
|
|
|
|
|
|
|
|
n = (n >= num) ? num : n;
|
|
|
|
|
|
|
|
|
|
memcpy(buf, &cirbuf->buf[cirbuf->rdptr], n * sizeof(cb_item_t));
|
|
|
|
|
|
|
|
|
|
cirbuf->rdptr = (cirbuf->rdptr + n) % CB_ITEM_N;
|
|
|
|
|
|
|
|
|
|
if((n == num) || CirBuf_Empty(cirbuf))
|
|
|
|
|
return n;
|
|
|
|
|
else
|
|
|
|
|
return n + CirBuf_Read(cirbuf, &buf[n], num - n);
|
|
|
|
|
}
|
|
|
|
|
}
|