今天跟大伙儿唠一款最近超常用的开源项目——fifofast。说白了,它就是一个专门为单片机(MCU)量身定制的 FIFO(先入先出)环形缓冲区,比市面上那些常见实现更轻、更快、更灵活,特别适合那些资源捉襟见肘的小家伙儿。
啥是 fifofast?
简单讲,fifofast 是用纯 C 写的、零动态内存、超小管理开销(一般只要 3 字节!)的通用 FIFO 实现。你能用它缓冲串口数据、ADC 测量值,或者任意在中断和主程序里共享的数据。它让数据进进出出,都稳稳当当,还不费 CPU。
它解决了哪些痛点?
-
• 你想要一个“即插即用”的 FIFO,结果各种例子都要自己改一堆宏、写新函数?fifofast 直接宏声明、inline 支持,一行声明就能用。
-
• 大多数实现总是浪费空间:指针、索引都占不少 SRAM。fifofast 管理开销就是个小头儿。
-
• 不爽 if 跳转?它用 2ⁿ 环形缓冲巧妙地把
if(idx>=N) idx=0;变成位运算,跑得更快。 -
• 想存任意类型?
_fff_declare(int16_t, fifo16, 8);就能存,哪怕是自定义 struct。
核心特性一览
|
特性 |
说明 |
|
通用数据 |
支持任意 C 数据类型,连 typedef 过的 struct/union 都行 |
|
静态内存 |
无 malloc/free,全部用编译期分配,零碎片 |
|
Inline 支持 |
宏+inline,大量代码展开,ISR 调用也能快 |
|
极小 RAM 占用 |
管理只要 3 字节——读指针、写指针、元素计数 |
|
易用 API |
写、读、peek、rebase……典型的 FIFO 操作一个都不少 |
|
调试友好 |
Atmel Studio 7 自带断点、Peek 调试都行 |
|
清晰文档 |
源代码里注释细致,全靠注释就能看懂 API |
代码示例:一分钟上手
下面这段最精简的例子,你只需包含 fifofast.h,就能声明、初始化、读写:
#include "fifofast.h"
// 声明一个 16 元素的 int8_t 类型 fifo,名字叫 fifo_int8
_fff_declare(int8_t, fifo_int8,16);
// 在某个 .c 文件里初始化一次
_fff_init(fifo_int8);
int main(void){
volatile int8_t tmp;
_fff_write(fifo_int8,-42);// 写入
tmp = _fff_read(fifo_int8);// 读取
// tmp 现在是 -42
while(1){/* ... */}
}
不够?还支持 _fff_peek(fifo, idx) 直接随机访问、_fff_rebase() 把“环”搬平,好用标准字符串函数。更高级的还有点可寻址的 FIFO、FIFO 数组、数据对齐……功能别太多。
优缺点大评测
优点
-
• 零动态分配:可靠、不怕碎片
-
• CPU 时间少:位运算取代分支,ISR 里跑也快
-
• API 直观:写读 peek rebase,一套就行
-
• 文档到位:Atmel Studio debugger 支持、源码注释丰富
缺点
-
• 容量只能 2ⁿ(1、2、4、8……),会自动向上凑
-
• 点可寻址(pointerable)FIFO 元素最大 255 字节
-
• Inline/宏会让固件体积比普通函数实现稍大
总结
fifofast 就是那种——你插上就能用、不改晦涩宏、不担心碎片、ISR 调用刷刷刷的好家伙。特别适合资源受限、实时要求高的 AVR8、SAMG、SAML 等 MCU 项目。要是你把它当成串口缓存、ADC 环形缓冲、任务间消息队列来用,都没问题,而且调试简单。
项目地址:https/github.com/nqtronix/fifofast