当前位置: 首页 > java >正文

SOC-ESP32S3部分:5-IDF的日志管理

飞书文档https://x509p6c8to.feishu.cn/wiki/MUkSwSCw1ixhl2kvNL2cU708nHe

前面的代码中,我们一般直接使用printf进行日志打印,这在绝大多数情况下是没问题的。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"void app_main(void)
{int i = 0;while (1) {printf("[%d] Hello world!\n", i);i++;vTaskDelay(5000 / portTICK_PERIOD_MS);}
}

但是企业中开发项目,其实要求我们可以更好管理日志,例如调试的日志在发布时不打印,例如应为每个模块设置不同的日志级别。那应该如何实现呢?

1.1、使用日志组件

其实idf中就给我们提供了日志组件,我们可以直接使用,具体说明可以点击下方文档了解。

https://docs.espressif.com/projects/esp-idf/zh_CN/v5.4/esp32s3/api-reference/system/log.html

头文件
#include "esp_log.h"可使用下列宏来定义不同的日志级别:
ESP_LOGE - 错误
ESP_LOGW - 警告
ESP_LOGI - 普通
ESP_LOGD - 调试
ESP_LOGV - 冗余

函数说明

函数说明如下:
ESP_LOGE(const char *tag, const char *format, ...);
ESP_LOGW(const char *tag, const char *format, ...);
ESP_LOGI(const char *tag, const char *format, ...);
ESP_LOGD(const char *tag, const char *format, ...);
ESP_LOGV(const char *tag, const char *format, ...);参数说明:
const char *tag
含义:日志标签(Log Tag),是一个字符串指针,用于标识日志信息的来源。
const char *format, ...
含义:这是一个格式化字符串和可变参数列表。format 是一个字符串,用于指定输出日志的格式,类似于 printf 函数的格式化字符串;使用示例:
int temperature = 25;
const char *TAG = "SENSOR";
ESP_LOGD(TAG, "The current temperature is %d degrees Celsius", temperature);

如何使用idf的日志库呢?为了方便演示,我们新建工程03_log_project,然后执行idf.py fullclean

修改main.c代码如下

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"static const char* TAG = "MyModule";  //模块名称void app_main(void)
{ESP_LOGE(TAG, "this is esp log");    //错误日志,用于记录系统中发生的严重错误,这些错误通常会导致程序无法正常运行或产生严重的异常情况。ESP_LOGW(TAG, "this is esp log");    //警告日志,用于记录可能会影响程序正常运行,但不会导致程序崩溃的潜在问题或异常情况。ESP_LOGI(TAG, "this is esp log");    //信息日志,用于记录程序的正常运行状态和重要事件,帮助开发者了解程序的执行流程和关键操作的结果。ESP_LOGD(TAG, "this is esp log");    //调试日志,用于记录程序的详细执行过程和中间结果,主要用于开发和调试阶段,帮助开发者排查问题。ESP_LOGV(TAG, "this is esp log");    //详细日志,用于记录最详细的程序执行信息,输出的日志信息最多,会带来较大的系统开销,通常只在开发和调试阶段使用。while (1) {vTaskDelay(5000 / portTICK_PERIOD_MS);}
}

复制的工程需要编译前,需要执行idf.py fullclean清除之前编译的配置。

idf.py fullclean
idf.py set-target esp32s3 
idf.py build
idf.py flash monitor //烧录,需要自行指定端口-p xxxx

此时我们可以看到打印的各种彩色日志

但细看我们会发现,日志只打印了E W I三条,还有D V的没有打印,这是因为什么呢?

1.2、设置打印日志级别

我们回到官网的文档部分:

https://docs.espressif.com/projects/esp-idf/zh_CN/v5.4/esp32s3/api-reference/system/log.html

我们可以回到文档中看到有这么一个描述:

也就是说我们可以配置CONFIG_LOG_DEFAULT_LEVEL这个宏来决定打印日志的类型,等于或小于这个宏值能打印,高的不能打印,在sdkconfig文件中可以看到CONFIG_LOG_DEFAULT_LEVEL默认为3,所以ESP_LOG_ERROR、ESP_LOG_WARN、ESP_LOG_INFO都可以打印。

typedef enum {ESP_LOG_NONE    = 0,    /*!< No log output */ESP_LOG_ERROR   = 1,    /*!< Critical errors, software module can not recover on its own */ESP_LOG_WARN    = 2,    /*!< Error conditions from which recovery measures have been taken */ESP_LOG_INFO    = 3,    /*!< Information messages which describe normal flow of events */ESP_LOG_DEBUG   = 4,    /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ESP_LOG_VERBOSE = 5,    /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ESP_LOG_MAX     = 6,    /*!< Number of levels supported */
} esp_log_level_t;

那这个CONFIG_LOG_DEFAULT_LEVEL在哪里配置呢?答案就是上节课的menuconfig中

我们依次找Component config → Log → Log Level

然后就可以修改日志打印级别,我们修改为Verbose即可

然后重复按ESC退出保存即可,保存成功后,我们可以在工程sdkconfig文件中看到

然后再次编译、烧录、运行

idf.py build
idf.py flash monitor //烧录,需要自行指定端口-p xxxx

到这里,我们就可以看到所有的日志都打印出来了。

1.3、更加快捷的menuconfig搜索

前面我们手动一个个设置寻找然后选择,效率还是太低了,那有没有直接搜索设置名称的方式呢?那当然也是有的,我们执行idf.py menuconfig

按/,搜索LOG_DEFAULT_LEVEL,注意,这里没有CONFIG

就可以看到日志级别的菜单,然后点击Enter回车,就可以直接进入到最终的设置页面

然后在这里直接修改即可,是不是方便多了呢?

到这里,我们就可以回答课程一开始提出的问题了,在调试阶段,我们可以设置CONFIG_LOG_DEFAULT_LEVEL=5,这时候所有日志都会打印,在产品发布时,我们可以设置CONFIG_LOG_DEFAULT_LEVEL=1,这时候只会打印关键日志,一些调试的信息别人就看不到了。

http://www.xdnf.cn/news/7915.html

相关文章:

  • LVDS系列13:Xilinx Ultrascale系可编程输入延迟(三)
  • STM32之串口通信WIFI上云
  • Centos8安装 python3并保留系统的python2
  • C语言求1到n的和(附带源码和解析)
  • 华为云Flexus+DeepSeek征文|零基础搭建Dify-LLM应用开发平台 - 从部署到应用的完整指南
  • 关于光谱相机的灵敏度
  • C++学习之类和对象_2
  • 【web全栈】若依框架B站学习视频
  • 面向高温工业场景的EtherCAT/CANopen协议转换系统设计与应用
  • 互联网大厂Java求职面试:Spring Cloud微服务架构与AI集成挑战
  • Redis从入门到实战 - 高级篇(下)
  • Linux锁和互斥锁
  • 机器学习之随机森林(五)
  • Unity ​​MeshCollider 无法被射线检测到
  • TCP网络编程学习
  • PCB设计实践(二十三)什么是阻抗匹配,需要做啥
  • Backwards对自动路由的影响
  • ​​AirtestIDE-win-1.2.9 使用教程:从安装到脚本录制(Windows版)
  • YOLOv11旋转目标检测Hrsc2016
  • day25- 系统编程之 标准IO(II) 及 文件IO
  • 网络编程概述
  • 搭载1000nits激光显示技术,海信电视探索X1系列发布
  • 【18. 四数之和 】
  • 【Linux系统】第七节—git+cgdb(详解)
  • MySQL 中 information_schema.processlist 使用原理
  • RT_Thread——内存管理
  • golang库源码学习——Pond,小而精的工作池库
  • git仓库代码操作
  • springboot+vue实现鲜花商城系统源码(带用户协同过滤个性化推荐算法)
  • 【WebRTC】源码更改麦克风权限