lwrb:一个用C11实现的超轻量级超简洁的 FIFO 环形缓冲区库

 


lwrb 是啥?
lwrb(Lightweight Generic Ring Buffer)其实就是一个超简洁的 FIFO 环形缓冲区库,纯 C(C11)实现。它把“先入先出”的数据队列包装成一个静态数组,省掉了动态内存分配的麻烦,还能在单写单读的场景下实现线程/中断安全。说白了,它就是让你的 MCU、DSP、甚至 AVR 在搬运数据时,既快又省资源的好帮手。


它解决了哪些痛点?

痛点

lwrb 的解决方案

动态内存不安全

完全使用静态数组,根本不用 malloc/free,避免碎片和泄漏

搬运数据慢

采用一次性 memcpy,比手写循环复制快很多

多线程/中断冲突

单写单读模式下,读写操作是原子指令(如 ARM Cortex‑M),天然安全

DMA 零拷贝难实现

缓冲区本身就是连续内存,直接给 DMA 用,省去拷贝开销

跨平台兼容性差

只依赖 size_t,几乎能跑在任何 C11 编译器上(只要注意小于 sizeof(size_t) 的 CPU 需要自行加原子保护)


安装 & 使用小指南

1️⃣ 获取源码

git clone https://github.com/MaJerle/lwrb.git

2️⃣ 把 lwrb.h、lwrb.c 加进你的工程
大多数 IDE 只需要把这两个文件拖进去,编译选项保持 C11 即可。

3️⃣ 初始化(示例代码)

#include "lwrb.h"

#define BUF_SIZE 256
static uint8_t buf[BUF_SIZE];
static lwrb_t rb;

void app_init(void) {
    /* 创建一个 256 字节的环形缓冲区 */
    lwrb_init(&rb, buf, BUF_SIZE);
}

4️⃣ 写入数据

uint8_t data_to_send[] = "Hello lwrb!";
size_t written = lwrb_write(&rb, data_to_send, sizeof(data_to_send));

5️⃣ 读取数据

uint8_t recv_buf[64];
size_t read = lwrb_read(&rb, recv_buf, sizeof(recv_buf));

6️⃣ 高级特性

  • • peek:lwrb_peek(&rb, recv_buf, len);(不消费)

  • • skip:lwrb_skip(&rb, len);(直接丢弃)

  • • 事件回调:lwrb_set_overflow_cb(&rb, overflow_handler);


优缺点速评

优点

缺点

零动态内存

,资源占用可预估

只能用在单写单读的 pipe 场景;多写多读需要自行加锁

线程/中断安全

(在支持原子 size_t 操作的 CPU 上)

对于 8 位 MCU(如 AVR)需要自行实现原子保护

DMA 友好

,零拷贝

不提供自动扩容,缓冲区大小必须在编译期确定

MIT 开源

,随意商用

文档相对简洁,入门时需要看源码了解细节

跨平台

,只依赖标准 C

只实现 FIFO,若需 LIFO、优先队列等高级结构,需要自行改造


总结一下
lwrb 就是那种“看起来很小,却能帮你省掉大把时间和内存”的神器。尤其是嵌入式项目里,常常要在 ISR、DMA、任务之间搬数据,手写环形缓冲区容易出错、效率低,直接把 lwrb 抖进来,省事儿又省心。只要你的平台支持原子 size_t 读写(大多数 Cortex‑M 系列都行),基本上“装上即用”。如果你在玩 AVR 那类超低位宽的芯片,记得自行加点原子保护——这点小折中也不算太大代价。

总之,想要在资源受限的环境里搞定可靠的数据流,lwrb 是个值得“一键集成”的选择。

项目地址:https://github.com/MaJerle/lwrb

 

发表评论