RT-thread rt

    技术2022-07-20  79

    使用rt-thread的同学可能会发现,RT官方预留的打印功能rt_kprintf无法输出小数(不知道是不是全部版本都这样,我这里使用的是3.1.4的版本出现这种情况,使用MCU为stm32)

    即使用类似下方打印输出时

    float num = 10.0f; rt_kprintf("float %.2f\n", num);

    输出的结果并不是

    float 10.00

    而是

    float %f

    查看了下rt_kprintf这个函数的实现方式后发现问题

    官方对于这个函数的实现如下

    void rt_kprintf(const char *fmt, ...) { va_list args; rt_size_t length; static char rt_log_buf[RT_CONSOLEBUF_SIZE]; va_start(args, fmt); /* the return value of vsnprintf is the number of bytes that would be * written to buffer had if the size of the buffer been sufficiently * large excluding the terminating null byte. If the output string * would be larger than the rt_log_buf, we have to adjust the output * length. */ length = rt_vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args); if (length > RT_CONSOLEBUF_SIZE - 1) length = RT_CONSOLEBUF_SIZE - 1; #ifdef RT_USING_DEVICE if (_console_device == RT_NULL) { rt_hw_console_output(rt_log_buf); } else { rt_uint16_t old_flag = _console_device->open_flag; _console_device->open_flag |= RT_DEVICE_FLAG_STREAM; rt_device_write(_console_device, 0, rt_log_buf, length); _console_device->open_flag = old_flag; } #else rt_hw_console_output(rt_log_buf); #endif va_end(args); }

    仔细看会发现官方这里格式化参数调用的接口是RT自己实现的

    length = rt_vsnprintf(rt_log_buf, sizeof(rt_log_buf) - 1, fmt, args);

    阅读了下RT实现的方法发现并没有对%f进行处理,因此把官方使用的接口替换成stdio.h中的

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

    再次打印小数就正常了,注意修改完需添加头文件,即

    #include <stdio.h>

    目前暂未发现这样修改后有什么问题,所以也不清楚RT官方是出于什么原因使用这样的实现方式,如果后期使用出现问题的时候可自行修改回原来的方式

    Processed: 0.008, SQL: 9