mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
feat(log): Use esp_log func in all LOG macros
This commit is contained in:
parent
a29589e266
commit
a5bc08fb55
@ -1,5 +1,26 @@
|
||||
menu "Log"
|
||||
|
||||
choice BOOTLOADER_LOG_VERSION
|
||||
prompt "Log version"
|
||||
help
|
||||
Select the log version to be used by the ESP log component.
|
||||
The app log version (CONFIG_LOG_VERSION) controls the version used in the bootloader,
|
||||
preventing the selection of different versions.
|
||||
For description of V1 and V2 see CONFIG_LOG_VERSION.
|
||||
|
||||
config BOOTLOADER_LOG_VERSION_1
|
||||
bool "V1" if LOG_VERSION_1
|
||||
config BOOTLOADER_LOG_VERSION_2
|
||||
bool "V2" if LOG_VERSION_2
|
||||
endchoice
|
||||
|
||||
config BOOTLOADER_LOG_VERSION
|
||||
int
|
||||
default 1 if BOOTLOADER_LOG_VERSION_1
|
||||
default 2 if BOOTLOADER_LOG_VERSION_2
|
||||
help
|
||||
This configuration sets the log version number based on the chosen log version.
|
||||
|
||||
choice BOOTLOADER_LOG_LEVEL
|
||||
bool "Bootloader log verbosity"
|
||||
default BOOTLOADER_LOG_LEVEL_INFO
|
||||
|
@ -3,11 +3,23 @@ menu "Format"
|
||||
config BOOTLOADER_LOG_COLORS
|
||||
bool "Color"
|
||||
default n
|
||||
select BOOTLOADER_LOG_COLORS_SUPPORT if BOOTLOADER_LOG_VERSION_2
|
||||
help
|
||||
Use ANSI terminal colors in log output
|
||||
Enable ANSI terminal color codes.
|
||||
Enable ANSI terminal color codes. Logs (info, errors, warnings) will contain color codes.
|
||||
In order to view these, your terminal program must support ANSI color codes.
|
||||
|
||||
config BOOTLOADER_LOG_COLORS_SUPPORT
|
||||
bool "Allow enabling color output at run time"
|
||||
depends on BOOTLOADER_LOG_VERSION_2
|
||||
default n
|
||||
help
|
||||
Enables support for color codes in the esp_log() function. If CONFIG_LOG_COLORS is enabled, this option
|
||||
is always active. If CONFIG_LOG_COLORS is disabled, this option allows you to still handle color codes
|
||||
in specific files by defining ESP_LOG_COLOR_DISABLED as 0 before including esp_log.h.
|
||||
|
||||
Note that enabling this option may slightly increase RAM/FLASH usage due to additional color handling
|
||||
functionality. It provides flexibility to manage color output even when CONFIG_LOG_COLORS is turned off.
|
||||
|
||||
choice BOOTLOADER_LOG_TIMESTAMP_SOURCE
|
||||
prompt "Timestamp"
|
||||
default BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS
|
||||
@ -32,7 +44,21 @@ menu "Format"
|
||||
|
||||
config BOOTLOADER_LOG_TIMESTAMP_SOURCE_CPU_TICKS
|
||||
bool "Milliseconds Since Boot"
|
||||
select BOOTLOADER_LOG_TIMESTAMP_SUPPORT
|
||||
|
||||
endchoice # BOOTLOADER_LOG_TIMESTAMP_SOURCE
|
||||
|
||||
config BOOTLOADER_LOG_TIMESTAMP_SUPPORT
|
||||
bool "Allow enabling timestamp output at run time"
|
||||
depends on BOOTLOADER_LOG_VERSION_2
|
||||
default y
|
||||
help
|
||||
Enables support for timestamp in the esp_log() function.
|
||||
If CONFIG_LOG_TIMESTAMP_SOURCE_NONE, this option allows you to still handle timestamp
|
||||
in specific files by defining ESP_LOG_TIMESTAMP_DISABLED as 0 before including esp_log.h.
|
||||
|
||||
Note that enabling this option may slightly increase RAM/FLASH usage due to additional timestamp handling
|
||||
functionality. It provides flexibility to manage timestamp output even when
|
||||
CONFIG_LOG_TIMESTAMP_SOURCE_NONE.
|
||||
|
||||
endmenu
|
||||
|
@ -12,7 +12,9 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_private/log_util.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_private/cache_utils.h"
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "esp_flash_internal.h"
|
||||
#if CONFIG_NEWLIB_ENABLED
|
||||
@ -107,6 +109,8 @@ ESP_SYSTEM_INIT_FN(init_flash, CORE, BIT(0), 130)
|
||||
#if CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
spi_flash_needs_reset_check();
|
||||
#endif // CONFIG_SPI_FLASH_BROWNOUT_RESET
|
||||
// The log library will call the registered callback function to check if the cache is disabled.
|
||||
esp_log_util_set_cache_enabled_cb(spi_flash_cache_enabled);
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
|
@ -13,7 +13,11 @@ endif()
|
||||
|
||||
set(srcs "src/${system_target}/log_timestamp.c"
|
||||
"src/log_timestamp_common.c"
|
||||
"src/${system_target}/log_lock.c")
|
||||
"src/${system_target}/log_lock.c"
|
||||
"src/${system_target}/util.c"
|
||||
"src/log_print.c"
|
||||
"src/log.c")
|
||||
|
||||
set(priv_requires "")
|
||||
|
||||
if(NOT non_os_build)
|
||||
|
@ -1,5 +1,51 @@
|
||||
menu "Log"
|
||||
|
||||
choice LOG_VERSION
|
||||
prompt "Log version"
|
||||
default LOG_VERSION_1
|
||||
help
|
||||
Select the log version to be used by the ESP log component.
|
||||
|
||||
- "V1": This version integrates log formatting into the format string provided by the user.
|
||||
Logs are processed and formatted during compile time, leading to a larger binary file.
|
||||
Example: ESP_LOGI("boot", "chip revision: v%d.%d", major, minor);
|
||||
Output: I (56) boot: chip revision: v3.0
|
||||
Note: Log strings are stored in Flash with added formatting characters.
|
||||
Format string on flash: "[0;32mI (%lu) %s: chip revision: v%d.%d [0m"
|
||||
|
||||
- "V2": This version centralizes log formatting within the esp_log() function.
|
||||
User-supplied format strings are stored without added formatting, reducing binary size.
|
||||
Example: ESP_LOGI("boot", "chip revision: v%d.%d", major, minor);
|
||||
Output: I (56) boot: chip revision: v3.0
|
||||
Note: This version supports runtime configuration of formatting and is more flexible,
|
||||
logging from constrained environments (ex.: ISR, Startup, Cache disabled).
|
||||
It may consumes a bit more stack and affect performance.
|
||||
Format string on flash: "chip revision: v%d.%d"
|
||||
|
||||
Use V1 for minimal stack usage and simpler implementation.
|
||||
Use V2 for smaller binary sizes, more flexible log formatting, and advanced features like disabling
|
||||
colors or timestamps.
|
||||
|
||||
config LOG_VERSION_1
|
||||
bool "V1"
|
||||
help
|
||||
Select this option to use Log V1. Recommended for projects with strict stack constraints
|
||||
or that prioritize performance over flexibility.
|
||||
|
||||
config LOG_VERSION_2
|
||||
bool "V2"
|
||||
help
|
||||
Select this option to use Log V2. Recommended for projects that require smaller binaries,
|
||||
runtime log formatting configuration, or advanced logging features.
|
||||
endchoice
|
||||
|
||||
config LOG_VERSION
|
||||
int
|
||||
default 1 if LOG_VERSION_1
|
||||
default 2 if LOG_VERSION_2
|
||||
help
|
||||
This configuration sets the log version number based on the chosen log version.
|
||||
|
||||
orsource "./Kconfig.level"
|
||||
|
||||
orsource "./Kconfig.format"
|
||||
|
@ -3,10 +3,23 @@ menu "Format"
|
||||
config LOG_COLORS
|
||||
bool "Color"
|
||||
default n
|
||||
select LOG_COLORS_SUPPORT if LOG_VERSION_2
|
||||
help
|
||||
Enable ANSI terminal color codes.
|
||||
Enable ANSI terminal color codes. Logs (info, errors, warnings) will contain color codes.
|
||||
In order to view these, your terminal program must support ANSI color codes.
|
||||
|
||||
config LOG_COLORS_SUPPORT
|
||||
bool "Allow enabling color output at run time"
|
||||
depends on LOG_VERSION_2
|
||||
default n
|
||||
help
|
||||
Enables support for color codes in the esp_log() function. If CONFIG_LOG_COLORS is enabled, this option
|
||||
is always active. If CONFIG_LOG_COLORS is disabled, this option allows you to still handle color codes
|
||||
in specific files by defining ESP_LOG_COLOR_DISABLED as 0 before including esp_log.h.
|
||||
|
||||
Note that enabling this option may slightly increase IRAM usage due to additional color handling
|
||||
functionality. It provides flexibility to manage color output even when CONFIG_LOG_COLORS is turned off.
|
||||
|
||||
choice LOG_TIMESTAMP_SOURCE
|
||||
prompt "Timestamp"
|
||||
default LOG_TIMESTAMP_SOURCE_RTOS
|
||||
@ -43,14 +56,30 @@ menu "Format"
|
||||
|
||||
config LOG_TIMESTAMP_SOURCE_RTOS
|
||||
bool "Milliseconds Since Boot"
|
||||
select LOG_TIMESTAMP_SUPPORT if LOG_VERSION_2
|
||||
|
||||
config LOG_TIMESTAMP_SOURCE_SYSTEM
|
||||
bool "System Time (HH:MM:SS.sss)"
|
||||
select LOG_TIMESTAMP_SUPPORT if LOG_VERSION_2
|
||||
|
||||
config LOG_TIMESTAMP_SOURCE_SYSTEM_FULL
|
||||
bool "System Time (YY-MM-DD HH:MM:SS.sss)"
|
||||
depends on NO_SYMBOL # hide it now, turn it on final MR
|
||||
select LOG_TIMESTAMP_SUPPORT if LOG_VERSION_2
|
||||
depends on LOG_VERSION_2
|
||||
|
||||
endchoice # LOG_TIMESTAMP_SOURCE
|
||||
|
||||
config LOG_TIMESTAMP_SUPPORT
|
||||
bool "Allow enabling timestamp output at run time"
|
||||
depends on LOG_VERSION_2
|
||||
default y
|
||||
help
|
||||
Enables support for timestamp in the esp_log() function.
|
||||
If CONFIG_LOG_TIMESTAMP_SOURCE_NONE, this option allows you to still handle timestamp
|
||||
in specific files by defining ESP_LOG_TIMESTAMP_DISABLED as 0 before including esp_log.h.
|
||||
|
||||
Note that enabling this option may slightly increase IRAM usage due to additional timestamp handling
|
||||
functionality. It provides flexibility to manage timestamp output even when
|
||||
CONFIG_LOG_TIMESTAMP_SOURCE_NONE.
|
||||
|
||||
endmenu
|
||||
|
@ -393,15 +393,117 @@ TEST_CASE("esp_log_util_cvt")
|
||||
TEST_CASE("esp_log_timestamp_str")
|
||||
{
|
||||
char buffer[64];
|
||||
bool critical = true;
|
||||
uint64_t timestamp_ms = esp_log_timestamp64(critical);
|
||||
esp_log_timestamp_str(critical, timestamp_ms, buffer);
|
||||
bool constrained_env = true;
|
||||
uint64_t timestamp_ms = esp_log_timestamp64(constrained_env);
|
||||
esp_log_timestamp_str(constrained_env, timestamp_ms, buffer);
|
||||
const std::regex test_print(EARLY_TIMESTAMP, std::regex::ECMAScript);
|
||||
CHECK(regex_search(string(buffer), test_print) == true);
|
||||
|
||||
critical = false;
|
||||
timestamp_ms = esp_log_timestamp64(critical);
|
||||
esp_log_timestamp_str(critical, timestamp_ms, buffer);
|
||||
constrained_env = false;
|
||||
timestamp_ms = esp_log_timestamp64(constrained_env);
|
||||
esp_log_timestamp_str(constrained_env, timestamp_ms, buffer);
|
||||
const std::regex test_print2(TIMESTAMP, std::regex::ECMAScript);
|
||||
CHECK(regex_search(string(buffer), test_print2) == true);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_log with formatting")
|
||||
{
|
||||
PrintFixture fix(ESP_LOG_INFO);
|
||||
|
||||
esp_log_config_t config = {
|
||||
.opts = {
|
||||
.log_level = ESP_LOG_NONE,
|
||||
.constrained_env = false,
|
||||
.require_formatting = true,
|
||||
.dis_color = false,
|
||||
.dis_timestamp = false,
|
||||
.reserved = 0,
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i <= 10; i++) {
|
||||
if (5 <= i && i < 7) {
|
||||
config.opts.log_level = ESP_LOG_INFO;
|
||||
} else if (7 <= i && i < 9) {
|
||||
config.opts.log_level = ESP_LOG_WARN;
|
||||
} else if (9 <= i) {
|
||||
config.opts.log_level = ESP_LOG_ERROR;
|
||||
};
|
||||
|
||||
esp_log(config, TEST_TAG, "Temp = %dC", i);
|
||||
|
||||
if (5 <= i && i < 7) {
|
||||
const std::regex test_print("I \\(" TIMESTAMP "\\) test: Temp = [0-9]+C", std::regex::ECMAScript);
|
||||
CHECK(regex_search(fix.get_print_buffer_string(), test_print) == true);
|
||||
} else if (7 <= i && i < 9) {
|
||||
const std::regex test_print("W \\(" TIMESTAMP "\\) test: Temp = [0-9]+C", std::regex::ECMAScript);
|
||||
CHECK(regex_search(fix.get_print_buffer_string(), test_print) == true);
|
||||
} else if (9 <= i) {
|
||||
const std::regex test_print("E \\(" TIMESTAMP "\\) test: Temp = [0-9]+C", std::regex::ECMAScript);
|
||||
CHECK(regex_search(fix.get_print_buffer_string(), test_print) == true);
|
||||
} else {
|
||||
const std::regex test_print("", std::regex::ECMAScript);
|
||||
CHECK(regex_search(fix.get_print_buffer_string(), test_print) == true);
|
||||
}
|
||||
fix.reset_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("esp_log without formatting")
|
||||
{
|
||||
PrintFixture fix(ESP_LOG_INFO);
|
||||
|
||||
esp_log_config_t config = {
|
||||
.opts = {
|
||||
.log_level = ESP_LOG_NONE,
|
||||
.constrained_env = false,
|
||||
.require_formatting = false, // print just text
|
||||
.dis_color = false,
|
||||
.dis_timestamp = false,
|
||||
.reserved = 0,
|
||||
}
|
||||
};
|
||||
|
||||
for (int i = 0; i <= 10; i++) {
|
||||
if (5 <= i && i < 7) {
|
||||
config.opts.log_level = ESP_LOG_INFO;
|
||||
} else if (7 <= i && i < 9) {
|
||||
config.opts.log_level = ESP_LOG_WARN;
|
||||
} else if (9 <= i) {
|
||||
config.opts.log_level = ESP_LOG_ERROR;
|
||||
};
|
||||
|
||||
esp_log(config, TEST_TAG, "Temp = %dC\n", i);
|
||||
|
||||
if (i >= 5) {
|
||||
const std::regex test_print("Temp = [0-9]+C", std::regex::ECMAScript);
|
||||
CHECK(regex_search(fix.get_print_buffer_string(), test_print) == true);
|
||||
} else {
|
||||
const std::regex test_print("", std::regex::ECMAScript);
|
||||
CHECK(regex_search(fix.get_print_buffer_string(), test_print) == true);
|
||||
}
|
||||
fix.reset_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("esp_log TAG can be NULL")
|
||||
{
|
||||
PrintFixture fix(ESP_LOG_INFO);
|
||||
|
||||
esp_log_config_t config = {
|
||||
.opts = {
|
||||
.log_level = ESP_LOG_ERROR,
|
||||
.constrained_env = false,
|
||||
.require_formatting = true,
|
||||
.dis_color = false,
|
||||
.dis_timestamp = false,
|
||||
.reserved = 0,
|
||||
}
|
||||
};
|
||||
|
||||
esp_log(config, NULL, "Temp = %dC", 120);
|
||||
|
||||
const std::regex test_print("E \\(" TIMESTAMP "\\) Temp = 120C", std::regex::ECMAScript);
|
||||
CHECK(regex_search(fix.get_print_buffer_string(), test_print) == true);
|
||||
fix.reset_buffer();
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <inttypes.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "esp_log_config.h"
|
||||
#include "esp_log_level.h"
|
||||
#include "esp_log_color.h"
|
||||
#include "esp_log_buffer.h"
|
||||
@ -22,197 +23,256 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Logs a formatted message using the provided log message configs and a variable argument list.
|
||||
*
|
||||
* @param config Configuration and level of the log message.
|
||||
* @param tag The tag string used to indicate the component from which to log.
|
||||
* It is also used to check whether logging is enabled for that tag (depends on CONFIG_LOG_TAG_LEVEL_IMPL).
|
||||
* If NULL then the tag is not printed.
|
||||
* @param format The format string for the log message.
|
||||
* @param ... Optional arguments to be formatted according to the format string.
|
||||
*/
|
||||
void esp_log(esp_log_config_t config, const char* tag, const char* format, ...);
|
||||
|
||||
/**
|
||||
* @brief Logs a formatted message using the provided log message configs and a variable argument list.
|
||||
*
|
||||
* @param config Configuration and level of the log message.
|
||||
* @param tag The tag string used to indicate the component from which to log.
|
||||
* It is also used to check whether logging is enabled for that tag (depends on CONFIG_LOG_TAG_LEVEL_IMPL).
|
||||
* If NULL then the tag is not printed.
|
||||
* @param format The format string for the log message.
|
||||
* @param args List of arguments.
|
||||
*/
|
||||
void esp_log_va(esp_log_config_t config, const char *tag, const char *format, va_list args);
|
||||
|
||||
/// macro to output logs in startup code, before heap allocator and syscalls have been initialized.
|
||||
/// Log at ``ESP_LOG_ERROR`` level. @see ``printf``,``ESP_LOGE``,``ESP_DRAM_LOGE``
|
||||
|
||||
/**
|
||||
* In the future, we want to become compatible with clang.
|
||||
* Hence, we provide two versions of the following macros which are using variadic arguments.
|
||||
* The first one is using the GNU extension \#\#__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,).
|
||||
* The first one is using the GNU extension ``##__VA_ARGS__``. The second one is using the C++20 feature ``__VA_OPT__(,)``.
|
||||
* This allows users to compile their code with standard C++20 enabled instead of the GNU extension.
|
||||
* Below C++20, we haven't found any good alternative to using \#\#__VA_ARGS__.
|
||||
* Below C++20, we haven't found any good alternative to using ``##__VA_ARGS__``.
|
||||
*/
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_EARLY_LOGE( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR, E __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_WARN`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGW( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN, W __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_INFO`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGI( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_INFO, I __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGD( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG, D __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGV( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_EARLY_LOGE( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR, E, ##__VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_WARN`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGW( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN, W, ##__VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_INFO`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGI( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_INFO, I, ##__VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGD( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG, D, ##__VA_ARGS__)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf``
|
||||
#define ESP_EARLY_LOGV( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
/** @cond */
|
||||
#define ESP_EARLY_LOGE(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR, E __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_EARLY_LOGW(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN, W __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_EARLY_LOGI(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_INFO, I __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_EARLY_LOGD(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG, D __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_EARLY_LOGV(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
|
||||
#define ESP_LOG_EARLY_IMPL(tag, format, log_level, log_tag_letter, ...) do { \
|
||||
if (_ESP_LOG_EARLY_ENABLED(log_level)) { \
|
||||
esp_rom_printf(LOG_FORMAT(log_tag_letter, format), esp_log_timestamp(), tag, ##__VA_ARGS__); \
|
||||
}} while(0)
|
||||
|
||||
#if !NON_OS_BUILD
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_LOGE( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
#define ESP_LOGW( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
#define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
#define ESP_LOGD( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
#define ESP_LOGV( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_LOGE( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__)
|
||||
#define ESP_LOGW( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, tag, format, ##__VA_ARGS__)
|
||||
#define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__)
|
||||
#define ESP_LOGD( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, tag, format, ##__VA_ARGS__)
|
||||
#define ESP_LOGV( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format, ##__VA_ARGS__)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#if ESP_LOG_VERSION == 1 && NON_OS_BUILD
|
||||
#define ESP_LOGE(tag, format, ...) do { ESP_EARLY_LOGE(tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGW(tag, format, ...) do { ESP_EARLY_LOGW(tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGI(tag, format, ...) do { ESP_EARLY_LOGI(tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGD(tag, format, ...) do { ESP_EARLY_LOGD(tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGV(tag, format, ...) do { ESP_EARLY_LOGV(tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#else
|
||||
#define ESP_LOGE(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGW(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGI(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGD(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_LOGV(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#endif
|
||||
|
||||
#define ESP_DRAM_LOGE(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR, E __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_DRAM_LOGW(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN, W __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_DRAM_LOGI(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_INFO, I __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_DRAM_LOGD(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG, D __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
#define ESP_DRAM_LOGV(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__); } while(0)
|
||||
/** @endcond */
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
/**
|
||||
* @brief Early log macros to output logs in startup code, before heap allocator and syscalls have been initialized.
|
||||
* The log level can be changed per-tag using ``esp_log_level_set(TAG, level)``.
|
||||
*/
|
||||
/// macro to output logs in startup code at ``ESP_LOG_ERROR`` level.
|
||||
#define ESP_EARLY_LOGE(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR, E, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_WARN`` level.
|
||||
#define ESP_EARLY_LOGW(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN, W, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_INFO`` level.
|
||||
#define ESP_EARLY_LOGI(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_INFO, I, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level.
|
||||
#define ESP_EARLY_LOGD(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG, D, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level.
|
||||
#define ESP_EARLY_LOGV(tag, format, ...) do { ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__); } while(0)
|
||||
|
||||
/**
|
||||
* Macro to output logs at ESP_LOG_ERROR level.
|
||||
*
|
||||
* @note This macro cannot be used when interrupts are disabled or inside an ISR. @see ``ESP_DRAM_LOGE``.
|
||||
*
|
||||
* @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime.
|
||||
*
|
||||
* @see ``printf``
|
||||
* @brief Normal logging macros to output logs.
|
||||
* The log level can be changed per-tag using ``esp_log_level_set(TAG, level)``.
|
||||
*/
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_LOGE( tag, format, ... ) ESP_EARLY_LOGE(tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_WARN`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGW( tag, format, ... ) ESP_EARLY_LOGW(tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_INFO`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGI( tag, format, ... ) ESP_EARLY_LOGI(tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_DEBUG`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGD( tag, format, ... ) ESP_EARLY_LOGD(tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_VERBOSE`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGV( tag, format, ... ) ESP_EARLY_LOGV(tag, format __VA_OPT__(,) __VA_ARGS__)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_LOGE( tag, format, ... ) ESP_EARLY_LOGE(tag, format, ##__VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_WARN`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGW( tag, format, ... ) ESP_EARLY_LOGW(tag, format, ##__VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_INFO`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGI( tag, format, ... ) ESP_EARLY_LOGI(tag, format, ##__VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_DEBUG`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGD( tag, format, ... ) ESP_EARLY_LOGD(tag, format, ##__VA_ARGS__)
|
||||
/// macro to output logs at ``ESP_LOG_VERBOSE`` level. @see ``ESP_LOGE``
|
||||
#define ESP_LOGV( tag, format, ... ) ESP_EARLY_LOGV(tag, format, ##__VA_ARGS__)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#endif // !NON_OS_BUILD
|
||||
#if ESP_LOG_VERSION == 1 && NON_OS_BUILD
|
||||
/// macro to output logs at ``ESP_LOG_ERROR`` level.
|
||||
#define ESP_LOGE(tag, format, ...) do { ESP_EARLY_LOGE(tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_WARN`` level.
|
||||
#define ESP_LOGW(tag, format, ...) do { ESP_EARLY_LOGW(tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_INFO`` level.
|
||||
#define ESP_LOGI(tag, format, ...) do { ESP_EARLY_LOGI(tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_DEBUG`` level.
|
||||
#define ESP_LOGD(tag, format, ...) do { ESP_EARLY_LOGD(tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_VERBOSE`` level.
|
||||
#define ESP_LOGV(tag, format, ...) do { ESP_EARLY_LOGV(tag, format, ##__VA_ARGS__); } while(0)
|
||||
#else
|
||||
/// macro to output logs at ``ESP_LOG_ERROR`` level.
|
||||
#define ESP_LOGE(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_WARN`` level.
|
||||
#define ESP_LOGW(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_INFO`` level.
|
||||
#define ESP_LOGI(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_DEBUG`` level.
|
||||
#define ESP_LOGD(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, tag, format, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs at ``ESP_LOG_VERBOSE`` level.
|
||||
#define ESP_LOGV(tag, format, ...) do { ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format, ##__VA_ARGS__); } while(0)
|
||||
#endif
|
||||
|
||||
/** runtime macro to output logs at a specified level.
|
||||
/**
|
||||
* @brief Macros to output logs when the cache is disabled.
|
||||
* Unlike normal logging macros, it's possible to use this macro when interrupts are disabled or inside an ISR.
|
||||
* Placing log strings in DRAM reduces available DRAM, so only use when absolutely essential.
|
||||
*
|
||||
* Usage: `ESP_DRAM_LOGE(DRAM_STR("my_tag"), "format", ...), or `ESP_DRAM_LOGE(TAG, "format", ...)`,
|
||||
* where TAG is a char* that points to a str in the DRAM.
|
||||
*/
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_ERROR`` level.
|
||||
#define ESP_DRAM_LOGE(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR, E, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_WARN`` level.
|
||||
#define ESP_DRAM_LOGW(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN, W, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_INFO`` level.
|
||||
#define ESP_DRAM_LOGI(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_INFO, I, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_DEBUG`` level.
|
||||
#define ESP_DRAM_LOGD(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG, D, ##__VA_ARGS__); } while(0)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_VERBOSE`` level.
|
||||
#define ESP_DRAM_LOGV(tag, format, ...) do { ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__); } while(0)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
|
||||
/// runtime macro to output logs at a specified configs. Also check the level with ``LOG_LOCAL_LEVEL``.
|
||||
#if ESP_LOG_VERSION == 2
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_LOG_LEVEL_LOCAL(configs, tag, format, ...) do { if (ESP_LOG_ENABLED(configs)) { ESP_LOG_LEVEL(configs, tag, format __VA_OPT__(,) __VA_ARGS__); } } while(0)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_LOG_LEVEL_LOCAL(configs, tag, format, ...) do { if (ESP_LOG_ENABLED(configs)) { ESP_LOG_LEVEL(configs, tag, format, ##__VA_ARGS__); } } while(0)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#else // ESP_LOG_VERSION == 1
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_LOG_LEVEL_LOCAL(configs, tag, format, ...) do { if (_ESP_LOG_ENABLED(configs)) { ESP_LOG_LEVEL(configs, tag, format __VA_OPT__(,) __VA_ARGS__); } } while(0)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_LOG_LEVEL_LOCAL(configs, tag, format, ...) do { if (_ESP_LOG_ENABLED(configs)) { ESP_LOG_LEVEL(configs, tag, format, ##__VA_ARGS__); } } while(0)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#endif // ESP_LOG_VERSION == 1
|
||||
|
||||
/** runtime macro to output logs at a specified level and with ESP_LOG_CONFIGS_DEFAULT.
|
||||
*
|
||||
* @param configs it includes level and other log configurations.
|
||||
* @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime.
|
||||
* @param level level of the output log.
|
||||
* @param format format of the output log. See ``printf``
|
||||
* @param ... variables to be replaced into the log. See ``printf``
|
||||
*
|
||||
* @see ``printf``
|
||||
*/
|
||||
#if ESP_LOG_VERSION == 2
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
esp_log(ESP_LOG_CONFIG_INIT(configs | ESP_LOG_CONFIGS_DEFAULT), tag, format __VA_OPT__(,) __VA_ARGS__); \
|
||||
} while(0)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
esp_log(ESP_LOG_CONFIG_INIT(configs | ESP_LOG_CONFIGS_DEFAULT), tag, format, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
|
||||
#else // ESP_LOG_VERSION == 1
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#if CONFIG_LOG_TIMESTAMP_SOURCE_RTOS
|
||||
#define ESP_LOG_LEVEL(level, tag, format, ...) do { \
|
||||
if (level==ESP_LOG_ERROR ) { esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_WARN ) { esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_DEBUG ) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_VERBOSE ) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else { esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_ERROR) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_ERROR), tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_WARN) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_WARN), tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_DEBUG) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_DEBUG), tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_VERBOSE) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_VERBOSE), tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_INFO), tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
} while(0)
|
||||
#elif CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM
|
||||
#define ESP_LOG_LEVEL(level, tag, format, ...) do { \
|
||||
if (level==ESP_LOG_ERROR ) { esp_log_write(ESP_LOG_ERROR, tag, LOG_SYSTEM_TIME_FORMAT(E, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_WARN ) { esp_log_write(ESP_LOG_WARN, tag, LOG_SYSTEM_TIME_FORMAT(W, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_DEBUG ) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_SYSTEM_TIME_FORMAT(D, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_VERBOSE ) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_SYSTEM_TIME_FORMAT(V, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else { esp_log_write(ESP_LOG_INFO, tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_ERROR) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_ERROR), tag, LOG_SYSTEM_TIME_FORMAT(E, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_WARN) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_WARN), tag, LOG_SYSTEM_TIME_FORMAT(W, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_DEBUG) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_DEBUG), tag, LOG_SYSTEM_TIME_FORMAT(D, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_VERBOSE) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_VERBOSE), tag, LOG_SYSTEM_TIME_FORMAT(V, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_INFO), tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
} while(0)
|
||||
#elif NON_OS_BUILD
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_ERROR) { ESP_EARLY_LOGE(tag, format __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_WARN) { ESP_EARLY_LOGW(tag, format __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_DEBUG) { ESP_EARLY_LOGD(tag, format __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_VERBOSE) { ESP_EARLY_LOGV(tag, format __VA_OPT__(,) __VA_ARGS__); } \
|
||||
else { ESP_EARLY_LOGI(tag, format __VA_OPT__(,) __VA_ARGS__); } \
|
||||
} while(0)
|
||||
#endif //CONFIG_LOG_TIMESTAMP_SOURCE_xxx
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#if CONFIG_LOG_TIMESTAMP_SOURCE_RTOS
|
||||
#define ESP_LOG_LEVEL(level, tag, format, ...) do { \
|
||||
if (level==ESP_LOG_ERROR ) { esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_WARN ) { esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_DEBUG ) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_VERBOSE ) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else { esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_ERROR) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_ERROR), tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_WARN) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_WARN), tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_DEBUG) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_DEBUG), tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_VERBOSE) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_VERBOSE), tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_INFO), tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
} while(0)
|
||||
#elif CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM
|
||||
#define ESP_LOG_LEVEL(level, tag, format, ...) do { \
|
||||
if (level==ESP_LOG_ERROR ) { esp_log_write(ESP_LOG_ERROR, tag, LOG_SYSTEM_TIME_FORMAT(E, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_WARN ) { esp_log_write(ESP_LOG_WARN, tag, LOG_SYSTEM_TIME_FORMAT(W, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_DEBUG ) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_SYSTEM_TIME_FORMAT(D, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (level==ESP_LOG_VERBOSE ) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_SYSTEM_TIME_FORMAT(V, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else { esp_log_write(ESP_LOG_INFO, tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_ERROR) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_ERROR), tag, LOG_SYSTEM_TIME_FORMAT(E, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_WARN) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_WARN), tag, LOG_SYSTEM_TIME_FORMAT(W, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_DEBUG) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_DEBUG), tag, LOG_SYSTEM_TIME_FORMAT(D, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_VERBOSE) { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_VERBOSE), tag, LOG_SYSTEM_TIME_FORMAT(V, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
else { esp_log(ESP_LOG_CONFIG_INIT(ESP_LOG_INFO), tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
} while(0)
|
||||
#elif NON_OS_BUILD
|
||||
#define ESP_LOG_LEVEL(configs, tag, format, ...) do { \
|
||||
if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_ERROR) { ESP_EARLY_LOGE(tag, format, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_WARN) { ESP_EARLY_LOGW(tag, format, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_DEBUG) { ESP_EARLY_LOGD(tag, format, ##__VA_ARGS__); } \
|
||||
else if (ESP_LOG_GET_LEVEL(configs)==ESP_LOG_VERBOSE) { ESP_EARLY_LOGV(tag, format, ##__VA_ARGS__); } \
|
||||
else { ESP_EARLY_LOGI(tag, format, ##__VA_ARGS__); } \
|
||||
} while(0)
|
||||
#endif //CONFIG_LOG_TIMESTAMP_SOURCE_xxx
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
|
||||
/** runtime macro to output logs at a specified level. Also check the level with ``LOG_LOCAL_LEVEL``.
|
||||
* If ``CONFIG_LOG_MASTER_LEVEL`` set, also check first against ``esp_log_get_level_master()``.
|
||||
*
|
||||
* @see ``printf``, ``ESP_LOG_LEVEL``
|
||||
*/
|
||||
#define ESP_LOG_LEVEL_LOCAL(level, tag, format, ...) do { \
|
||||
if (_ESP_LOG_ENABLED(level)) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief Macro to output logs when the cache is disabled. Log at ``ESP_LOG_ERROR`` level.
|
||||
*
|
||||
* @note Unlike normal logging macros, it's possible to use this macro when interrupts are
|
||||
* disabled or inside an ISR.
|
||||
*
|
||||
* Similar to @see ``ESP_EARLY_LOGE``, the log level cannot be changed per-tag, however
|
||||
* esp_log_level_set("*", level) will set the default level which controls these log lines also.
|
||||
*
|
||||
* Usage: `ESP_DRAM_LOGE(DRAM_STR("my_tag"), "format", or `ESP_DRAM_LOGE(TAG, "format", ...)`,
|
||||
* where TAG is a char* that points to a str in the DRAM.
|
||||
*
|
||||
* @note Placing log strings in DRAM reduces available DRAM, so only use when absolutely essential.
|
||||
*
|
||||
* @see ``esp_rom_printf``,``ESP_LOGE``
|
||||
*/
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_DRAM_LOGE( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR, E __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_WARN`` level. @see ``ESP_DRAM_LOGW``,``ESP_LOGW``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGW( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN, W __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_INFO`` level. @see ``ESP_DRAM_LOGI``,``ESP_LOGI``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGI( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_INFO, I __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_DEBUG`` level. @see ``ESP_DRAM_LOGD``,``ESP_LOGD``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGD( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG, D __VA_OPT__(,) __VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_VERBOSE`` level. @see ``ESP_DRAM_LOGV``,``ESP_LOGV``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGV( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_DRAM_LOGE( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR, E, ##__VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_WARN`` level. @see ``ESP_DRAM_LOGW``,``ESP_LOGW``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGW( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN, W, ##__VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_INFO`` level. @see ``ESP_DRAM_LOGI``,``ESP_LOGI``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGI( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_INFO, I, ##__VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_DEBUG`` level. @see ``ESP_DRAM_LOGD``,``ESP_LOGD``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGD( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG, D, ##__VA_ARGS__)
|
||||
/// macro to output logs when the cache is disabled at ``ESP_LOG_VERBOSE`` level. @see ``ESP_DRAM_LOGV``,``ESP_LOGV``, ``esp_rom_printf``
|
||||
#define ESP_DRAM_LOGV( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#endif // ESP_LOG_VERSION == 1
|
||||
|
||||
/** @cond */
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_DRAM_LOG_IMPL(tag, format, log_level, log_tag_letter, ...) do { \
|
||||
if (_ESP_LOG_EARLY_ENABLED(log_level)) { \
|
||||
esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag __VA_OPT__(,) __VA_ARGS__); \
|
||||
}} while(0)
|
||||
#define ESP_LOG_EARLY_IMPL(tag, format, configs, log_tag_letter, ...) do { \
|
||||
if (ESP_LOG_VERSION == 1) { \
|
||||
if (_ESP_LOG_EARLY_ENABLED(configs)) { esp_rom_printf(LOG_FORMAT(log_tag_letter, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
} else { \
|
||||
if (ESP_LOG_ENABLED(configs)) { esp_log(ESP_LOG_CONFIG_INIT(configs | ESP_LOG_CONFIGS_DEFAULT | ESP_LOG_CONFIG_CONSTRAINED_ENV), tag, format __VA_OPT__(,) __VA_ARGS__); } \
|
||||
} } while(0)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_DRAM_LOG_IMPL(tag, format, log_level, log_tag_letter, ...) do { \
|
||||
if (_ESP_LOG_EARLY_ENABLED(log_level)) { \
|
||||
esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag, ##__VA_ARGS__); \
|
||||
}} while(0)
|
||||
#define ESP_LOG_EARLY_IMPL(tag, format, configs, log_tag_letter, ...) do { \
|
||||
if (ESP_LOG_VERSION == 1) { \
|
||||
if (_ESP_LOG_EARLY_ENABLED(configs)) { esp_rom_printf(LOG_FORMAT(log_tag_letter, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \
|
||||
} else { \
|
||||
if (ESP_LOG_ENABLED(configs)) { esp_log(ESP_LOG_CONFIG_INIT(configs | ESP_LOG_CONFIGS_DEFAULT | ESP_LOG_CONFIG_CONSTRAINED_ENV), tag, format, ##__VA_ARGS__); } \
|
||||
} } while(0)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
|
||||
#if defined(__cplusplus) && (__cplusplus > 201703L)
|
||||
#define ESP_DRAM_LOG_IMPL(tag, format, configs, log_tag_letter, ...) do { \
|
||||
if (ESP_LOG_VERSION == 1) { \
|
||||
if (_ESP_LOG_EARLY_ENABLED(configs)) { esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag __VA_OPT__(,) __VA_ARGS__); } \
|
||||
} else { \
|
||||
if (ESP_LOG_ENABLED(configs)) { esp_log(ESP_LOG_CONFIG_INIT(configs | ESP_LOG_CONFIGS_DEFAULT | ESP_LOG_CONFIG_CONSTRAINED_ENV | ESP_LOG_CONFIG_DIS_COLOR | ESP_LOG_CONFIG_DIS_TIMESTAMP), tag, DRAM_STR(format) __VA_OPT__(,) __VA_ARGS__); } \
|
||||
} } while(0)
|
||||
#else // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
#define ESP_DRAM_LOG_IMPL(tag, format, configs, log_tag_letter, ...) do { \
|
||||
if (ESP_LOG_VERSION == 1) { \
|
||||
if (_ESP_LOG_EARLY_ENABLED(configs)) { esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag, ##__VA_ARGS__); } \
|
||||
} else { \
|
||||
if (ESP_LOG_ENABLED(configs)) { esp_log(ESP_LOG_CONFIG_INIT(configs | ESP_LOG_CONFIGS_DEFAULT | ESP_LOG_CONFIG_CONSTRAINED_ENV | ESP_LOG_CONFIG_DIS_COLOR | ESP_LOG_CONFIG_DIS_TIMESTAMP), tag, DRAM_STR(format), ##__VA_ARGS__); } \
|
||||
} } while(0)
|
||||
#endif // !(defined(__cplusplus) && (__cplusplus > 201703L))
|
||||
/** @endcond */
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_log_config.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -13,6 +14,13 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond */
|
||||
// Determines whether esp_log() includes code to handle color codes.
|
||||
#if (!BOOTLOADER_BUILD && CONFIG_LOG_COLORS_SUPPORT) || (BOOTLOADER_BUILD && CONFIG_BOOTLOADER_LOG_COLORS_SUPPORT)
|
||||
#define ESP_LOG_SUPPORT_COLOR (1)
|
||||
#else
|
||||
#define ESP_LOG_SUPPORT_COLOR (0)
|
||||
#endif
|
||||
|
||||
// ANSI Color Codes:
|
||||
// Macros for defining foreground colors (text).
|
||||
#define LOG_ANSI_COLOR_BLACK "30"
|
||||
@ -77,7 +85,7 @@ extern "C" {
|
||||
* printf(LOG_ANSI_COLOR_FORMAT(LOG_ANSI_COLOR_STYLE_BOLD, LOG_ANSI_COLOR_WHITE, LOG_ANSI_COLOR_BG_BLUE) "%s" LOG_ANSI_COLOR_RESET "\n", text_str);
|
||||
*/
|
||||
|
||||
#if (!BOOTLOADER_BUILD && CONFIG_LOG_COLORS) || (BOOTLOADER_BUILD && CONFIG_BOOTLOADER_LOG_COLORS)
|
||||
#if !ESP_LOG_COLOR_DISABLED
|
||||
#define LOG_COLOR_BLACK LOG_ANSI_COLOR_BLACK
|
||||
#define LOG_COLOR_RED LOG_ANSI_COLOR_RED
|
||||
#define LOG_COLOR_GREEN LOG_ANSI_COLOR_GREEN
|
||||
|
156
components/log/include/esp_log_config.h
Normal file
156
components/log/include/esp_log_config.h
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include "esp_log_level.h"
|
||||
#include "esp_assert.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @cond */
|
||||
/// Log version macros.
|
||||
#define ESP_LOG_V2 (1)
|
||||
#if BOOTLOADER_BUILD
|
||||
#define ESP_LOG_VERSION (CONFIG_BOOTLOADER_LOG_VERSION)
|
||||
#else
|
||||
#define ESP_LOG_VERSION (CONFIG_LOG_VERSION)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This define controls the log configuration options, particularly when the built project operates in constrained environments.
|
||||
*
|
||||
* For the bootloader build:
|
||||
* It is always set to "1" because certain log features are unnecessary, reducing the binary size.
|
||||
*
|
||||
* For the application build:
|
||||
* If this define is set in the user namespace, all logs in the specific file will use a simplified path for logging.
|
||||
*
|
||||
* This define determines whether the "constrained_env" flag will be enabled in ESP_LOG_CONFIGS_DEFAULT, indicating that logging is capable of functioning
|
||||
* in constrained environments such as the bootloader, ISR, startup code, early log, or when the cache is disabled. In these cases,
|
||||
* `esp_log()` utilizes a simplified implementation to output logs.
|
||||
*/
|
||||
#if BOOTLOADER_BUILD
|
||||
#define ESP_LOG_CONSTRAINED_ENV (1)
|
||||
#else // !BOOTLOADER_BUILD
|
||||
#ifndef ESP_LOG_CONSTRAINED_ENV
|
||||
#define ESP_LOG_CONSTRAINED_ENV (0)
|
||||
#endif
|
||||
#endif // !BOOTLOADER_BUILD
|
||||
|
||||
/**
|
||||
* This define helps control log configuration options, specifically whether color output will be appended to log messages.
|
||||
* If this define is not set in the user namespace, its value will be determined by Kconfig options.
|
||||
* If the define is set in the user namespace, it will override the default configurations (ESP_LOG_CONFIGS_DEFAULT) for the user's specific file.
|
||||
* This define controls the "dis_color" flag, which is included in ESP_LOG_CONFIGS_DEFAULT
|
||||
*/
|
||||
#ifndef ESP_LOG_COLOR_DISABLED
|
||||
#if (!BOOTLOADER_BUILD && CONFIG_LOG_COLORS) || (BOOTLOADER_BUILD && CONFIG_BOOTLOADER_LOG_COLORS)
|
||||
#define ESP_LOG_COLOR_DISABLED (0)
|
||||
#else
|
||||
#define ESP_LOG_COLOR_DISABLED (1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This define helps control log configuration options, specifically whether timestamp will be appended to log message.
|
||||
* If this define is not set in the user namespace, its value will be determined by Kconfig options.
|
||||
* If the define is set in the user namespace, it will override the default configurations (ESP_LOG_CONFIGS_DEFAULT) for the user's specific file.
|
||||
* This define controls the "dis_timestamp" flag, which is included in ESP_LOG_CONFIGS_DEFAULT
|
||||
*/
|
||||
#ifndef ESP_LOG_TIMESTAMP_DISABLED
|
||||
#if (!BOOTLOADER_BUILD && CONFIG_LOG_TIMESTAMP_SOURCE_NONE) || (BOOTLOADER_BUILD && CONFIG_BOOTLOADER_LOG_TIMESTAMP_SOURCE_NONE)
|
||||
#define ESP_LOG_TIMESTAMP_DISABLED (1)
|
||||
#else
|
||||
#define ESP_LOG_TIMESTAMP_DISABLED (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This define helps control log configuration options, specifically whether formatting (ex.: color, timestamp) will be appended to log message.
|
||||
* If the define is set in the user namespace, it will override the default configurations (ESP_LOG_CONFIGS_DEFAULT) for the user's specific file.
|
||||
* This define controls the "require_formatting" flag, which is included in ESP_LOG_CONFIGS_DEFAULT
|
||||
*/
|
||||
#ifndef ESP_LOG_FORMATTING_DISABLED
|
||||
#define ESP_LOG_FORMATTING_DISABLED (0)
|
||||
#endif
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Logging configuration structure for ESP log.
|
||||
*/
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
esp_log_level_t log_level: ESP_LOG_LEVEL_LEN; /*!< Log level */
|
||||
uint32_t constrained_env: 1; /*!< Flag indicating if logging is from a constrained environment (e.g., bootloader, ISR, startup code, early log, or when the cache is disabled). In such cases, esp_rom_vprintf is used instead of the vprintf. */
|
||||
uint32_t require_formatting: 1; /*!< Flag specifying whether the log message needs additional formatting. If set, esp_log() will add formatting elements like color, timestamp, and tag to the log message. */
|
||||
uint32_t dis_color: 1; /*!< Flag to disable color in log output. If set, log messages will not include color codes. */
|
||||
uint32_t dis_timestamp: 1; /*!< Flag to disable timestamps in log output. If set, log messages will not include timestamps. */
|
||||
uint32_t reserved: 25; /*!< Reserved for future use. Should be initialized to 0. */
|
||||
} opts;
|
||||
uint32_t data; /*!< Raw data representing all options in a 32-bit word. */
|
||||
};
|
||||
} esp_log_config_t;
|
||||
|
||||
/** @cond */
|
||||
#define ESP_LOG_OFFSET_CONSTRAINED_ENV (ESP_LOG_LEVEL_LEN) /*!< Offset for constrained_env field from esp_log_config_t */
|
||||
#define ESP_LOG_OFFSET_REQUIRE_FORMATTING (4) /*!< Offset for require_formatting field from esp_log_config_t */
|
||||
#define ESP_LOG_OFFSET_DIS_COLOR_OFFSET (5) /*!< Offset for dis_color field from esp_log_config_t */
|
||||
#define ESP_LOG_OFFSET_DIS_TIMESTAMP (6) /*!< Offset for dis_timestamp field from esp_log_config_t */
|
||||
|
||||
ESP_STATIC_ASSERT(ESP_LOG_OFFSET_CONSTRAINED_ENV == ESP_LOG_LEVEL_LEN, "The log level should not overlap the following fields in esp_log_config_t");
|
||||
/** @endcond */
|
||||
|
||||
#define ESP_LOG_CONFIG_LEVEL_MASK ((1 << ESP_LOG_LEVEL_LEN) - 1) /*!< Mask for level field in esp_log_config_t */
|
||||
#define ESP_LOG_CONFIG_CONSTRAINED_ENV (1 << ESP_LOG_OFFSET_CONSTRAINED_ENV) /*!< Value for constrained_env field in esp_log_config_t */
|
||||
#define ESP_LOG_CONFIG_REQUIRE_FORMATTING (1 << ESP_LOG_OFFSET_REQUIRE_FORMATTING) /*!< Value for require_formatting field in esp_log_config_t */
|
||||
#define ESP_LOG_CONFIG_DIS_COLOR (1 << ESP_LOG_OFFSET_DIS_COLOR_OFFSET) /*!< Value for dis_color field in esp_log_config_t */
|
||||
#define ESP_LOG_CONFIG_DIS_TIMESTAMP (1 << ESP_LOG_OFFSET_DIS_TIMESTAMP) /*!< Value for dis_timestamp field in esp_log_config_t */
|
||||
|
||||
/**
|
||||
* @brief Macro for setting log configurations according to selected Kconfig options.
|
||||
*
|
||||
* @note The `require_formatting` flag is always set for logv2.
|
||||
*/
|
||||
#ifndef ESP_LOG_CONFIGS_DEFAULT
|
||||
#define ESP_LOG_CONFIGS_DEFAULT ( \
|
||||
((ESP_LOG_CONSTRAINED_ENV) ? (ESP_LOG_CONFIG_CONSTRAINED_ENV) : 0) \
|
||||
| ((ESP_LOG_FORMATTING_DISABLED) ? (0) : (ESP_LOG_CONFIG_REQUIRE_FORMATTING)) \
|
||||
| ((ESP_LOG_COLOR_DISABLED) ? (ESP_LOG_CONFIG_DIS_COLOR) : 0) \
|
||||
| ((ESP_LOG_TIMESTAMP_DISABLED) ? (ESP_LOG_CONFIG_DIS_TIMESTAMP) : 0))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Macro to initialize an `esp_log_config_t` structure.
|
||||
*
|
||||
* This macro directly initializes an `esp_log_config_t` structure by setting the raw `data` field
|
||||
* with the provided `configs` parameter. It is useful when you have already defined the configuration
|
||||
* settings and wish to apply them directly.
|
||||
*
|
||||
* @param configs The raw configuration data to initialize the `esp_log_config_t` structure.
|
||||
*
|
||||
* @return An initialized `esp_log_config_t` structure containing the specified configuration data.
|
||||
*/
|
||||
#if defined(__cplusplus)
|
||||
#define ESP_LOG_CONFIG_INIT(configs) (__extension__({ \
|
||||
esp_log_config_t __esp_log_config; \
|
||||
__esp_log_config.data = (configs); \
|
||||
__esp_log_config;}))
|
||||
#else
|
||||
#define ESP_LOG_CONFIG_INIT(configs) ((esp_log_config_t){.data = (configs)})
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -29,11 +29,25 @@ typedef enum {
|
||||
|
||||
#define ESP_LOG_LEVEL_LEN (3) /*!< Number of bits used to represent the log level */
|
||||
#define ESP_LOG_LEVEL_MASK ((1 << ESP_LOG_LEVEL_LEN) - 1) /*!< Mask for log level */
|
||||
/// Returns level from config
|
||||
#define ESP_LOG_GET_LEVEL(config) ((config) & ESP_LOG_LEVEL_MASK)
|
||||
|
||||
/** @cond */
|
||||
ESP_STATIC_ASSERT(ESP_LOG_MAX <= ESP_LOG_LEVEL_MASK, "Log level items of esp_log_level_t must fit ESP_LOG_LEVEL_MASK");
|
||||
|
||||
// LOG_LOCAL_LEVEL controls what log levels are included in the binary.
|
||||
/**
|
||||
* @brief Controls the log levels included in the binary.
|
||||
*
|
||||
* This define determines the maximum log level that will be compiled into the binary for the current build configuration.
|
||||
* It adjusts the verbosity of logging by specifying which log levels are included or excluded.
|
||||
*
|
||||
* If this define is not explicitly set in the user namespace, its value is derived from Kconfig options:
|
||||
* - `CONFIG_BOOTLOADER_LOG_LEVEL` for bootloader builds.
|
||||
* - `CONFIG_SECURE_TEE_LOG_LEVEL` for Secure TEE builds.
|
||||
* - `CONFIG_LOG_MAXIMUM_LEVEL` for all other builds.
|
||||
*
|
||||
* If explicitly defined in the user's code, it overrides these default values, allowing fine-grained control over log verbosity.
|
||||
*/
|
||||
#ifndef LOG_LOCAL_LEVEL
|
||||
#if BOOTLOADER_BUILD
|
||||
#define LOG_LOCAL_LEVEL CONFIG_BOOTLOADER_LOG_LEVEL
|
||||
@ -43,6 +57,7 @@ ESP_STATIC_ASSERT(ESP_LOG_MAX <= ESP_LOG_LEVEL_MASK, "Log level items of esp_log
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_MAXIMUM_LEVEL
|
||||
#endif
|
||||
#endif // LOG_LOCAL_LEVEL
|
||||
/** @endcond */
|
||||
|
||||
/**
|
||||
* @brief Check if a specific log level is enabled at compile-time.
|
||||
@ -52,27 +67,28 @@ ESP_STATIC_ASSERT(ESP_LOG_MAX <= ESP_LOG_LEVEL_MASK, "Log level items of esp_log
|
||||
* determine if logging for the specified level should be included in the binary,
|
||||
* helping to exclude logs that are not configured.
|
||||
*
|
||||
* @param level log level.
|
||||
* @param configs it includes log configs and level.
|
||||
* @return true if the specified log level is enabled, false otherwise.
|
||||
*/
|
||||
#define ESP_LOG_ENABLED(level) (LOG_LOCAL_LEVEL >= (level))
|
||||
#define ESP_LOG_ENABLED(configs) (LOG_LOCAL_LEVEL >= ESP_LOG_GET_LEVEL(configs))
|
||||
|
||||
/** @cond */
|
||||
#if NON_OS_BUILD
|
||||
|
||||
#define _ESP_LOG_ENABLED(log_level) (LOG_LOCAL_LEVEL >= (log_level))
|
||||
#define _ESP_LOG_EARLY_ENABLED(log_level) _ESP_LOG_ENABLED(log_level)
|
||||
#define _ESP_LOG_ENABLED(log_level) ESP_LOG_ENABLED(log_level)
|
||||
#define _ESP_LOG_EARLY_ENABLED(log_level) ESP_LOG_ENABLED(log_level)
|
||||
|
||||
#else // !NON_OS_BUILD
|
||||
|
||||
#if CONFIG_LOG_MASTER_LEVEL
|
||||
#define _ESP_LOG_ENABLED(log_level) (esp_log_get_level_master() >= (log_level) && LOG_LOCAL_LEVEL >= (log_level))
|
||||
#define _ESP_LOG_ENABLED(log_level) (esp_log_get_level_master() >= ESP_LOG_GET_LEVEL(log_level) && ESP_LOG_ENABLED(log_level))
|
||||
#else // !CONFIG_LOG_MASTER_LEVEL
|
||||
#define _ESP_LOG_ENABLED(log_level) (LOG_LOCAL_LEVEL >= (log_level))
|
||||
#define _ESP_LOG_ENABLED(log_level) ESP_LOG_ENABLED(log_level)
|
||||
#endif // !CONFIG_LOG_MASTER_LEVEL
|
||||
|
||||
/* For early log, there is no log tag filtering. So we want to log only if both the LOG_LOCAL_LEVEL and the
|
||||
currently configured min log level are higher than the log level */
|
||||
#define _ESP_LOG_EARLY_ENABLED(log_level) (LOG_LOCAL_LEVEL >= (log_level) && esp_log_get_default_level() >= (log_level))
|
||||
#define _ESP_LOG_EARLY_ENABLED(log_level) (ESP_LOG_ENABLED(log_level) && esp_log_get_default_level() >= ESP_LOG_GET_LEVEL(log_level))
|
||||
|
||||
#endif // !NON_OS_BUILD
|
||||
|
||||
@ -91,7 +107,11 @@ currently configured min log level are higher than the log level */
|
||||
__attribute__((always_inline))
|
||||
static inline esp_log_level_t esp_log_get_default_level(void)
|
||||
{
|
||||
#if CONFIG_LOG_DYNAMIC_LEVEL_CONTROL
|
||||
#if BOOTLOADER_BUILD
|
||||
return (esp_log_level_t) CONFIG_BOOTLOADER_LOG_LEVEL;
|
||||
#elif ESP_TEE_BUILD
|
||||
return (esp_log_level_t) CONFIG_SECURE_TEE_LOG_LEVEL;
|
||||
#elif CONFIG_LOG_DYNAMIC_LEVEL_CONTROL
|
||||
extern esp_log_level_t esp_log_default_level;
|
||||
return esp_log_default_level;
|
||||
#else
|
||||
@ -104,14 +124,13 @@ static inline esp_log_level_t esp_log_get_default_level(void)
|
||||
/**
|
||||
* @brief Master log level.
|
||||
*
|
||||
* Optional master log level to check against for ESP_LOGx macros before calling
|
||||
* esp_log_write. Allows one to set a higher CONFIG_LOG_MAXIMUM_LEVEL but not
|
||||
* Allows one to set a higher CONFIG_LOG_MAXIMUM_LEVEL but not
|
||||
* impose a performance hit during normal operation (only when instructed). An
|
||||
* application may set esp_log_set_level_master(level) to globally enforce a
|
||||
* maximum log level. ESP_LOGx macros above this level will be skipped immediately,
|
||||
* rather than calling esp_log or esp_log_write and doing a cache hit.
|
||||
* maximum log level. ESP_LOG macros above this level will be skipped,
|
||||
* rather than doing a tag lookup.
|
||||
*
|
||||
* @note The tradeoff is increased application size.
|
||||
* The Master log level is not applicable for the bootloader.
|
||||
*
|
||||
* @param level Master log level
|
||||
*/
|
||||
@ -119,6 +138,7 @@ void esp_log_set_level_master(esp_log_level_t level);
|
||||
|
||||
/**
|
||||
* @brief Returns master log level.
|
||||
* The Master log level is not applicable for the bootloader.
|
||||
* @return Master log level
|
||||
*/
|
||||
esp_log_level_t esp_log_get_level_master(void);
|
||||
|
@ -12,6 +12,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Checks if a log message with the given log level and tag should be logged.
|
||||
*
|
||||
* @param level The log level of the message.
|
||||
* @param tag The tag associated with the message.
|
||||
* @return true if the log message can be logged,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool esp_log_is_tag_loggable(esp_log_level_t level, const char *tag);
|
||||
|
||||
/**
|
||||
* @brief Set the default log level.
|
||||
*
|
||||
|
60
components/log/include/esp_private/log_print.h
Normal file
60
components/log/include/esp_private/log_print.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include "esp_log_config.h"
|
||||
#include "esp_log_write.h"
|
||||
#include "esp_rom_sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Outputs a formatted log message.
|
||||
*
|
||||
* @note It internally calls a vprintf function that was set by esp_log_set_vprintf().
|
||||
* @see esp_log_set_vprintf
|
||||
*
|
||||
* @param config The config log
|
||||
* @param format The format string for the log message.
|
||||
* @param args The variable argument list containing the values to be formatted.
|
||||
*/
|
||||
__attribute__((always_inline)) static inline void esp_log_vprintf(esp_log_config_t config, const char *format, va_list args)
|
||||
{
|
||||
#if BOOTLOADER_BUILD
|
||||
esp_rom_vprintf(format, args);
|
||||
#else // APP
|
||||
extern vprintf_like_t esp_log_vprint_func;
|
||||
#if ESP_LOG_VERSION == 2
|
||||
vprintf_like_t vprint_func[2] = {
|
||||
esp_log_vprint_func,
|
||||
esp_rom_vprintf,
|
||||
};
|
||||
vprint_func[config.opts.constrained_env](format, args);
|
||||
#else // ESP_LOG_VERSION == 1
|
||||
esp_log_vprint_func(format, args);
|
||||
#endif // ESP_LOG_VERSION == 1
|
||||
#endif // APP
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Outputs a formatted log message.
|
||||
*
|
||||
* @note It internally calls esp_log_vprintf().
|
||||
* @see esp_log_vprintf
|
||||
*
|
||||
* @param config The config log
|
||||
* @param format The format string for the log message.
|
||||
* @param ... Optional arguments to be formatted according to the format string.
|
||||
*/
|
||||
void esp_log_printf(esp_log_config_t config, const char *format, ...) __attribute__((format(printf, 2, 3)));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -6,6 +6,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -64,6 +66,45 @@ int esp_log_util_cvt_hex(unsigned long long val, int pad, char *buf);
|
||||
*/
|
||||
int esp_log_util_cvt_dec(unsigned long long val, int pad, char *buf);
|
||||
|
||||
/**
|
||||
* @typedef esp_log_cache_enabled_t
|
||||
* @brief Callback function type for checking the state of the SPI flash cache.
|
||||
*
|
||||
* This function pointer is used to determine whether the SPI flash cache is enabled
|
||||
* during logging operations.
|
||||
*
|
||||
* @return
|
||||
* - true if the SPI flash cache is enabled.
|
||||
* - false if the SPI flash cache is disabled.
|
||||
*/
|
||||
typedef bool (*esp_log_cache_enabled_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Sets the callback function to check the SPI flash cache state.
|
||||
*
|
||||
* This function allows setting a custom callback to check whether the SPI flash
|
||||
* cache is enabled. If a callback is provided, it will be used during logging
|
||||
* operations to ensure that logging does not interfere with cache-disabled scenarios.
|
||||
*
|
||||
* @note This function must be called during system startup to initialize it.
|
||||
*
|
||||
* @param[in] func Pointer to the callback function of type `esp_log_cache_enabled_t`.
|
||||
* Pass `NULL` to disable the cache check.
|
||||
*/
|
||||
void esp_log_util_set_cache_enabled_cb(esp_log_cache_enabled_t func);
|
||||
|
||||
/**
|
||||
* @brief Check if the current context is constrained.
|
||||
*
|
||||
* This function checks if logging in the current context is doing from:
|
||||
* - ISR context.
|
||||
* - Disabled SPI flash cache.
|
||||
* - Task scheduler not running.
|
||||
*
|
||||
* @return true if the context is constrained, false otherwise.
|
||||
*/
|
||||
bool esp_log_util_is_constrained(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -7,3 +7,9 @@ entries:
|
||||
log_timestamp:esp_log_timestamp (noflash)
|
||||
log_timestamp:esp_log_early_timestamp (noflash)
|
||||
log_lock (noflash)
|
||||
util (noflash)
|
||||
log_timestamp_common (noflash)
|
||||
log_print (noflash)
|
||||
log (noflash)
|
||||
if LOG_MASTER_LEVEL = y:
|
||||
log_level: esp_log_get_level_master (noflash)
|
||||
|
12
components/log/src/linux/util.c
Normal file
12
components/log/src/linux/util.c
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool esp_log_util_is_constrained(void)
|
||||
{
|
||||
return false;
|
||||
}
|
123
components/log/src/log.c
Normal file
123
components/log/src/log.c
Normal file
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "esp_log_config.h"
|
||||
#include "esp_log_level.h"
|
||||
#include "esp_log_color.h"
|
||||
#include "esp_log_timestamp.h"
|
||||
#include "esp_private/log_level.h"
|
||||
#include "esp_private/log_timestamp.h"
|
||||
#include "esp_private/log_lock.h"
|
||||
#include "esp_private/log_util.h"
|
||||
#include "esp_private/log_print.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static __attribute__((unused)) const char s_lvl_name[ESP_LOG_MAX] = {
|
||||
'\0', // NONE
|
||||
'E', // ERROR
|
||||
'W', // WARNING
|
||||
'I', // INFO
|
||||
'D', // DEBUG
|
||||
'V', // VERBOSE
|
||||
};
|
||||
|
||||
static __attribute__((unused)) const char s_lvl_color[ESP_LOG_MAX][8] = {
|
||||
"\0", // NONE
|
||||
LOG_ANSI_COLOR_REGULAR(LOG_ANSI_COLOR_RED)"\0", // ERROR
|
||||
LOG_ANSI_COLOR_REGULAR(LOG_ANSI_COLOR_YELLOW)"\0", // WARNING
|
||||
LOG_ANSI_COLOR_REGULAR(LOG_ANSI_COLOR_GREEN)"\0", // INFO
|
||||
"\0", // DEBUG
|
||||
"\0", // VERBOSE
|
||||
};
|
||||
|
||||
static __attribute__((unused)) bool is_level_loggable(esp_log_config_t config)
|
||||
{
|
||||
#if BOOTLOADER_BUILD
|
||||
return (config.opts.log_level != ESP_LOG_NONE) && (esp_log_get_default_level() >= config.opts.log_level);
|
||||
#else
|
||||
return (config.opts.log_level != ESP_LOG_NONE)
|
||||
#if CONFIG_LOG_MASTER_LEVEL
|
||||
&& (esp_log_get_level_master() >= config.opts.log_level)
|
||||
#endif // CONFIG_LOG_MASTER_LEVEL
|
||||
&& ((config.opts.constrained_env) ? (esp_log_get_default_level() >= config.opts.log_level) : true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void __attribute__((optimize("-O3"))) esp_log_va(esp_log_config_t config, const char *tag, const char *format, va_list args)
|
||||
{
|
||||
#if ESP_LOG_VERSION == 1
|
||||
if (config.opts.log_level != ESP_LOG_NONE && esp_log_is_tag_loggable(config.opts.log_level, tag)) {
|
||||
extern vprintf_like_t esp_log_vprint_func;
|
||||
esp_log_vprint_func(format, args);
|
||||
}
|
||||
#else // ESP_LOG_VERSION == 2
|
||||
if (is_level_loggable(config)) {
|
||||
__attribute__((unused)) uint64_t timestamp = 0;
|
||||
config.opts.dis_timestamp |= !ESP_LOG_SUPPORT_TIMESTAMP;
|
||||
config.opts.constrained_env = ESP_LOG_CONSTRAINED_ENV || config.opts.constrained_env || esp_log_util_is_constrained();
|
||||
if (!config.opts.dis_timestamp && ((!ESP_LOG_CONSTRAINED_ENV && config.opts.require_formatting) || ESP_LOG_CONSTRAINED_ENV)) {
|
||||
timestamp = esp_log_timestamp64(config.opts.constrained_env);
|
||||
}
|
||||
#if !ESP_LOG_CONSTRAINED_ENV
|
||||
if (!config.opts.constrained_env && tag != NULL && !esp_log_is_tag_loggable(config.opts.log_level, tag)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// formatting log
|
||||
if (config.opts.require_formatting) { // 1. print "<color_start><level_name> <(time)> <tag>: "
|
||||
#if !ESP_LOG_CONSTRAINED_ENV
|
||||
if (!config.opts.constrained_env) {
|
||||
// flockfile&funlockfile are used here to prevent other threads
|
||||
// from writing to the same stream simultaneously using printf-like functions.
|
||||
// Below is formatting log, there are multiple calls to vprintf to log a single message.
|
||||
flockfile(stdout);
|
||||
}
|
||||
#endif
|
||||
config.opts.dis_color = !ESP_LOG_SUPPORT_COLOR || config.opts.dis_color || (s_lvl_color[config.opts.log_level][0] == '\0');
|
||||
char timestamp_buffer[32] = { 0 };
|
||||
if (!config.opts.dis_timestamp) {
|
||||
esp_log_timestamp_str(config.opts.constrained_env, timestamp, timestamp_buffer);
|
||||
}
|
||||
esp_log_printf(config, "%s%c %s%s%s%s%s",
|
||||
(!config.opts.dis_color) ? s_lvl_color[config.opts.log_level] : "",
|
||||
s_lvl_name[config.opts.log_level],
|
||||
(!config.opts.dis_timestamp) ? "(" : "",
|
||||
timestamp_buffer,
|
||||
(!config.opts.dis_timestamp) ? ") " : "",
|
||||
(tag) ? tag : "",
|
||||
(tag) ? ": " : "");
|
||||
}
|
||||
|
||||
esp_log_vprintf(config, format, args); // 2. print user message
|
||||
|
||||
if (config.opts.require_formatting) { // 3. print "<color_end><\n>"
|
||||
esp_log_printf(config, "%s", (config.opts.dis_color) ? "\n" : LOG_RESET_COLOR"\n");
|
||||
#if !ESP_LOG_CONSTRAINED_ENV
|
||||
if (!config.opts.constrained_env) {
|
||||
funlockfile(stdout);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // ESP_LOG_VERSION == 2
|
||||
}
|
||||
|
||||
void __attribute__((optimize("-O3"))) esp_log(esp_log_config_t config, const char* tag, const char* format, ...)
|
||||
{
|
||||
#if ESP_LOG_VERSION == 1
|
||||
if (1) {
|
||||
#else // ESP_LOG_VERSION == 2
|
||||
if (is_level_loggable(config)) {
|
||||
#endif
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
esp_log_va(config, tag, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "esp_log_level.h"
|
||||
#include "esp_private/log_level.h"
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@ -38,3 +38,18 @@ void esp_log_set_level_master(esp_log_level_t level)
|
||||
s_master_log_level = level;
|
||||
}
|
||||
#endif // CONFIG_LOG_MASTER_LEVEL
|
||||
|
||||
bool esp_log_is_tag_loggable(esp_log_level_t level, const char *tag)
|
||||
{
|
||||
#if CONFIG_LOG_TAG_LEVEL_IMPL_NONE
|
||||
(void)tag;
|
||||
#if CONFIG_LOG_DYNAMIC_LEVEL_CONTROL
|
||||
return (esp_log_default_level >= level);
|
||||
#else
|
||||
(void)level;
|
||||
return true;
|
||||
#endif
|
||||
#else // !CONFIG_LOG_TAG_LEVEL_IMPL_NONE
|
||||
return esp_log_level_get_timeout(tag) >= level && level > ESP_LOG_NONE;
|
||||
#endif // !CONFIG_LOG_TAG_LEVEL_IMPL_NONE
|
||||
}
|
||||
|
19
components/log/src/log_print.c
Normal file
19
components/log/src/log_print.c
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "esp_private/log_print.h"
|
||||
#include "esp_log_config.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
void esp_log_printf(esp_log_config_t config, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
esp_log_vprintf(config, format, args);
|
||||
va_end(args);
|
||||
}
|
12
components/log/src/noos/util.c
Normal file
12
components/log/src/noos/util.c
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool esp_log_util_is_constrained(void)
|
||||
{
|
||||
return true;
|
||||
}
|
@ -10,18 +10,19 @@
|
||||
#include <stdio.h>
|
||||
#include "esp_log_write.h"
|
||||
#include "esp_private/log_lock.h"
|
||||
#include "esp_private/log_level.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_log_level.h"
|
||||
#include "esp_log_config.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static vprintf_like_t s_log_print_func = &vprintf;
|
||||
vprintf_like_t esp_log_vprint_func = &vprintf;
|
||||
|
||||
vprintf_like_t esp_log_set_vprintf(vprintf_like_t func)
|
||||
{
|
||||
esp_log_impl_lock();
|
||||
vprintf_like_t orig_func = s_log_print_func;
|
||||
s_log_print_func = func;
|
||||
esp_log_impl_unlock();
|
||||
return orig_func;
|
||||
/* This builtin, as described by Intel, is not a traditional
|
||||
* test-and-set operation, but rather an atomic exchange operation. It
|
||||
* writes value into *ptr, and returns the previous contents of *ptr.
|
||||
*/
|
||||
return __atomic_exchange_n(&esp_log_vprint_func, func, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
void esp_log_writev(esp_log_level_t level,
|
||||
@ -29,10 +30,7 @@ void esp_log_writev(esp_log_level_t level,
|
||||
const char *format,
|
||||
va_list args)
|
||||
{
|
||||
esp_log_level_t level_for_tag = esp_log_level_get_timeout(tag);
|
||||
if (ESP_LOG_NONE != level_for_tag && level <= level_for_tag) {
|
||||
(*s_log_print_func)(format, args);
|
||||
}
|
||||
esp_log_va(ESP_LOG_CONFIG_INIT(level), tag, format, args);
|
||||
}
|
||||
|
||||
void esp_log_write(esp_log_level_t level,
|
||||
@ -41,6 +39,6 @@ void esp_log_write(esp_log_level_t level,
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
esp_log_writev(level, tag, format, list);
|
||||
esp_log_va(ESP_LOG_CONFIG_INIT(level), tag, format, list);
|
||||
va_end(list);
|
||||
}
|
||||
|
27
components/log/src/os/util.c
Normal file
27
components/log/src/os/util.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_private/log_util.h"
|
||||
#include "esp_compiler.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
static esp_log_cache_enabled_t esp_log_cache_enabled = NULL;
|
||||
|
||||
void esp_log_util_set_cache_enabled_cb(esp_log_cache_enabled_t func)
|
||||
{
|
||||
esp_log_cache_enabled = func;
|
||||
}
|
||||
|
||||
bool esp_log_util_is_constrained(void)
|
||||
{
|
||||
return (xPortInIsrContext()
|
||||
#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP
|
||||
|| ((esp_log_cache_enabled) ? !esp_log_cache_enabled() : false)
|
||||
#endif
|
||||
|| unlikely(xTaskGetSchedulerState() != taskSCHEDULER_RUNNING));
|
||||
}
|
@ -48,7 +48,12 @@ TEST_CASE("test master logging level performance", "[log]")
|
||||
|
||||
#ifdef CONFIG_LOG_MASTER_LEVEL
|
||||
esp_log_set_level_master(ESP_LOG_NONE);
|
||||
TEST_ASSERT_INT_WITHIN(100, 150, calc_time_of_logging(ITERATIONS));
|
||||
#if ESP_LOG_VERSION == 1
|
||||
const int typical_value = 150;
|
||||
#else // ESP_LOG_VERSION == 2
|
||||
const int typical_value = 250;
|
||||
#endif // ESP_LOG_VERSION == 2
|
||||
TEST_ASSERT_INT_WITHIN(100, typical_value, calc_time_of_logging(ITERATIONS));
|
||||
#else
|
||||
esp_log_level_set("*", ESP_LOG_NONE);
|
||||
TEST_ASSERT_INT_WITHIN(DELTA_US, EXPECTED_US, calc_time_of_logging(ITERATIONS) / ITERATIONS);
|
||||
|
@ -55,8 +55,7 @@ void putc_to_buffer(char c)
|
||||
|
||||
static int print_to_buffer(const char *format, va_list args)
|
||||
{
|
||||
int ret = vsnprintf(s_print_buffer, BUFFER_SIZE, format, args);
|
||||
printf(s_print_buffer);
|
||||
int ret = vsnprintf(&s_print_buffer[s_counter], BUFFER_SIZE, format, args);
|
||||
s_counter += ret;
|
||||
assert(s_counter < BUFFER_SIZE);
|
||||
return ret;
|
||||
|
360
components/log/test_apps/main/test_log_perf.c
Normal file
360
components/log/test_apps/main/test_log_perf.c
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
#include "sys/param.h"
|
||||
#include "unity.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_rom_uart.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
typedef struct {
|
||||
SemaphoreHandle_t done;
|
||||
int stack_usage;
|
||||
int (*func)(void);
|
||||
} perf_log_test_t;
|
||||
|
||||
static const char * TAG = "test";
|
||||
|
||||
const int max_loops = 5;
|
||||
|
||||
static void print_via_vprintf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vprintf(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static void print_via_esp_rom_vprintf(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
esp_rom_vprintf(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static int test_stack_usage_esp_rom_printf(void)
|
||||
{
|
||||
UBaseType_t start, end;
|
||||
start = uxTaskGetStackHighWaterMark(NULL);
|
||||
esp_rom_printf("test msg with value %d\n", 1);
|
||||
end = uxTaskGetStackHighWaterMark(NULL);
|
||||
return start - end;
|
||||
}
|
||||
|
||||
static int test_stack_usage_esp_rom_vprintf(void)
|
||||
{
|
||||
UBaseType_t start, end;
|
||||
start = uxTaskGetStackHighWaterMark(NULL);
|
||||
print_via_esp_rom_vprintf("test msg with value %d\n", 2);
|
||||
end = uxTaskGetStackHighWaterMark(NULL);
|
||||
return start - end;
|
||||
}
|
||||
|
||||
static int test_stack_usage_early_log(void)
|
||||
{
|
||||
UBaseType_t start, end;
|
||||
start = uxTaskGetStackHighWaterMark(NULL);
|
||||
ESP_EARLY_LOGI(TAG, "test msg with value %d", 3);
|
||||
end = uxTaskGetStackHighWaterMark(NULL);
|
||||
return start - end;
|
||||
}
|
||||
|
||||
static int test_stack_usage_dram_log(void)
|
||||
{
|
||||
UBaseType_t start, end;
|
||||
start = uxTaskGetStackHighWaterMark(NULL);
|
||||
ESP_DRAM_LOGI(TAG, "test msg with value %d", 4);
|
||||
end = uxTaskGetStackHighWaterMark(NULL);
|
||||
return start - end;
|
||||
}
|
||||
|
||||
static int test_stack_usage_printf(void)
|
||||
{
|
||||
UBaseType_t start, end;
|
||||
start = uxTaskGetStackHighWaterMark(NULL);
|
||||
printf("test msg with value %d\n", 5);
|
||||
end = uxTaskGetStackHighWaterMark(NULL);
|
||||
return start - end;
|
||||
}
|
||||
|
||||
static int test_stack_usage_vprintf(void)
|
||||
{
|
||||
UBaseType_t start, end;
|
||||
start = uxTaskGetStackHighWaterMark(NULL);
|
||||
print_via_vprintf("test msg with value %d\n", 6);
|
||||
end = uxTaskGetStackHighWaterMark(NULL);
|
||||
return start - end;
|
||||
}
|
||||
|
||||
static int test_stack_usage_esp_log(void)
|
||||
{
|
||||
UBaseType_t start, end;
|
||||
start = uxTaskGetStackHighWaterMark(NULL);
|
||||
ESP_LOGI(TAG, "test msg with value %d", 7);
|
||||
end = uxTaskGetStackHighWaterMark(NULL);
|
||||
return start - end;
|
||||
}
|
||||
|
||||
static void log_stack_usage_task(void* arg)
|
||||
{
|
||||
perf_log_test_t *a = (perf_log_test_t *) arg;
|
||||
|
||||
const uint32_t mask = esp_cpu_intr_get_enabled_mask();
|
||||
esp_cpu_intr_disable(0xFFFFFFFF);
|
||||
a->stack_usage = a->func();
|
||||
esp_cpu_intr_enable(mask);
|
||||
|
||||
TEST_ASSERT(xSemaphoreGive(a->done));
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("Stack usage for log APIs", "[log]")
|
||||
{
|
||||
int priority = uxTaskPriorityGet(NULL) + 1;
|
||||
perf_log_test_t args = {
|
||||
.done = xSemaphoreCreateBinary(),
|
||||
.stack_usage = 0,
|
||||
.func = NULL,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int (*func)(void);
|
||||
int stack_usages;
|
||||
} log_test_case_t;
|
||||
|
||||
log_test_case_t test_cases[] = {
|
||||
{"esp_rom_printf", test_stack_usage_esp_rom_printf, 0},
|
||||
{"esp_rom_vprintf", test_stack_usage_esp_rom_vprintf, 0},
|
||||
{"early_log", test_stack_usage_early_log, 0},
|
||||
{"dram_log", test_stack_usage_dram_log, 0},
|
||||
{"printf", test_stack_usage_printf, 0},
|
||||
{"vprintf", test_stack_usage_vprintf, 0},
|
||||
{"esp_log", test_stack_usage_esp_log, 0},
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
|
||||
args.func = test_cases[i].func;
|
||||
TEST_ASSERT(xTaskCreatePinnedToCore(log_stack_usage_task, test_cases[i].name, 4095, &args, priority, NULL, 0));
|
||||
TEST_ASSERT(xSemaphoreTake(args.done, 100 / portTICK_PERIOD_MS));
|
||||
test_cases[i].stack_usages = args.stack_usage;
|
||||
}
|
||||
|
||||
printf("\nStack usage for %s chip:\n", CONFIG_IDF_TARGET);
|
||||
for (int i = 0; i < sizeof(test_cases) / sizeof(test_cases[0]); i++) {
|
||||
printf("%-20s %d bytes\n", test_cases[i].name, test_cases[i].stack_usages);
|
||||
}
|
||||
|
||||
vSemaphoreDelete(args.done);
|
||||
}
|
||||
|
||||
static void mock_putc(char c)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int mock_vprintf(const char *format, va_list args)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int measuring_execution_time_esp_rom_printf(bool without_output)
|
||||
{
|
||||
int diff;
|
||||
int64_t start, end;
|
||||
diff = INT32_MAX;
|
||||
for (int i = 0; i < max_loops; i++) {
|
||||
start = esp_timer_get_time();
|
||||
if (without_output) {
|
||||
esp_rom_printf("\r");
|
||||
} else {
|
||||
esp_rom_printf("test msg %d\n", i);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
diff = MIN(diff, end - start);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int measuring_execution_time_esp_rom_vprintf(bool without_output)
|
||||
{
|
||||
int diff;
|
||||
int64_t start, end;
|
||||
diff = INT32_MAX;
|
||||
for (int i = 0; i < max_loops; i++) {
|
||||
start = esp_timer_get_time();
|
||||
if (without_output) {
|
||||
print_via_esp_rom_vprintf("\r");
|
||||
} else {
|
||||
print_via_esp_rom_vprintf("test msg %d\n", i);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
diff = MIN(diff, end - start);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int measuring_execution_time_early_log(bool without_output)
|
||||
{
|
||||
int diff;
|
||||
int64_t start, end;
|
||||
diff = INT32_MAX;
|
||||
if (without_output) {
|
||||
esp_rom_install_channel_putc(1, mock_putc);
|
||||
}
|
||||
for (int i = 0; i < max_loops; i++) {
|
||||
start = esp_timer_get_time();
|
||||
if (without_output) {
|
||||
ESP_EARLY_LOGI(TAG, "");
|
||||
} else {
|
||||
ESP_EARLY_LOGI(TAG, "test msg %d", i);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
diff = MIN(diff, end - start);
|
||||
}
|
||||
if (without_output) {
|
||||
esp_rom_install_channel_putc(1, esp_rom_output_putc);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int measuring_execution_time_dram_log(bool without_output)
|
||||
{
|
||||
int diff;
|
||||
int64_t start, end;
|
||||
diff = INT32_MAX;
|
||||
if (without_output) {
|
||||
esp_rom_install_channel_putc(1, mock_putc);
|
||||
}
|
||||
for (int i = 0; i < max_loops; i++) {
|
||||
start = esp_timer_get_time();
|
||||
if (without_output) {
|
||||
ESP_DRAM_LOGI(TAG, "");
|
||||
} else {
|
||||
ESP_DRAM_LOGI(TAG, "test msg %d", i);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
diff = MIN(diff, end - start);
|
||||
}
|
||||
if (without_output) {
|
||||
esp_rom_install_channel_putc(1, esp_rom_output_putc);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int measuring_execution_time_printf(bool without_output)
|
||||
{
|
||||
int diff;
|
||||
int64_t start, end;
|
||||
diff = INT32_MAX;
|
||||
for (int i = 0; i < max_loops; i++) {
|
||||
start = esp_timer_get_time();
|
||||
if (without_output) {
|
||||
printf("\r");
|
||||
} else {
|
||||
printf("test msg %d\n", i);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
diff = MIN(diff, end - start);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int measuring_execution_time_vprintf(bool without_output)
|
||||
{
|
||||
int diff;
|
||||
int64_t start, end;
|
||||
diff = INT32_MAX;
|
||||
for (int i = 0; i < max_loops; i++) {
|
||||
start = esp_timer_get_time();
|
||||
if (without_output) {
|
||||
print_via_vprintf("\r");
|
||||
} else {
|
||||
print_via_vprintf("test msg %d\n", i);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
diff = MIN(diff, end - start);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
static int measuring_execution_time_esp_log_macro(bool without_output)
|
||||
{
|
||||
int diff;
|
||||
int64_t start, end;
|
||||
diff = INT32_MAX;
|
||||
vprintf_like_t original_vprintf;
|
||||
if (without_output) {
|
||||
original_vprintf = esp_log_set_vprintf(mock_vprintf);
|
||||
}
|
||||
for (int i = 0; i < max_loops; i++) {
|
||||
start = esp_timer_get_time();
|
||||
if (without_output) {
|
||||
ESP_LOGI(TAG, "\r");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "test msg %d", i);
|
||||
}
|
||||
end = esp_timer_get_time();
|
||||
diff = MIN(diff, end - start);
|
||||
}
|
||||
if (without_output) {
|
||||
esp_log_set_vprintf(original_vprintf);
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
TEST_CASE("Performance measurement for log APIs", "[log]")
|
||||
{
|
||||
#if ESP_LOG_VERSION == 2
|
||||
const int count_prints = 3;
|
||||
#else
|
||||
const int count_prints = 1;
|
||||
#endif
|
||||
|
||||
const uint32_t mask = esp_cpu_intr_get_enabled_mask();
|
||||
esp_cpu_intr_disable(0xFFFFFFFF);
|
||||
|
||||
int m_esp_rom_printf = measuring_execution_time_esp_rom_printf(true);
|
||||
int m_esp_rom_printf_output = measuring_execution_time_esp_rom_printf(false);
|
||||
|
||||
int m_esp_rom_vprintf = measuring_execution_time_esp_rom_vprintf(true);
|
||||
int m_esp_rom_vprintf_output = measuring_execution_time_esp_rom_vprintf(false);
|
||||
|
||||
int m_early_log = measuring_execution_time_early_log(true);
|
||||
int m_early_log_output = measuring_execution_time_early_log(false);
|
||||
|
||||
int m_dram_log_printf = measuring_execution_time_dram_log(true);
|
||||
int m_dram_log_printf_output = measuring_execution_time_dram_log(false);
|
||||
|
||||
int m_printf = measuring_execution_time_printf(true);
|
||||
int m_printf_output = measuring_execution_time_printf(false);
|
||||
|
||||
int m_vprintf = measuring_execution_time_vprintf(true);
|
||||
int m_vprintf_output = measuring_execution_time_vprintf(false);
|
||||
|
||||
int m_esp_log_macro = measuring_execution_time_esp_log_macro(true);
|
||||
int m_esp_log_macro_output = measuring_execution_time_esp_log_macro(false);
|
||||
|
||||
esp_cpu_intr_enable(mask);
|
||||
|
||||
esp_rom_printf("\nPerformance measurements for %s chip:\n", CONFIG_IDF_TARGET);
|
||||
esp_rom_printf("Function w/o output (us) | w/ output (us)\n");
|
||||
esp_rom_printf("esp_rom_printf %d %d\n", m_esp_rom_printf, m_esp_rom_printf_output);
|
||||
esp_rom_printf("esp_rom_vprintf %d %d\n", m_esp_rom_vprintf, m_esp_rom_vprintf_output);
|
||||
esp_rom_printf("ESP_EARLY_LOGI %d + %d %d\n", m_early_log, count_prints * m_esp_rom_printf, m_early_log_output);
|
||||
esp_rom_printf("ESP_DRAM_LOGI %d + %d %d\n", m_dram_log_printf, count_prints * m_esp_rom_vprintf, m_dram_log_printf_output);
|
||||
esp_rom_printf("printf %d %d\n", m_printf, m_printf_output);
|
||||
esp_rom_printf("vprintf %d %d\n", m_vprintf, m_vprintf_output);
|
||||
esp_rom_printf("ESP_LOGI %d + %d %d\n", m_esp_log_macro, count_prints * m_vprintf, m_esp_log_macro_output);
|
||||
}
|
@ -11,7 +11,7 @@ The logging library provides three ways for setting log verbosity:
|
||||
- **At compile time**: in menuconfig, set the verbosity level using the option :ref:`CONFIG_LOG_DEFAULT_LEVEL`.
|
||||
- Optionally, also in menuconfig, set the maximum verbosity level using the option :ref:`CONFIG_LOG_MAXIMUM_LEVEL`. By default, this is the same as the default level, but it can be set higher in order to compile more optional logs into the firmware.
|
||||
- **At runtime**: all logs for verbosity levels lower than :ref:`CONFIG_LOG_DEFAULT_LEVEL` are enabled by default. The function :cpp:func:`esp_log_level_set` can be used to set a logging level on a per-module basis. Modules are identified by their tags, which are human-readable ASCII zero-terminated strings. Note that the ability to change the log level at runtime depends on :ref:`CONFIG_LOG_DYNAMIC_LEVEL_CONTROL`.
|
||||
- **At runtime**: if :ref:`CONFIG_LOG_MASTER_LEVEL` is enabled then a ``Master logging level`` can be set using :cpp:func:`esp_log_set_level_master`. This option adds an additional logging level check for all compiled logs. Note that this will increase application size. This feature is useful if you want to compile a lot of logs that are selectable at runtime, but also want to avoid the performance hit from looking up the tags and their log level when you don't want log output.
|
||||
- **At runtime**: if :ref:`CONFIG_LOG_MASTER_LEVEL` is enabled then a ``Master logging level`` can be set using :cpp:func:`esp_log_set_level_master`. This option adds an additional logging level check. This feature is useful if you want to compile a lot of logs that are selectable at runtime, but also want to avoid the performance hit from looking up the tags and their log level when you don't want log output.
|
||||
|
||||
There are the following verbosity levels:
|
||||
|
||||
@ -105,9 +105,7 @@ If your application does not require dynamic log level changes and you do not ne
|
||||
Master Logging Level
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
To enable the Master logging level feature, the :ref:`CONFIG_LOG_MASTER_LEVEL` option must be enabled. It adds an additional level check for ``ESP_LOGx`` macros before calling :cpp:func:`esp_log_write`. This allows to set a higher :ref:`CONFIG_LOG_MAXIMUM_LEVEL`, but not inflict a performance hit during normal operation (only when directed). An application may set the master logging level (:cpp:func:`esp_log_set_level_master`) globally to enforce a maximum log level. ``ESP_LOGx`` macros above this level will be skipped immediately, rather than calling :cpp:func:`esp_log_write` and doing a tag lookup. It is recommended to only use this in an top-level application and not in shared components as this would override the global log level for any user using the component. By default, at startup, the Master logging level is :ref:`CONFIG_LOG_DEFAULT_LEVEL`.
|
||||
|
||||
Note that this feature increases application size because the additional check is added into all ``ESP_LOGx`` macros.
|
||||
To enable the Master logging level feature, the :ref:`CONFIG_LOG_MASTER_LEVEL` option must be enabled. There is an additional level check in :cpp:func:`esp_log`. This allows to set a higher :ref:`CONFIG_LOG_MAXIMUM_LEVEL`, but not inflict a performance hit during normal operation (only when directed). An application may set the master logging level (:cpp:func:`esp_log_set_level_master`) globally to enforce a maximum log level. ``ESP_LOGx`` macros above this level will be skipped, rather than doing a tag lookup. It is recommended to only use this in an top-level application and not in shared components as this would override the global log level for any user using the component. By default, at startup, the Master logging level is :ref:`CONFIG_LOG_DEFAULT_LEVEL`.
|
||||
|
||||
The snippet below shows how it works. Setting the Master logging level to ``ESP_LOG_NONE`` disables all logging globally. :cpp:func:`esp_log_level_set` does not currently affect logging. But after the Master logging level is released, the logs will be printed as set by :cpp:func:`esp_log_level_set`.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user