165 lines
4.0 KiB
C
165 lines
4.0 KiB
C
/*
|
||
* 模块名称:Ring Buffer
|
||
* 模块功能:字节环形缓冲区实现,head == tail 为空,head + 1 == tail 为满
|
||
* 适用平台:通用嵌入式平台
|
||
* 作者:王建锋
|
||
* 创建日期:2026-07-19
|
||
* 修改记录:
|
||
* v1.0 2026-07-19 王建锋 创建初始版本
|
||
*/
|
||
|
||
#include "ringbuf.h"
|
||
|
||
/*
|
||
* 函数功能:初始化环形缓冲区
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* pool - 存储池指针
|
||
* size - 存储池大小(字节)
|
||
* 返 回 值:无
|
||
* 限定条件:rb 和 pool 均为非空指针
|
||
* 函数说明:size 保留一个空位用于区分空/满状态
|
||
*/
|
||
void ringbuf_init(ringbuf_t *rb, uint8_t *pool, size_t size)
|
||
{
|
||
rb->buf = pool;
|
||
rb->size = size;
|
||
rb->head = 0;
|
||
rb->tail = 0;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:写入数据到环形缓冲区
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* data - 源数据指针
|
||
* len - 待写入长度
|
||
* 返 回 值:实际写入字节数
|
||
* 限定条件:rb 和 data 均为非空指针
|
||
* 函数说明:空间不足时写入能容纳的最大字节数
|
||
*/
|
||
size_t ringbuf_put(ringbuf_t *rb, const uint8_t *data, size_t len)
|
||
{
|
||
size_t cap = 0;
|
||
size_t n = 0;
|
||
size_t i = 0;
|
||
|
||
cap = rb->size - 1 - ringbuf_avail(rb);
|
||
n = (len < cap) ? len : cap;
|
||
|
||
for (i = 0; i < n; i++) {
|
||
rb->buf[rb->head] = data[i];
|
||
rb->head = (rb->head + 1) % rb->size;
|
||
}
|
||
|
||
return n;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:从环形缓冲区读取数据
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* data - 目标数据指针
|
||
* len - 期望读取长度
|
||
* 返 回 值:实际读取字节数
|
||
* 限定条件:rb 和 data 均为非空指针
|
||
* 函数说明:读取后数据从缓冲区移除
|
||
*/
|
||
size_t ringbuf_get(ringbuf_t *rb, uint8_t *data, size_t len)
|
||
{
|
||
size_t n = 0;
|
||
size_t i = 0;
|
||
|
||
n = ringbuf_avail(rb);
|
||
n = (n < len) ? n : len;
|
||
|
||
for (i = 0; i < n; i++) {
|
||
data[i] = rb->buf[rb->tail];
|
||
rb->tail = (rb->tail + 1) % rb->size;
|
||
}
|
||
|
||
return n;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:预读取数据(不移除)
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* data - 目标数据指针
|
||
* len - 期望读取长度
|
||
* 返 回 值:实际可读取字节数
|
||
* 限定条件:rb 和 data 均为非空指针
|
||
* 函数说明:与 ringbuf_get 的区别是不移动 tail 指针
|
||
*/
|
||
size_t ringbuf_peek(const ringbuf_t *rb, uint8_t *data, size_t len)
|
||
{
|
||
size_t n = 0;
|
||
size_t i = 0;
|
||
size_t idx = 0;
|
||
|
||
n = ringbuf_avail(rb);
|
||
n = (n < len) ? n : len;
|
||
|
||
for (i = 0; i < n; i++) {
|
||
idx = (rb->tail + i) % rb->size;
|
||
data[i] = rb->buf[idx];
|
||
}
|
||
|
||
return n;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:获取缓冲区中有效数据长度
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* 返 回 值:有效数据字节数
|
||
* 限定条件:rb 为非空指针
|
||
*/
|
||
size_t ringbuf_avail(const ringbuf_t *rb)
|
||
{
|
||
if (rb->head >= rb->tail) {
|
||
return rb->head - rb->tail;
|
||
}
|
||
return rb->size - rb->tail + rb->head;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:获取缓冲区剩余空间
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* 返 回 值:剩余空间字节数(保留一个空位)
|
||
* 限定条件:rb 为非空指针
|
||
*/
|
||
size_t ringbuf_space(const ringbuf_t *rb)
|
||
{
|
||
return rb->size - 1 - ringbuf_avail(rb);
|
||
}
|
||
|
||
/*
|
||
* 函数功能:判断缓冲区是否为空
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* 返 回 值:1 - 空,0 - 非空
|
||
* 限定条件:rb 为非空指针
|
||
*/
|
||
int ringbuf_is_empty(const ringbuf_t *rb)
|
||
{
|
||
return (rb->head == rb->tail) ? 1 : 0;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:判断缓冲区是否为满
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* 返 回 值:1 - 满,0 - 非满
|
||
* 限定条件:rb 为非空指针
|
||
*/
|
||
int ringbuf_is_full(const ringbuf_t *rb)
|
||
{
|
||
return (ringbuf_avail(rb) == rb->size - 1) ? 1 : 0;
|
||
}
|
||
|
||
/*
|
||
* 函数功能:重置缓冲区
|
||
* 入口参数:rb - 缓冲区控制块指针
|
||
* 返 回 值:无
|
||
* 限定条件:rb 为非空指针
|
||
*/
|
||
void ringbuf_reset(ringbuf_t *rb)
|
||
{
|
||
rb->head = 0;
|
||
rb->tail = 0;
|
||
}
|