printf 其实是个 超小型、超快、零依赖 的格式化输出库,专门给 嵌入式系统 量身打造。普通的 libc printf 在 MCU 上一拖再拖,往往会把代码体积膨胀 20 KB 以上,还可能不够线程安全。这个库把所有必须的代码都塞进 printf.c,一个文件搞定,连浮点、指数、long long 都能按需裁剪。
它帮你解决了哪些痛点?
|
痛点 |
传统 libc |
这个 tiny printf |
| 代码体积 |
常常 > 20 KB |
只要 ~600 行源码,几 KB |
| 依赖 |
需要完整的 C 标准库 |
零依赖,单文件 |
| 线程安全 |
可能出现竞争 |
完全可重入、线程安全 |
| 可裁剪 |
功能固定,删不掉 |
通过宏开关关闭浮点、指数等 |
| 移植难度 |
需要链接 libc,平台限制多 |
只要的 |
| 调试/测试 |
难以保证全部 format 正确 |
超 400 条单元测试,覆盖率高 |
一句话:想省内存、想快、想稳,就选它。
装起来有多简单?
-
1. 把
printf.c和printf.h拉进你的工程。 -
2. 实现一个低层的字符输出函数
_putchar(比如 UART 发字节)。void _putchar(char ch) {
// 把 ch 发到串口、屏幕或调试口
UART_SendByte(ch);
}
3. 像使用标准库一样调用:
printf("温度是 %0.2f°C\n", temperature);
sprintf(buf, "ID=%08X", device_id);
4. 想要更灵活?直接用 fctprintf 把任意回调当成流:
fctprintf(my_log_func, NULL, "错误码: 0x%X\n", err);
如果担心缓冲突,强烈推荐 用 snprintf,把最大缓冲区长度写进去,安全又省心。
优点 & 缺点
优点
-
• 体积小:600 行左右源码,几 KB 就能跑。
-
• 零依赖:不需要任何外部库,直接编进 MCU。
-
• 全特性:支持
%d %u %x %f %e %g %s %c %p,还有宽度、精度、标志等完整格式。 -
• 可裁剪:宏开关关闭不需要的功能,进一步压缩体积。
-
• 线程安全:不使用全局静态缓冲区,随意并发调用。
-
• 测试覆盖:400+ 用例,基本保证标准兼容。
缺点
-
• 不支持宽字符(wchar_t),对中文宽字符的直接打印要自行转换。
-
• 浮点支持会稍微增大代码,如果 MCU 没有硬件浮点,关闭宏会更省空间。
-
• 需要自行实现
_putchar*输出,对新手来说稍有门槛(但大多数平台已有 UART 示例)。
小结
嵌入式项目常常因为 printf 把固件体积炸开而头疼,这个 tiny printf 用 “一行代码 + 一个回调” 的方式,既保留了强大的格式化功能,又把体积压到极限。可裁剪、零依赖、线程安全,基本满足所有对 代码体积、性能、可靠性 有苛刻要求的场景。要是你正为 MCU 的日志、调试、UI 文本而苦恼,赶紧把它拽进来试试吧。
项目地址: https://github.com/mpaland/printf