RT-Thread 入门学习笔记:浮点数终端格式打印的四种实现方法

简介

  • RT-Thread 的rt_kprintf,普通的格式打印没有问题,但是暂不支持打印%lf、%f这种浮点打印
  • 如何格式化打印浮点数呢?如float类型,如double类型
  • 默认rt_kprintf格式化打印浮点数:
    rt_kprintf("RMC : Latitude: %lf[%c], Longitude: %lf[%c], Fix: %c\n", pack.lat, pack.ns,
        pack.lon, pack.ew, pack.status);
  • 打印结果:
RMC : Latitude: %f[E], Longitude: %f[ix: H

打印原理

  • 标准C库提供字符串的格式化函数,rt_kprintf没有使用标准C库,为了降低ROM(Flash)的开销
  • 这里不直接使用标准C库的printfsprintf,使用的是:vsnprintf
  • RT-Thread rt_kprintf为了缩小代码体积,通过重新实现rt_vsnprintf的方式,实现了大部分vsnprintf功能。

第一种方法

  • 既然RT-Thread rt_kprintf使用了:rt_vsnprintf,直接改为:vsnprintf,就可以实现浮点数打印了
RMC : Latitude: 3115.642200[N], Longitude: 12127.549000[E], Fix: A
  • 当然增加了ROM(Flash)的占用,大概增加了7KB左右吧
  • 修改RT-Thread 系统的代码,总感觉不太好,还好,rt_kprintf是 weak弱属性,也就是用户可以重写

第二种方法

  • rt_kprintf的重写
  • 重写的代码的位置可以随便放,只是把rt_vsnprintf改为:vsnprintf

第三种方法:

  • 浮点打印的毕竟是少数,可以单独实现一个浮点打印的函数,基于vsnprintf,类似于rt_kprintf,如下:
#include 

#define DBG_BUFF_MAX_LEN          256

/* debug print : support float double */
int dbg_printf(const char *fmt, ...)
{
    va_list args;
    static char rt_log_buf[DBG_BUFF_MAX_LEN] = { 0 };

    va_start(args, fmt);
    int length = vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);

    rt_kputs(rt_log_buf);

    return length;
}

第四种方法

  • 开启ulog组件,并且开启浮点支持

RT-Thread 入门学习笔记:浮点数终端格式打印的四种实现方法_第1张图片

  • 因为ulog组件里的字符串格式化输出,开启浮点支持后,也调用了vsnprintf
  • 演示:
#define DBG_TAG    "nmea.test"
#define DBG_LVL     DBG_LOG
#include 

void nmea_parse_test_rmc(void)
{
    nmea_rmc_t pack = { 0 };

    nmea_parse_rmc(rmc_buf, rt_strlen(rmc_buf), &pack);
    LOG_D("RMC : Latitude: %lf[%c], Longitude: %lf[%c], Fix: %c\n", pack.lat, pack.ns,
        pack.lon, pack.ew, pack.status);
}
MSH_CMD_EXPORT(nmea_parse_test_rmc, nmea_parse_test_rmc);
  • 效果:
[6466] D/nmea.test: RMC : Latitude: 3115.642200[N], Longitude: 12127.549000[E], Fix: A

终极方法

  • 以上只是为了调试方便,简单的实现了浮点的打印,真正的实现就是优化:rt_vsnprintf,让它实现浮点的打印
  • 这要考虑实现的复杂度,是否代码的ROM(Flash)占用比标准C库小
  • 这个放在后面实现,可以参考一些类似于gcc的c库,参考标准C库vsnprintf【暂未实现】

小结

  • 普通的调试rt_kprintf本身就够了
  • 若有浮点打印需求,可以直接写一个专用的可以输出浮点的函数,类似于上面的【方法三】
  • 可以使用ulog等组件,实现LOG分级输出控制等,让输出管理起来更便捷

你可能感兴趣的:(RT-Thread,RT-Thread,浮点打印)