lwrb 是啥?
lwrb(Lightweight Generic Ring Buffer)其实就是一个超简洁的 FIFO 环形缓冲区库,纯 C(C11)实现。它把“先入先出”的数据队列包装成一个静态数组,省掉了动态内存分配的麻烦,还能在单写单读的场景下实现线程/中断安全。说白了,它就是让你的 MCU、DSP、甚至 AVR 在搬运数据时,既快又省资源的好帮手。
它解决了哪些痛点?
|
痛点 |
lwrb 的解决方案 |
| 动态内存不安全 |
完全使用静态数组,根本不用 |
| 搬运数据慢 |
采用一次性 |
| 多线程/中断冲突 |
单写单读模式下,读写操作是原子指令(如 ARM Cortex‑M),天然安全 |
| DMA 零拷贝难实现 |
缓冲区本身就是连续内存,直接给 DMA 用,省去拷贝开销 |
| 跨平台兼容性差 |
只依赖 |
安装 & 使用小指南
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 场景;多写多读需要自行加锁 |
| 线程/中断安全
(在支持原子 |
对于 8 位 MCU(如 AVR)需要自行实现原子保护 |
| DMA 友好
,零拷贝 |
不提供自动扩容,缓冲区大小必须在编译期确定 |
| MIT 开源
,随意商用 |
文档相对简洁,入门时需要看源码了解细节 |
| 跨平台
,只依赖标准 C |
只实现 FIFO,若需 LIFO、优先队列等高级结构,需要自行改造 |
总结一下
lwrb 就是那种“看起来很小,却能帮你省掉大把时间和内存”的神器。尤其是嵌入式项目里,常常要在 ISR、DMA、任务之间搬数据,手写环形缓冲区容易出错、效率低,直接把 lwrb 抖进来,省事儿又省心。只要你的平台支持原子 size_t 读写(大多数 Cortex‑M 系列都行),基本上“装上即用”。如果你在玩 AVR 那类超低位宽的芯片,记得自行加点原子保护——这点小折中也不算太大代价。
总之,想要在资源受限的环境里搞定可靠的数据流,lwrb 是个值得“一键集成”的选择。
项目地址:https://github.com/MaJerle/lwrb