1 /* 2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef __ESP_LOG_H__ 8 #define __ESP_LOG_H__ 9 10 #include <stdint.h> 11 #include <stdarg.h> 12 #include "sdkconfig.h" 13 #include "esp_rom_sys.h" 14 #if CONFIG_IDF_TARGET_ESP32 15 #include "esp32/rom/ets_sys.h" // will be removed in idf v5.0 16 #elif CONFIG_IDF_TARGET_ESP32S2 17 #include "esp32s2/rom/ets_sys.h" 18 #elif CONFIG_IDF_TARGET_ESP32S3 19 #include "esp32s3/rom/ets_sys.h" 20 #elif CONFIG_IDF_TARGET_ESP32C3 21 #include "esp32c3/rom/ets_sys.h" 22 #elif CONFIG_IDF_TARGET_ESP32H2 23 #include "esp32h2/rom/ets_sys.h" 24 #endif 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 /** 31 * @brief Log level 32 * 33 */ 34 typedef enum { 35 ESP_LOG_NONE, /*!< No log output */ 36 ESP_LOG_ERROR, /*!< Critical errors, software module can not recover on its own */ 37 ESP_LOG_WARN, /*!< Error conditions from which recovery measures have been taken */ 38 ESP_LOG_INFO, /*!< Information messages which describe normal flow of events */ 39 ESP_LOG_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ 40 ESP_LOG_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ 41 } esp_log_level_t; 42 43 typedef int (*vprintf_like_t)(const char *, va_list); 44 45 /** 46 * @brief Default log level 47 * 48 * This is used by the definition of ESP_EARLY_LOGx macros. It is not 49 * recommended to set this directly, call esp_log_level_set("*", level) 50 * instead. 51 */ 52 extern esp_log_level_t esp_log_default_level; 53 54 /** 55 * @brief Set log level for given tag 56 * 57 * If logging for given component has already been enabled, changes previous setting. 58 * 59 * Note that this function can not raise log level above the level set using 60 * CONFIG_LOG_MAXIMUM_LEVEL setting in menuconfig. 61 * 62 * To raise log level above the default one for a given file, define 63 * LOG_LOCAL_LEVEL to one of the ESP_LOG_* values, before including 64 * esp_log.h in this file. 65 * 66 * @param tag Tag of the log entries to enable. Must be a non-NULL zero terminated string. 67 * Value "*" resets log level for all tags to the given value. 68 * 69 * @param level Selects log level to enable. Only logs at this and lower verbosity 70 * levels will be shown. 71 */ 72 void esp_log_level_set(const char* tag, esp_log_level_t level); 73 74 /** 75 * @brief Get log level for given tag, can be used to avoid expensive log statements 76 * 77 * @param tag Tag of the log to query current level. Must be a non-NULL zero terminated 78 * string. 79 * 80 * @return The current log level for the given tag 81 */ 82 esp_log_level_t esp_log_level_get(const char* tag); 83 84 /** 85 * @brief Set function used to output log entries 86 * 87 * By default, log output goes to UART0. This function can be used to redirect log 88 * output to some other destination, such as file or network. Returns the original 89 * log handler, which may be necessary to return output to the previous destination. 90 * 91 * @note Please note that function callback here must be re-entrant as it can be 92 * invoked in parallel from multiple thread context. 93 * 94 * @param func new Function used for output. Must have same signature as vprintf. 95 * 96 * @return func old Function used for output. 97 */ 98 vprintf_like_t esp_log_set_vprintf(vprintf_like_t func); 99 100 /** 101 * @brief Function which returns timestamp to be used in log output 102 * 103 * This function is used in expansion of ESP_LOGx macros. 104 * In the 2nd stage bootloader, and at early application startup stage 105 * this function uses CPU cycle counter as time source. Later when 106 * FreeRTOS scheduler start running, it switches to FreeRTOS tick count. 107 * 108 * For now, we ignore millisecond counter overflow. 109 * 110 * @return timestamp, in milliseconds 111 */ 112 uint32_t esp_log_timestamp(void); 113 114 /** 115 * @brief Function which returns system timestamp to be used in log output 116 * 117 * This function is used in expansion of ESP_LOGx macros to print 118 * the system time as "HH:MM:SS.sss". The system time is initialized to 119 * 0 on startup, this can be set to the correct time with an SNTP sync, 120 * or manually with standard POSIX time functions. 121 * 122 * Currently this will not get used in logging from binary blobs 123 * (i.e WiFi & Bluetooth libraries), these will still print the RTOS tick time. 124 * 125 * @return timestamp, in "HH:MM:SS.sss" 126 */ 127 char* esp_log_system_timestamp(void); 128 129 /** 130 * @brief Function which returns timestamp to be used in log output 131 * 132 * This function uses HW cycle counter and does not depend on OS, 133 * so it can be safely used after application crash. 134 * 135 * @return timestamp, in milliseconds 136 */ 137 uint32_t esp_log_early_timestamp(void); 138 139 /** 140 * @brief Write message into the log 141 * 142 * This function is not intended to be used directly. Instead, use one of 143 * ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV macros. 144 * 145 * This function or these macros should not be used from an interrupt. 146 */ 147 void esp_log_write(esp_log_level_t level, const char* tag, const char* format, ...) __attribute__ ((format (printf, 3, 4))); 148 149 /** 150 * @brief Write message into the log, va_list variant 151 * @see esp_log_write() 152 * 153 * This function is provided to ease integration toward other logging framework, 154 * so that esp_log can be used as a log sink. 155 */ 156 void esp_log_writev(esp_log_level_t level, const char* tag, const char* format, va_list args); 157 158 /** @cond */ 159 160 #include "esp_log_internal.h" 161 162 #ifndef LOG_LOCAL_LEVEL 163 #ifndef BOOTLOADER_BUILD 164 #define LOG_LOCAL_LEVEL CONFIG_BOOTLOADER_LOG_LEVEL 165 #else 166 #define LOG_LOCAL_LEVEL CONFIG_BOOTLOADER_LOG_LEVEL 167 #endif 168 #endif 169 170 /** @endcond */ 171 172 /** 173 * @brief Log a buffer of hex bytes at specified level, separated into 16 bytes each line. 174 * 175 * @param tag description tag 176 * @param buffer Pointer to the buffer array 177 * @param buff_len length of buffer in bytes 178 * @param level level of the log 179 * 180 */ 181 #define ESP_LOG_BUFFER_HEX_LEVEL( tag, buffer, buff_len, level ) \ 182 do {\ 183 if ( LOG_LOCAL_LEVEL >= (level) ) { \ 184 esp_log_buffer_hex_internal( tag, buffer, buff_len, level ); \ 185 } \ 186 } while(0) 187 188 /** 189 * @brief Log a buffer of characters at specified level, separated into 16 bytes each line. Buffer should contain only printable characters. 190 * 191 * @param tag description tag 192 * @param buffer Pointer to the buffer array 193 * @param buff_len length of buffer in bytes 194 * @param level level of the log 195 * 196 */ 197 #define ESP_LOG_BUFFER_CHAR_LEVEL( tag, buffer, buff_len, level ) \ 198 do {\ 199 if ( LOG_LOCAL_LEVEL >= (level) ) { \ 200 esp_log_buffer_char_internal( tag, buffer, buff_len, level ); \ 201 } \ 202 } while(0) 203 204 /** 205 * @brief Dump a buffer to the log at specified level. 206 * 207 * The dump log shows just like the one below: 208 * 209 * W (195) log_example: 0x3ffb4280 45 53 50 33 32 20 69 73 20 67 72 65 61 74 2c 20 |ESP32 is great, | 210 * W (195) log_example: 0x3ffb4290 77 6f 72 6b 69 6e 67 20 61 6c 6f 6e 67 20 77 69 |working along wi| 211 * W (205) log_example: 0x3ffb42a0 74 68 20 74 68 65 20 49 44 46 2e 00 |th the IDF..| 212 * 213 * It is highly recommend to use terminals with over 102 text width. 214 * 215 * @param tag description tag 216 * @param buffer Pointer to the buffer array 217 * @param buff_len length of buffer in bytes 218 * @param level level of the log 219 */ 220 #define ESP_LOG_BUFFER_HEXDUMP( tag, buffer, buff_len, level ) \ 221 do { \ 222 if ( LOG_LOCAL_LEVEL >= (level) ) { \ 223 esp_log_buffer_hexdump_internal( tag, buffer, buff_len, level); \ 224 } \ 225 } while(0) 226 227 /** 228 * @brief Log a buffer of hex bytes at Info level 229 * 230 * @param tag description tag 231 * @param buffer Pointer to the buffer array 232 * @param buff_len length of buffer in bytes 233 * 234 * @see ``esp_log_buffer_hex_level`` 235 * 236 */ 237 #define ESP_LOG_BUFFER_HEX(tag, buffer, buff_len) \ 238 do { \ 239 if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { \ 240 ESP_LOG_BUFFER_HEX_LEVEL( tag, buffer, buff_len, ESP_LOG_INFO ); \ 241 }\ 242 } while(0) 243 244 /** 245 * @brief Log a buffer of characters at Info level. Buffer should contain only printable characters. 246 * 247 * @param tag description tag 248 * @param buffer Pointer to the buffer array 249 * @param buff_len length of buffer in bytes 250 * 251 * @see ``esp_log_buffer_char_level`` 252 * 253 */ 254 #define ESP_LOG_BUFFER_CHAR(tag, buffer, buff_len) \ 255 do { \ 256 if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) { \ 257 ESP_LOG_BUFFER_CHAR_LEVEL( tag, buffer, buff_len, ESP_LOG_INFO ); \ 258 }\ 259 } while(0) 260 261 /** @cond */ 262 263 //to be back compatible 264 #define esp_log_buffer_hex ESP_LOG_BUFFER_HEX 265 #define esp_log_buffer_char ESP_LOG_BUFFER_CHAR 266 267 268 #if CONFIG_LOG_COLORS 269 #define LOG_COLOR_BLACK "30" 270 #define LOG_COLOR_RED "31" 271 #define LOG_COLOR_GREEN "32" 272 #define LOG_COLOR_BROWN "33" 273 #define LOG_COLOR_BLUE "34" 274 #define LOG_COLOR_PURPLE "35" 275 #define LOG_COLOR_CYAN "36" 276 #define LOG_COLOR(COLOR) "\033[0;" COLOR "m" 277 #define LOG_BOLD(COLOR) "\033[1;" COLOR "m" 278 #define LOG_RESET_COLOR "\033[0m" 279 #define LOG_COLOR_E LOG_COLOR(LOG_COLOR_RED) 280 #define LOG_COLOR_W LOG_COLOR(LOG_COLOR_BROWN) 281 #define LOG_COLOR_I LOG_COLOR(LOG_COLOR_GREEN) 282 #define LOG_COLOR_D 283 #define LOG_COLOR_V 284 #else //CONFIG_LOG_COLORS 285 #define LOG_COLOR_E 286 #define LOG_COLOR_W 287 #define LOG_COLOR_I 288 #define LOG_COLOR_D 289 #define LOG_COLOR_V 290 #define LOG_RESET_COLOR 291 #endif //CONFIG_LOG_COLORS 292 293 #define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%u) %s: " format LOG_RESET_COLOR "\n" 294 #define LOG_SYSTEM_TIME_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%s) %s: " format LOG_RESET_COLOR "\n" 295 296 /** @endcond */ 297 298 /// 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`` 299 #define portGET_ARGUMENT_COUNT_INNER(zero, one, count, ...) count 300 301 /** 302 * In the future, we want to switch to C++20. We also want to become compatible with clang. 303 * Hence, we provide two versions of the following macros which are using variadic arguments. 304 * The first one is using the GNU extension \#\#__VA_ARGS__. The second one is using the C++20 feature __VA_OPT__(,). 305 * This allows users to compile their code with standard C++20 enabled instead of the GNU extension. 306 * Below C++20, we haven't found any good alternative to using \#\#__VA_ARGS__. 307 */ 308 #if defined(__cplusplus) && (__cplusplus > 201703L) 309 #define ESP_EARLY_LOGE( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR, E __VA_OPT__(,) __VA_ARGS__) 310 /// macro to output logs in startup code at ``ESP_LOG_WARN`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 311 #define ESP_EARLY_LOGW( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN, W __VA_OPT__(,) __VA_ARGS__) 312 /// macro to output logs in startup code at ``ESP_LOG_INFO`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 313 #define ESP_EARLY_LOGI( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_INFO, I __VA_OPT__(,) __VA_ARGS__) 314 /// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 315 #define ESP_EARLY_LOGD( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG, D __VA_OPT__(,) __VA_ARGS__) 316 /// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 317 #define ESP_EARLY_LOGV( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__) 318 #else // !(defined(__cplusplus) && (__cplusplus > 201703L)) 319 #define ESP_EARLY_LOGE( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_ERROR, E, ##__VA_ARGS__) 320 /// macro to output logs in startup code at ``ESP_LOG_WARN`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 321 #define ESP_EARLY_LOGW( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_WARN, W, ##__VA_ARGS__) 322 /// macro to output logs in startup code at ``ESP_LOG_INFO`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 323 #define ESP_EARLY_LOGI( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_INFO, I, ##__VA_ARGS__) 324 /// macro to output logs in startup code at ``ESP_LOG_DEBUG`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 325 #define ESP_EARLY_LOGD( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_DEBUG, D, ##__VA_ARGS__) 326 /// macro to output logs in startup code at ``ESP_LOG_VERBOSE`` level. @see ``ESP_EARLY_LOGE``,``ESP_LOGE``, ``printf`` 327 #define ESP_EARLY_LOGV( tag, format, ... ) ESP_LOG_EARLY_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__) 328 #endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) 329 330 #ifdef BOOTLOADER_BUILD 331 #define _ESP_LOG_EARLY_ENABLED(log_level) (LOG_LOCAL_LEVEL >= (log_level)) 332 #else 333 /* For early log, there is no log tag filtering. So we want to log only if both the LOG_LOCAL_LEVEL and the 334 currently configured min log level are higher than the log level */ 335 #define _ESP_LOG_EARLY_ENABLED(log_level) (LOG_LOCAL_LEVEL >= (log_level) && esp_log_default_level >= (log_level)) 336 #endif 337 338 #define ESP_LOG_EARLY_IMPL(tag, format, log_level, log_tag_letter, ...) do { \ 339 if (_ESP_LOG_EARLY_ENABLED(log_level)) { \ 340 esp_rom_printf(LOG_FORMAT(log_tag_letter, format), esp_log_timestamp(), tag, ##__VA_ARGS__); \ 341 }} while(0) 342 343 #ifndef BOOTLOADER_BUILD 344 #if defined(__cplusplus) && (__cplusplus > 201703L) 345 #define ESP_LOGE( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, tag, format __VA_OPT__(,) __VA_ARGS__) 346 #define ESP_LOGW( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, tag, format __VA_OPT__(,) __VA_ARGS__) 347 #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format __VA_OPT__(,) __VA_ARGS__) 348 #define ESP_LOGD( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, tag, format __VA_OPT__(,) __VA_ARGS__) 349 #define ESP_LOGV( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format __VA_OPT__(,) __VA_ARGS__) 350 #else // !(defined(__cplusplus) && (__cplusplus > 201703L)) 351 #define ESP_LOGE( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__) 352 #define ESP_LOGW( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_WARN, tag, format, ##__VA_ARGS__) 353 #define ESP_LOGI( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_INFO, tag, format, ##__VA_ARGS__) 354 #define ESP_LOGD( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_DEBUG, tag, format, ##__VA_ARGS__) 355 #define ESP_LOGV( tag, format, ... ) ESP_LOG_LEVEL_LOCAL(ESP_LOG_VERBOSE, tag, format, ##__VA_ARGS__) 356 #endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) 357 #else 358 359 /** 360 * Macro to output logs at ESP_LOG_ERROR level. 361 * 362 * @note This macro cannot be used when interrupts are disabled or inside an ISR. @see ``ESP_DRAM_LOGE``. 363 * 364 * @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime. 365 * 366 * @see ``printf`` 367 */ 368 #if defined(__cplusplus) && (__cplusplus > 201703L) 369 #define ESP_LOGE( tag, format, ... ) ESP_EARLY_LOGE(tag, format __VA_OPT__(,) __VA_ARGS__) 370 /// macro to output logs at ``ESP_LOG_WARN`` level. @see ``ESP_LOGE`` 371 #define ESP_LOGW( tag, format, ... ) ESP_EARLY_LOGW(tag, format __VA_OPT__(,) __VA_ARGS__) 372 /// macro to output logs at ``ESP_LOG_INFO`` level. @see ``ESP_LOGE`` 373 #define ESP_LOGI( tag, format, ... ) ESP_EARLY_LOGI(tag, format __VA_OPT__(,) __VA_ARGS__) 374 /// macro to output logs at ``ESP_LOG_DEBUG`` level. @see ``ESP_LOGE`` 375 #define ESP_LOGD( tag, format, ... ) ESP_EARLY_LOGD(tag, format __VA_OPT__(,) __VA_ARGS__) 376 /// macro to output logs at ``ESP_LOG_VERBOSE`` level. @see ``ESP_LOGE`` 377 #define ESP_LOGV( tag, format, ... ) ESP_EARLY_LOGV(tag, format __VA_OPT__(,) __VA_ARGS__) 378 #else // !(defined(__cplusplus) && (__cplusplus > 201703L)) 379 #define ESP_LOGE( tag, format, ... ) ESP_EARLY_LOGE(tag, format, ##__VA_ARGS__) 380 /// macro to output logs at ``ESP_LOG_WARN`` level. @see ``ESP_LOGE`` 381 #define ESP_LOGW( tag, format, ... ) ESP_EARLY_LOGW(tag, format, ##__VA_ARGS__) 382 /// macro to output logs at ``ESP_LOG_INFO`` level. @see ``ESP_LOGE`` 383 #define ESP_LOGI( tag, format, ... ) ESP_EARLY_LOGI(tag, format, ##__VA_ARGS__) 384 /// macro to output logs at ``ESP_LOG_DEBUG`` level. @see ``ESP_LOGE`` 385 #define ESP_LOGD( tag, format, ... ) ESP_EARLY_LOGD(tag, format, ##__VA_ARGS__) 386 /// macro to output logs at ``ESP_LOG_VERBOSE`` level. @see ``ESP_LOGE`` 387 #define ESP_LOGV( tag, format, ... ) ESP_EARLY_LOGV(tag, format, ##__VA_ARGS__) 388 #endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) 389 #endif // BOOTLOADER_BUILD 390 391 /** runtime macro to output logs at a specified level. 392 * 393 * @param tag tag of the log, which can be used to change the log level by ``esp_log_level_set`` at runtime. 394 * @param level level of the output log. 395 * @param format format of the output log. see ``printf`` 396 * @param ... variables to be replaced into the log. see ``printf`` 397 * 398 * @see ``printf`` 399 */ 400 /* Zephyr: remove ESP_LOG */ 401 #define ESP_LOG_LEVEL(level, tag, format, ...) 402 403 /* 404 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__); } \ 405 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__); } \ 406 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__); } \ 407 else { esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \ 408 } while(0) 409 #elif CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM 410 #define ESP_LOG_LEVEL(level, tag, format, ...) do { \ 411 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__); } \ 412 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__); } \ 413 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__); } \ 414 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__); } \ 415 else { esp_log_write(ESP_LOG_INFO, tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \ 416 } while(0) 417 #endif //CONFIG_LOG_TIMESTAMP_SOURCE_xxx 418 #else // !(defined(__cplusplus) && (__cplusplus > 201703L)) 419 #if CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 420 #define ESP_LOG_LEVEL(level, tag, format, ...) do { \ 421 if (level==ESP_LOG_ERROR ) { esp_log_write(ESP_LOG_ERROR, tag, LOG_FORMAT(E, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ 422 else if (level==ESP_LOG_WARN ) { esp_log_write(ESP_LOG_WARN, tag, LOG_FORMAT(W, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ 423 else if (level==ESP_LOG_DEBUG ) { esp_log_write(ESP_LOG_DEBUG, tag, LOG_FORMAT(D, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ 424 else if (level==ESP_LOG_VERBOSE ) { esp_log_write(ESP_LOG_VERBOSE, tag, LOG_FORMAT(V, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ 425 else { esp_log_write(ESP_LOG_INFO, tag, LOG_FORMAT(I, format), esp_log_timestamp(), tag, ##__VA_ARGS__); } \ 426 } while(0) 427 #elif CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM 428 #define ESP_LOG_LEVEL(level, tag, format, ...) do { \ 429 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__); } \ 430 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__); } \ 431 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__); } \ 432 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__); } \ 433 else { esp_log_write(ESP_LOG_INFO, tag, LOG_SYSTEM_TIME_FORMAT(I, format), esp_log_system_timestamp(), tag, ##__VA_ARGS__); } \ 434 } while(0) 435 #endif //CONFIG_LOG_TIMESTAMP_SOURCE_xxx 436 #endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) 437 */ 438 439 /** runtime macro to output logs at a specified level. Also check the level with ``LOG_LOCAL_LEVEL``. 440 * 441 * @see ``printf``, ``ESP_LOG_LEVEL`` 442 */ 443 #define ESP_LOG_LEVEL_LOCAL(level, tag, format, ...) do { \ 444 if ( LOG_LOCAL_LEVEL >= level ) ESP_LOG_LEVEL(level, tag, format, ##__VA_ARGS__); \ 445 } while(0) 446 447 448 /** 449 * @brief Macro to output logs when the cache is disabled. log at ``ESP_LOG_ERROR`` level. 450 * 451 * @note Unlike normal logging macros, it's possible to use this macro when interrupts are 452 * disabled or inside an ISR. 453 * 454 * Similar to @see ``ESP_EARLY_LOGE``, the log level cannot be changed per-tag, however 455 * esp_log_level_set("*", level) will set the default level which controls these log lines also. 456 * 457 * Usage: `ESP_DRAM_LOGE(DRAM_STR("my_tag"), "format", or `ESP_DRAM_LOGE(TAG, "format", ...)`, 458 * where TAG is a char* that points to a str in the DRAM. 459 * 460 * @note Placing log strings in DRAM reduces available DRAM, so only use when absolutely essential. 461 * 462 * @see ``esp_rom_printf``,``ESP_LOGE`` 463 */ 464 #if defined(__cplusplus) && (__cplusplus > 201703L) 465 #define ESP_DRAM_LOGE( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR, E __VA_OPT__(,) __VA_ARGS__) 466 /// macro to output logs when the cache is disabled at ``ESP_LOG_WARN`` level. @see ``ESP_DRAM_LOGW``,``ESP_LOGW``, ``esp_rom_printf`` 467 #define ESP_DRAM_LOGW( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN, W __VA_OPT__(,) __VA_ARGS__) 468 /// macro to output logs when the cache is disabled at ``ESP_LOG_INFO`` level. @see ``ESP_DRAM_LOGI``,``ESP_LOGI``, ``esp_rom_printf`` 469 #define ESP_DRAM_LOGI( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_INFO, I __VA_OPT__(,) __VA_ARGS__) 470 /// macro to output logs when the cache is disabled at ``ESP_LOG_DEBUG`` level. @see ``ESP_DRAM_LOGD``,``ESP_LOGD``, ``esp_rom_printf`` 471 #define ESP_DRAM_LOGD( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG, D __VA_OPT__(,) __VA_ARGS__) 472 /// macro to output logs when the cache is disabled at ``ESP_LOG_VERBOSE`` level. @see ``ESP_DRAM_LOGV``,``ESP_LOGV``, ``esp_rom_printf`` 473 #define ESP_DRAM_LOGV( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V __VA_OPT__(,) __VA_ARGS__) 474 #else // !(defined(__cplusplus) && (__cplusplus > 201703L)) 475 #define ESP_DRAM_LOGE( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_ERROR, E, ##__VA_ARGS__) 476 /// macro to output logs when the cache is disabled at ``ESP_LOG_WARN`` level. @see ``ESP_DRAM_LOGW``,``ESP_LOGW``, ``esp_rom_printf`` 477 #define ESP_DRAM_LOGW( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_WARN, W, ##__VA_ARGS__) 478 /// macro to output logs when the cache is disabled at ``ESP_LOG_INFO`` level. @see ``ESP_DRAM_LOGI``,``ESP_LOGI``, ``esp_rom_printf`` 479 #define ESP_DRAM_LOGI( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_INFO, I, ##__VA_ARGS__) 480 /// macro to output logs when the cache is disabled at ``ESP_LOG_DEBUG`` level. @see ``ESP_DRAM_LOGD``,``ESP_LOGD``, ``esp_rom_printf`` 481 #define ESP_DRAM_LOGD( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_DEBUG, D, ##__VA_ARGS__) 482 /// macro to output logs when the cache is disabled at ``ESP_LOG_VERBOSE`` level. @see ``ESP_DRAM_LOGV``,``ESP_LOGV``, ``esp_rom_printf`` 483 #define ESP_DRAM_LOGV( tag, format, ... ) ESP_DRAM_LOG_IMPL(tag, format, ESP_LOG_VERBOSE, V, ##__VA_ARGS__) 484 #endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) 485 486 /** @cond */ 487 #define _ESP_LOG_DRAM_LOG_FORMAT(letter, format) DRAM_STR(#letter " %s: " format "\n") 488 489 #if defined(__cplusplus) && (__cplusplus > 201703L) 490 #define ESP_DRAM_LOG_IMPL(tag, format, log_level, log_tag_letter, ...) do { \ 491 if (_ESP_LOG_EARLY_ENABLED(log_level)) { \ 492 esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag __VA_OPT__(,) __VA_ARGS__); \ 493 }} while(0) 494 #else // !(defined(__cplusplus) && (__cplusplus > 201703L)) 495 #define ESP_DRAM_LOG_IMPL(tag, format, log_level, log_tag_letter, ...) do { \ 496 if (_ESP_LOG_EARLY_ENABLED(log_level)) { \ 497 esp_rom_printf(_ESP_LOG_DRAM_LOG_FORMAT(log_tag_letter, format), tag, ##__VA_ARGS__); \ 498 }} while(0) 499 #endif // !(defined(__cplusplus) && (__cplusplus > 201703L)) 500 /** @endcond */ 501 502 #ifdef __cplusplus 503 } 504 #endif 505 506 507 #endif /* __ESP_LOG_H__ */ 508