用几百行代码把完整的printf格式化功能搬到了裸机环境

 


这个开源printf它到底是个啥?
printf,顾名思义就是把格式化好的字符串“喊”出来,传统的 stdio.h 实现太肥——在资源紧张的单片机上会把代码体积膨胀 20 KB 甚至更高。于是社区的 mpaland/printf 横空出世:只要把 printf.c 丢进项目,配上一个 _putchar(),立马拥有完整的 printf / sprintf / snprintf / fctprintf 功能,且 不依赖任何库,代码只有几百行,体积小到让人惊呼。


它解决了哪些痛点?

痛点

传统方式

这款 printf 的解决方案

代码体积爆炸

链入完整 libc,几十 KB

仅 600 行源码,几 KB 代码

线程安全/可重入性差

静态缓冲区、全局变量

完全不使用静态变量,随调用即安全

浮点/长整支持不完整

需要额外库或手动移植

支持 float、double、long long(可宏关闭)

依赖外部库

必须链接 libc,增加维护成本

零依赖,直接编译进项目

调试不友好

打印信息受限,格式不全

完整的 flag、宽度、精度、长度修饰符,几乎兼容标准 C99


怎么装、怎么用?

  1. 1. 下载源码:git clone https://github.com/mpaland/printf.git,把 printf.c、printf.h 拉进你的工程。

  2. 2. 实现低层输出:在项目里写个 _putchar(),把字符发到 UART、SWO 或者 LCD。

    void _putchar(char ch)
    {
        // 这里把字符写到串口
        UART_SendByte(ch);
    }
  • 3. 像使用标准库一样调用:

    printf("温度=%0.2f°C, 计数=%d\r\n", temperature, cnt);
    sprintf(buf, "ID:0x%X", device_id);
    snprintf(buf, sizeof(buf), "电压=%3.1fV", voltage);
    fctprintf(my_stream, NULL, "实时日志: %s", log);
  • 4. 可选宏:如果真的要极限压缩,可以在编译时加 -DPRINTF_DISABLE_SUPPORT_FLOAT、-DPRINTF_DISABLE_SUPPORT_LONG_LONG 等,去掉不需要的特性。


  • 优缺点一目了然

    优点

    说明

    体积小

    只要几 KB,适配所有资源受限的 MCU

    零依赖

    不需要 libc、new、malloc,直接编进裸机项目

    功能全

    完整的格式化支持(%d、%x、%f、%e、%b、%p…)

    线程安全

    没有全局状态,随调用即安全

    可裁剪

    通过宏关闭浮点、长整、指数等特性

    MIT 许可证

    商业项目随意使用,无侵权顾虑

    缺点

    说明

    需要自行实现 _putchar

    对新手来说多了一步底层适配

    不支持宽字符

    只处理普通 char,如果要打印 Unicode 需要自行扩展

    调试信息有限

    只能输出到实现的接口,若接口本身有问题会“看不见”日志


    总结一下
    如果你在做 STM32、ESP32、Raspberry‑Pi Pico 之类的嵌入式项目,别再硬搬 libc 的 printf,那等于是把体积炸弹装进你的固件。mpaland/printf 用几百行代码把完整的格式化功能搬到了裸机环境,零依赖、可裁剪、线程安全——简直是嵌入式开发者的福音。把它拉进项目,省的每次想打印调试信息时都要去翻库文档,直接写 printf("x=%d\r\n", x);,省时省力又省空间。


    项目地址:https://github.com/mpaland/printf

     

    发表评论