• arm-none-eabi-gcc下实现printf的两种方式


    方式1,移植第三方printf库:

    1. 下载地址:https://github.com/mpaland/printf

    2. 拷贝其中的printf.c和printf.h到本地;

    3. 重新实现 void _putchar(char character) 接口,使用具体串口发送ch数据,如在 uart_hal.c中重新实现该接口:

    1. void _putchar(char character)
    2. {
    3. UART_TypeDef *base = g_uart_bases[UART_CONSOLE_INSTANCE];
    4. uint32_t tmp_d = character;
    5. tmp_d &= 0xff;
    6. uart_drv_fput_char(base, tmp_d);
    7. }

    使用时可通过在printf.c开头部分或printf.h中增加或注释如下宏定义来关闭或开启特定打印模式:

    1. #define PRINTF_DISABLE_SUPPORT_FLOAT // 是否支持 %f 类的打印
    2. #define PRINTF_DISABLE_SUPPORT_EXPONENTIAL // 是否支持 %e 类的打印
    3. #define PRINTF_DISABLE_SUPPORT_LONG_LONG // 是否支持 %lld 类的打印
    4. #define PRINTF_DISABLE_SUPPORT_PTRDIFF_T // 是否支持 %ld 类的打印

    方式2,重新实现系统调用:

    1. 新增syscall.c文件,在其中添加如下代码:

    1. extern int __io_putchar(int ch);
    2. int _write(int file, char *ptr, int len)
    3. {
    4. int DataIdx;
    5. for (DataIdx = 0; DataIdx < len; DataIdx++)
    6. {
    7. __io_putchar( *ptr++ );
    8. }
    9. return len;
    10. }

    2. 重新实现 int __io_putchar(int ch) 接口,使用具体串口发送ch数据,如在 uart_hal.c中重新实现该接口:

    1. int __io_putchar(int ch)
    2. {
    3. UART_TypeDef *base = g_uart_bases[UART_CONSOLE_INSTANCE];
    4. uart_drv_fput_char(base, ch);
    5. return ch;
    6. }

    两种printf实现方式的比较:

    移植第三方printf库的优缺点:

    优点:

    • 除几个标准库外不依赖其他实现;

    • 可单独控制 %f,%e,%lld,%ld格式的打印实现,可根据需要精确控制;

    • 可更进一步对代码进行裁剪,如不使用sprintf类接口可对相关代码进行裁剪;

      缺点:

    • 相同优化等级下比实现系统调用方式代码体积大一些(只支持%d %s打印时在opt=O2时比前者大1.7kb);

    重新实现系统调用方式的优缺点:

    优点:

    • 相同优化等级下比移植第三方库代码体积小一些;

      缺点:

    • 不支持%f,%e,%lld类的打印

    • 代码不可裁剪;

  • 相关阅读:
    雷军在微博发文:小米澎湃 OS(Xiaomi HyperOS)正式版已完成封包
    三维视频融合技术如何为智慧城市建设赋能
    Python中两个最常用的单元测试框架unittest和pytest
    unity【动画】操作_角色动画控制器 c#
    OpenTiny HUICharts 正式开源发布,一个简单、易上手的图表组件库
    算法学习笔记2023.1
    一年顶十年
    软件测试:功能测试常用的测试用例大全
    Oracle/PLSQL: Group_ID Function
    C++课程设计《最短路径》
  • 原文地址:https://blog.csdn.net/ppdyhappy/article/details/134161701