1、模型
2、代码实现
typedef struct {
uint32_t bufsize; /* round buffer size */
uint32_t used; /* round buffer used */
uint8_t *bptr; /* begin position */
uint8_t *eptr; /* end position */
uint8_t *wptr; /* write position */
uint8_t *rptr; /* read position */
} RoundBuf_t;
static void roundbuf_update_used(RoundBuf_t *round);
/*******************************************************************
** 函数名: roundbuf_init
** 函数描述: 初始化循环缓冲区
** 参数: [in] round: 循环缓冲区
** [in] mem: 循环缓冲区所管理的内存地址
** [in] memsize: 循环缓冲区所管理的内存字节数
** [in] rule: 循环缓冲区数据读取是的解码规则
** 返回: 实际可用长度为数组长度-1,防止写入指针追上读取指针
********************************************************************/
void roundbuf_init(RoundBuf_t *round, uint8_t *mem, uint32_t memsize)
{
round->bufsize = memsize-1;
round->used = 0;
round->bptr = mem;
round->eptr = mem + round->bufsize;
round->wptr = round->rptr = round->bptr;
}
/*******************************************************************
** 函数名: roundbuf_reset
** 函数描述: 复位循环缓冲区, 即将循环缓冲区的已使用字节数清0
** 参数: [in] round: 循环缓冲区
** 返回: 无
********************************************************************/
void roundbuf_reset(RoundBuf_t *round)
{
round->used = 0;
round->rptr = round->wptr = round->bptr;
}
/*******************************************************************
** 函数名: roundbuf_get_start_pos
** 函数描述: 获取循环缓冲区所管理内存的起始指针
** 参数: [in] round: 循环缓冲区
** 返回: 所管理内存的起始指针
********************************************************************/
uint8_t *roundbuf_get_start_pos(RoundBuf_t *round)
{
return round->bptr;
}
/*******************************************************************
** 函数名: roundbuf_write_byte
** 函数描述: 往循环缓冲区中写入一个字节的数据
** 参数: [in] round: 循环缓冲区
** [in] data: 待写入的数据
** 返回: 如写之前循环缓冲区中的使用字节数达到所管理内存的字节数,
** 则返回失败; 否则, 返回成功
********************************************************************/
bool roundbuf_write_byte(RoundBuf_t *round, uint8_t data)
{
if( NULL == round )
return false;
if( round->used >= round->bufsize )
return false;
*round->wptr = data;
if( round->wptr >= round->eptr )
{
round->wptr = round->bptr;
}
else
{
round->wptr++;
}
//更新缓存区已经使用的数量
roundbuf_update_used(round);
return true;
}
/*******************************************************************
** 函数名: roundbuf_read_byte
** 函数描述: 从循环缓冲区中读取一个字节的数据
** 参数: [in] round: 循环缓冲区
** 返回: 如读之前循环缓冲区中的使用字节数为0, 则返回-1;
** 否则, 返回读取到的字节
********************************************************************/
int32_t roundbuf_read_byte(RoundBuf_t *round)
{
int32_t ret;
//获取当前数组使用情况
if (round->used == 0)
return -1;
ret = *round->rptr;
if (round->rptr >= round->eptr)
{
round->rptr = round->bptr;
}
else
{
round->rptr++;
}
//更新缓存区已经使用的数量
roundbuf_update_used(round);
return ret;
}
/*******************************************************************
** 函数名: roundbuf_read_data
** 函数描述: 读循环缓冲区指定长度
** 参数: [in] round: 循环缓冲区
** [out] pdata: 要读数据块的指针
** [in] datalen: 要读数据块的字节数
** 返回: 实际读出数据长度
********************************************************************/
int32_t roundbuf_read_data(RoundBuf_t *round, uint8_t *pdata, uint32_t datalen)
{
uint32_t i, readlen;
uint32_t used = round->used;
if( used <= datalen )
{
readlen = used;
}
else
{
readlen = datalen;
}
for ( i = 0; i < readlen; i++ )
{
pdata[i] = *round->rptr;
if (round->rptr >= round->eptr)
{
round->rptr = round->bptr;
}
else
{
round->rptr++;
}
}
//更新缓存区已经使用的数量
roundbuf_update_used(round);
return readlen;
}
/*******************************************************************
** 函数名: roundbuf_read_byte_no_move_ptr
** 函数描述: 再不移动缓冲区指针的情况下,从循环缓冲区中读取一个字节的数据
** 参数: [in] round: 循环缓冲区
** 返回: 剩余的可用字节数
********************************************************************/
int32_t roundbuf_read_byte_no_move_ptr(RoundBuf_t *round)
{
if (round->used == 0)
return -1;
else
return *round->rptr;
}
/*******************************************************************
** 函数名: roundbuf_get_left
** 函数描述: 获取循环缓冲区中剩余的可用字节数
** 参数: [in] round: 循环缓冲区
** 返回: 剩余的可用字节数
********************************************************************/
uint32_t roundbuf_get_left(RoundBuf_t *round)
{
return (round->bufsize - round->used);
}
/*******************************************************************
** 函数名: roundbuf_update_used
** 函数描述: 更新循环缓冲区中已使用字节数
** 参数: [in] round: 循环缓冲区
** 返回: 无
********************************************************************/
static void roundbuf_update_used(RoundBuf_t *round)
{
if( (round->wptr) == (round->rptr) )
round->used = 0;
else if( (round->wptr) > (round->rptr) )
round->used = (round->wptr) - (round->rptr);
else //if( (round->wptr) < (round->rptr) )
round->used = ( (round->eptr) - (round->rptr) ) + ( (round->wptr) - (round->bptr) ) + 1 ;
}
/*******************************************************************
** 函数名: roundbuf_get_used
** 函数描述: 获取循环缓冲区中已使用字节数
** 参数: [in] round: 循环缓冲区
** 返回: 已使用的字节数
********************************************************************/
uint32_t roundbuf_get_used(RoundBuf_t *round)
{
return round->used;
}
/*******************************************************************
** 函数名: roundbuf_write_block
** 函数描述: 往循环缓冲区中写入一块数据单元
** 参数: [in] round: 循环缓冲区
** [in] bptr: 待写入数据块的指针
** [in] blksize: 待写入数据块的字节数
** 返回: 成功写入循环缓冲区的字节数
********************************************************************/
bool roundbuf_write_block(RoundBuf_t *round, uint8_t *bptr, uint32_t blksize)
{
if(blksize > roundbuf_get_left(round))
return false;
for(; blksize > 0; blksize--)
{
*round->wptr = *bptr++;
if( round->wptr >= round->eptr )
{
round->wptr = round->bptr;
}
else
{
round->wptr++;
}
}
//更新缓存区已经使用的数量
roundbuf_update_used(round);
return true;
}