ESP32学习笔记——LOG日志库的使用

注:本文由CHATGPT辅助创作,未经验证,实际工程使用请仔细甄别。
对于设置日志级别的几种方式(esp_log_level_set、CONFIG_LOG_DEFAULT_LEVEL、CONFIG_LOG_MAXIMUM_LEVEL、LOG_LOCAL_LEVEL )容易混淆,特此学习并记录。

文章目录

  • 一. 初始化与基础用法
  • 二. 日志级别
  • 三. 日志函数
  • 四. 设置日志级别
    • 1. esp_log_level_set(TAG, level)
    • 2. CONFIG_LOG_DEFAULT_LEVEL
    • 3. LOG_LOCAL_LEVEL
    • CONFIG_LOG_MAXIMUM_LEVEL
    • 三者的优先级和交互关系
  • 五. 日志格式

ESP官网参考链接:
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/system/log.html(日志库)

ESP32的日志库(esp_log.h)提供了一个简单而高效的方式来记录调试信息、错误和其他日志。使用这个库可以方便地将日志信息输出到串口、文件等,有助于开发过程中的调试和性能分析。以下是它的使用方法和一些常见的API。

一. 初始化与基础用法

在FreeRTOS系统中,只需包含头文件即可使用,不需要专门初始化。默认情况下,所有日志会输出到UART。

#include "esp_log.h"

二. 日志级别

ESP32的日志库支持以下几种日志级别,按优先级从高到低排列:

  • ESP_LOG_ERROR:错误信息,严重的问题。
  • ESP_LOG_WARN:警告信息,潜在问题。
  • ESP_LOG_INFO: 一般信息,系统状态或进程说明。
  • ESP_LOG_DEBUG:调试信息,用于开发阶段的详细信息。
  • ESP_LOG_VERBOSE:最详细的信息,一般用于跟踪代码流。

可以使用环境变量或代码设置日志级别控制输出。

三. 日志函数

以下是常见的日志函数,TAG是用来标记日志来源的字符串,可以方便地追踪日志属于哪个模块。

#define TAG "my_module"  // 定义一个TAG用于标记模块名称ESP_LOGE(TAG, "This is an error message: %d", error_code);    // 错误日志
ESP_LOGW(TAG, "This is a warning");                          // 警告日志
ESP_LOGI(TAG, "System is running at %d MHz", cpu_freq);      // 信息日志
ESP_LOGD(TAG, "Variable x = %d", x);                         // 调试日志
ESP_LOGV(TAG, "Entering function foo()");                    // 详细日志

这些宏会根据设置的日志级别进行编译,如果设置为较低的日志级别(例如ESP_LOG_INFO),则不会编译更高详细级别(如DEBUGVERBOSE),从而节省资源。
(见下章)

四. 设置日志级别

在ESP-IDF中,CONFIG_LOG_DEFAULT_LEVEL配置、 LOG_LOCAL_LEVEL宏定义、esp_log_level_set(TAG, level)函数,这三者都可以控制日志的输出级别,但它们的作用范围和应用时机各有不同。以下是这三个方法的详细说明和它们之间的区别:

1. esp_log_level_set(TAG, level)

启用 CONFIG_LOG_DYNAMIC_LEVEL_CONTROL 选项后,则可在运行时通过 esp_log_level_set() 更改日志级别。
动态更改日志级别提高了灵活性,但也会产生额外的代码开销。 如果应用程序不需要动态更改日志级别,并且不需要使用标签来控制每个模块的日志,建议禁用 CONFIG_LOG_DYNAMIC_LEVEL_CONTROL

  • 作用范围:运行时设置特定模块的日志级别。
  • 作用对象:仅针对指定的 TAG(模块)生效。
  • 生效时机:运行时动态控制,可以在代码的不同部分调整同一模块的日志级别。
  • 使用场景:当需要在运行时动态调整某个模块的日志级别时使用,例如调试特定模块而不影响其他模块的日志输出。
esp_log_level_set("my_module", ESP_LOG_WARN);  // 将"my_module"模块的日志级别设置为WARN
esp_log_level_set("*", ESP_LOG_INFO);  // 将所有模块的日志级别设置为INFO

注意,函数 esp_log_level_set() 无法将日志级别设置为高于 CONFIG_LOG_MAXIMUM_LEVEL 指定的级别。如需在编译时将特定文件的日志级别提高到此最高级别以上,请使用 LOG_LOCAL_LEVEL 宏。

2. CONFIG_LOG_DEFAULT_LEVEL

menuconfig 中,使用选项 CONFIG_LOG_DEFAULT_LEVEL 来设置日志级别。配置后,项目中所有模块的默认日志级别将被设置(如 ESP_LOG_WARN),即启用所有级别低于 CONFIG_LOG_DEFAULT_LEVEL 的日志。

  • 作用范围:全局默认日志级别,影响整个项目的日志输出。
  • 作用对象:所有模块的默认日志级别。
  • 生效时机:编译时配置,通过 menuconfig 设置。此选项在项目编译前生效,编译完成后无法动态更改。
  • 使用场景:用于为整个项目设置统一的日志级别,适合在正式发布时限制日志输出。

通过 menuconfig 配置:

idf.py menuconfig
# 进入 "Component config" -> "Log output" -> "Default log verbosity"
# 设置全局默认日志级别,例如设置为 WARN

3. LOG_LOCAL_LEVEL

  • 作用范围:文件级别,影响单个源文件的日志输出。
  • 作用对象:当前源文件中的所有日志宏调用。
  • 生效时机:编译时控制,必须在文件顶部定义;在编译时决定当前文件可输出的日志级别。
  • 使用场景:当某个源文件需要更高或更低的日志级别,而不影响其他文件的日志输出时使用。

在文件顶部定义:

#define LOG_LOCAL_LEVEL ESP_LOG_WARN
#include "esp_log.h"

这样设置后,当前文件中的所有日志输出会限制在 WARN 级别及以上,即使在代码中调用了 ESP_LOGD(),这些低级别日志也不会输出。

CONFIG_LOG_MAXIMUM_LEVEL

可以在 menuconfig 中使用选项 CONFIG_LOG_MAXIMUM_LEVEL 设置最高日志级别。这个选项默认被配置为默认级别,但这个选项也可以被配置为更高级别,将更多的可选日志编译到固件中。

三者的优先级和交互关系

  1. CONFIG_LOG_DEFAULT_LEVEL 是项目的全局默认日志级别,影响所有模块,但它可以被 esp_log_level_setLOG_LOCAL_LEVEL 覆盖。
  2. LOG_LOCAL_LEVEL 的优先级高于CONFIG_LOG_DEFAULT_LEVEL,并且只能影响定义了它的源文件。如果某文件定义了 #define LOG_LOCAL_LEVEL ESP_LOG_WARN,即便全局日志级别为 INFO,该文件仍会限制在 WARN 及以上。

总结

  • 如果想控制单个模块的日志输出,可以在代码中用 esp_log_level_set(TAG, level)
  • 如果希望在编译时控制单个文件的日志级别,可以使用 LOG_LOCAL_LEVEL。
  • 如果需要在项目整体上控制日志级别,使用 CONFIG_LOG_DEFAULT_LEVEL。

五. 日志格式

默认的日志输出格式包括时间戳、日志级别和标签等。输出样例如下:

I (200) my_module: System is running at 160 MHz

其中:

  • I 表示 INFO 级别。
  • (200) 表示时间戳(从系统启动以来的毫秒数)。
  • my_module 是 TAG 标签。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/5081.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【RAG系列】KG-RAG 用最简单的方式将知识图谱引入RAG

目录 前言 一、引入知识图谱的作用 二、引入知识图谱的挑战 三、KG-RAG的理论 query多跳有限性 知识局部密集性 四、KG-RAG的方法 向量入库 向量相似搜索 扩展子图 LLM Rerank LLM response 五、效果比对 六、源码 总结 前言 本文介绍一种比较新颖的RAG范式&am…

编程语言越来越多,为什么C/C++还没有被现在的时代淘汰呢?

近年来,随着人工智能、大数据等领域的兴起,各种新兴编程语言层出不穷,例如Python、Go等,它们以更简洁的语法、更丰富的库以及更友好的开发体验,吸引了大量开发者。 在这样的背景下,不少人开始质疑C/C这类“…

Docling:开源的文档解析工具,支持多种格式的解析和转换,可与其他 AI 工具集成

❤️ 如果你也关注大模型与 AI 的发展现状,且对大模型应用开发非常感兴趣,我会快速跟你分享最新的感兴趣的 AI 应用和热点信息,也会不定期分享自己的想法和开源实例,欢迎关注我哦! 🥦 微信公众号&#xff…

学习笔记:Spring框架源码Part.2——核心

学习视频链接:https://www.bilibili.com/video/BV1zd4y1L7YD Spring学习笔记——核心 前言第三章 容器和上下文一、认识bean工厂1、基础能力2、更强的枚举能力3、灵活的分层能力4、构建和自动装配的能力5、更强的配置能力6、更多配置项7、工厂的生命周期 二、bean工…

linux守护进程与后台进程的区别

守护进程与后台进程有以下区别: 1. 概念与定义 后台进程: 是指在操作系统后台运行的进程,它不与用户直接交互(没有连接到用户的终端)。用户在终端中启动一个程序并让其在后台运行(如通过在命令后加“&…

【360】基于springboot的志愿服务管理系统

摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装志愿服务管理系统软件来发挥其高效地信息处理的作用&#x…

【LLM Agents体验】Dify框架的安装指南

Dify简介: 核心功能‌12 ‌Dify是一款开源的大语言模型(LLM)应用开发平台,融合了后端即服务(Backend as a Service, BaaS)和LLMOps的理念,使开发者可以快速搭建生产级的生成式AI应用。LLMOps涵盖了大型语言模型的开发、…

TODO Error occurred while trying to proxy:【】

文章目录 场景异常解决 场景 使用 Ant Disign Pro 连接本地接口。 异常 Error occurred while trying to proxy: localhost:8000/api/login/account?token%20%20123[HPM] Error occurred while proxying request localhost:8000/api/login/account?token%20%20123 to http…

Linux 文件基本属性

1.Linux 文件基本属性 Linux 系统是一种典型的多用户系统,不同用户处于不同地位,拥有不同的权限。为了保护系统的安全性,Linux 系统对不同的用户访问同一文件(包括目录文件)的权限做了不同的规定。Linux 通常使用以下两…

数据结构-归并排序笔记

【数据结构】八大排序(超详解附动图源码)_数据结构排序-CSDN博客 看这个学思路 一 归并排序介绍: 归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解&#xf…

关于使用python pptx生成或“复制”PPT页面的问题

先说两个结论: 对于主题不完全相同的页面,pptx 无法完全复制PPT页面,文字图片可以复制,但是背景之类的无法复制pptx 无法直接在指定页码或者指定页面后插入页面 今天做项目的时候,需要根据PPT模板使用python生成相应…

Uniapp底部导航栏设置(附带PS填充图标教程)

首先需要注册和登录ifconfont官网,然后创建项目添加需要的图标 创建和添加图标库请参考:Uniapp在Vue环境中引入iconfont图标库(详细教程) 打开iconfont官网,找到之前添加的图标库,下载png图片 如果需要的…

算法——双指针

目录 前言一、什么是双指针二、算法特点三、算法实现步骤四、常见形式五、应用场景与示例六、优势与注意事项七、双指针算法动态图解八、经典例题[1. 回文判定](https://www.lanqiao.cn/problems/1371/learning/?page1&first_category_id1&name%E5%9B%9E%E6%96%87%E5%…

L6.【LeetCode笔记】合并两个有序链表

1.题目 https://leetcode.cn/problems/merge-two-sorted-lists/ 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4]示例 2&…

类的加载机制

一、类的生命周期 类从被加载到虚拟机内存中开始到卸载出内存为止,它的整个生命周期可以简单概括为 7 个阶段: 加载(Loading)验证(Verification)准备(Preparation)解析&#xff08…

接口测试用例设计的关键步骤与技巧解析

接口测试是确保系统组件之间高效、稳定交互的重要环节。然而,设计出合理的接口测试用例,并不是一件轻而易举的事。如何通过高质量的测试用例揭示潜在问题?今天带你深度解析接口测试用例设计的关键步骤和实用技巧,助你在测试领域更…

Java线程6种生命周期及转换

多线程技术是我们后端工程师在面试的时候必问的一个知识点,今天就来盘点一下多线程的相关知识, 先来说下进程,线程及线程的生命周期: 进程:进程就是正在进行中的程序,是没有生命的实体,只有在运…

柯桥学英语|老外说“You‘re cheap”,不是“你真便宜”!真正的意思是什么?

在跨文化交流中,误解常常源于对语言字面意义的直接翻译。今天,我们就来揭开一个常见的误解——“Youre cheap”的真实含义,并探讨与之相关的英文表达。 “Youre cheap”的真实含义 当老外对你说“Youre cheap”,千万别以为他们在…

IDEA构建JavaWeb项目,并通过Tomcat成功运行

目录 一、Tomcat简介 二、Tomcat安装步骤 1.选择分支下载 2.点击下载zip安装包 3.解压到没有中文、空格和特殊字符的目录下 4.双击bin目录下的startup.bat脚本启动Tomcat 5.浏览器访问Tomcat 6.关闭Tomcat服务器 三、Tomcat目录介绍 四、WEB项目的标准结构 五、WEB…

电商行业企业员工培训的在线知识库构建

在电商行业,员工的培训和发展对于保持竞争力至关重要。随着电子商务的兴起和消费者行为的变化,电商行业需要不断适应新的市场趋势。在线培训知识库作为一种有效的培训工具,可以帮助企业提升员工技能,优化客户服务,增强…