Stm32F103&Rt_Thread系列开发——03 日志管理

Stm32F103&Rt_Thread系列开发——03 日志管理

一、前言:

        本系列教程教大家如何从0开始,在Stm32F1系列芯片上使用Rt_Thread实时操作系统进行程序开发,本教程选择的开发板为:正点原子Mini STM32F103RCT6开发板。

        在进行程序开发之前,先要建立日志管理,这样在程序开发过程中,才能根据日志信息准确定位程序所出现的问题。本章将介绍RT_Thread 的日志管理系统。

二、普通打印

1、打印函数

        学过stm32裸机的朋友,都知道裸机中是将C语言中的printf()函数进行重定向后,就可以在裸机代码中使用,在RT thread实时操作系统中,也提供了一个打印函数 rt_kprintf(); 该函数原型的路径在:/rt-thread/src/kservice.c中,其使用方法与printf()一致,并且官方推荐使用该函数,因为其效率高于printf();。唯一的缺点是,不支持浮点数打印。

使用案例:

//测试打印
const int number = 12;
const int hex = 0xa;
const char str[] = "this is test string!";
rt_kprintf("orange \n");
rt_kprintf("number: %d\n", number);
rt_kprintf("hex: %x\n", hex);
rt_kprintf("string: %s\n", str);
rt_kprintf("float: %f\n", numf);

//打印结果
orange 
number: 12
hex: a
string: this is test string!
float: %f

2、浮点数打印

前一节提到,rt_kprintf(); 不支持浮点数打印,那么当需要打印浮点数时,如何操作?笔者搜集了三种处理方法。

测试代码如下:

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include <stdio.h>

#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;
}

int main(void)
{
    //测试浮点打印
    const float pi = 3.14f;
    //方法1
    rt_kprintf("No1 pi = %d.%03d\n", (int)pi, (int)(pi*1000)%1000);
    //方法2
    dbg_printf("No2 pi = %f\n", pi);
    //方法3
    char tempchar[10];
    sprintf(tempchar, "No3 pi = %f\n", pi);
    rt_kprintf(tempchar);
    
    while (1)
    {
        rt_thread_mdelay(500);
    }
}

//测试结果
No1 pi = 3.140
No2 pi = 3.140000
No3 pi = 3.140000

方法1:应用了计算的方法,将浮点数的整数部分与小数部分单独打印。

方法2:运用vsnprintf()函数,重新封装了一个打印函数,进行打印。

方法3:使用:sprintf()函数,将格式化字符串,保存到一段char数组中,之后用rt_kprinf() 打印。

当然,还可以使用c库自带的prinf()函数,但是需要重定向串口。

3、番外,多格式打印

在做工程开发中,常用到有格式要求的数字输出,演示如下:

十进制输出使用%d,十六进制输出使用%x。而%2d,中的2表示输出宽度。%.2d与%02d类似,都表示宽度不足2时,向前方补0。%-2d表示后补空格。十六进制类似。

//输出
int a = 5;
rt_kprintf("%d\n", a);
rt_kprintf("%2d\n", a);
rt_kprintf("%.2d\n", a);
rt_kprintf("%-2d\n", a);
rt_kprintf("%02d\n", a);
//输出
5
 5
05
5 
05
//代码
int b = 0xf;
rt_kprintf("%x\n", b);
rt_kprintf("%2x\n", b);
rt_kprintf("%.2x\n", b);
rt_kprintf("%-2x\n", b);
rt_kprintf("%02x\n", b);
//输出
f
 f
0f
f 
0f

浮点数中,%.2f,表示,保留两位小数。

//代码
const float pi = 3.14159f;
dbg_printf("%f\n", pi);
dbg_printf("%.2f\n", pi);
dbg_printf("%.3f\n", pi);
// 输出
3.141590
3.14
3.142

三、日志打印

        平时使用日志时,需要区分日志等级,日志等级一般分为四个,分别是:错误(ERROR),警告(WARNING),信息(INFO),调试(LOG)。

        其中优先级为 错误 > 警告 > 信息 > 调试。我们可以在指定单个.c文件中日志的打印等级,指定打印等级后,高于该等级的日志会被打印,低于该等级的日志不会被打印。例如,指定打印等级为警告,则该文件中的错误与警告会被打印,而信息与调试不会被打印。

        Rt thread 有自带的打印日志,也可以配置轻量级日志ulog,本文介绍自带打印日志信息。

1、日志打印

打印日志的头文件为 ,该文件在/rt-thread/include/rtdbg.h中。

使用时,需要添加段名与打印等级,并包含头文件,示例如下:

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>

#define DBG_SECTION_NAME "main"
#define DBG_COLOR
#define DBG_LEVEL DBG_LOG       //调试
// #define DBG_LEVEL DBG_INFO      //信息
// #define DBG_LEVEL DBG_WARNING   //警告
// #define DBG_LEVEL DBG_ERROR     //错误
#include <rtdbg.h>

int mian()
{
    LOG_D("this is debug");
    LOG_I("this is information");
    LOG_W("this is working");
    LOG_E("this is error");
}

输出示例:

值得注意的是:由于头文件的包含具有顺序性,故在文件中,先包含其余模块头文件,再定义DBG_SECTION_NAME与DBG_LEVEL宏,最后再包含头文件。

四、结语

日志打印就介绍到这里了,下期分享更多精彩内容。

最后欢迎关注我的公众号,会定期推送嵌入式相关教程。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值