Библиотека лога предоставляет 2 способа установки подробности вывода информации (verbosity level):
· В момент компиляции (compile time): в menuconfig установить verbosity level по умолчанию, используя опцию CONFIG_LOG_DEFAULT_LEVEL. · Опционально, также в menuconfig, установите максимальный уровень подробности (maximum verbosity level), используя опцию CONFIG_LOG_MAXIMUM_LEVEL. По умолчанию она имеет такое же значение, что и CONFIG_LOG_DEFAULT_LEVEL, однако её можно установить на более высокий уровень, чтобы скомпилировать в firmware больше опциональных логов. · Во время работы приложения (runtime): все логи, у которых уровни подробности меньше, чем CONFIG_LOG_DEFAULT_LEVEL, по умолчанию разрешены. Функция esp_log_level_set() может использоваться для установки уровня подробности лога в пределах одного модуля (файла исходного кода). Модули идентифицируются по своим тегам, которые являются удобочитаемыми строками ASCIIZ.
Существуют следующие уровни подробности лога (verbosity level):
· Error (самый низкий уровень, выводятся только ошибки) · Warning · Info · Debug · Verbose (самый высокий уровень подробности вывода)
Замечание: функция esp_log_level_set() не может установить уровни подробности лога выше, чем это указано опцией CONFIG_LOG_MAXIMUM_LEVEL. Чтобы увеличить уровень лога для определенного фала выше этого максимума в момент компиляции, используйте макрос LOG_LOCAL_LEVEL (подробнее об этом см. далее).
[Как использовать библиотеку лога ESP-IDF]
В каждом C-файле (модуле), в котором используется лог, определите переменную TAG, как показано ниже:
static const char* TAG = "MyModule";
Затем используйте макросы вывода, например:
ESP_LOGW(TAG, "Baud rate error %.1f%%. Requested: %d baud, actual: %d baud",
error * 100, baud_req, baud_real);
Доступны несколько макросов для разных уровней подробности вывода:
ESP_LOGE - error (самый низкий уровень) ESP_LOGW - warning ESP_LOGI - info ESP_LOGD - debug ESP_LOGV - verbose (самый высокий уровень)
Эти макросы отличаются друг от друга двумя моментами: во-первых, будет или не будет выведено макросом сообщение, зависит от текущего установленного уровня подробности. Во-вторых, отличается цвет текста выводимых сообщений в команде idf.py monitor. Например, ESP_LOGI выведет сообщение зеленым текстом, ESP_LOGW желтым текстом, а ESP_LOGE красным текстом.
Дополнительно существуют версии ESP_EARLY_LOGx для этих макросов, например ESP_EARLY_LOGE. Эти версии явно используются только в коде раннего запуска (startup), до того момента, как инициализируется куча (heap allocator) и системные вызовы (syscalls). Обычные макросы ESP_LOGx могут также использоваться, когда компилируется bootloader, однако для них произойдет откат обратно к той же реализации, что и у макросов ESP_EARLY_LOGx.
Также существуют версии ESP_DRAM_LOGx этих макросов, например ESP_DRAM_LOGE. Эти версии используются в некоторых местах, где вывод в лог может привести в условиях запрещенных прерываний, или когда кэш памяти flash недоступна. Использование этих макросов должно быть максимально щадящим, поскольку вывод в лог на таких местах кода вообще следует избегать по соображениям производительности.
Замечание: внутри критических секций кода прерывания запрещены, так что можно использовать только лишь ESP_DRAM_LOGx (что предпочтительнее) или ESP_EARLY_LOGx. Несмотря на то, что есть возможность использовать такой лог в этих ситуациях, лучше всего хорошо структурировать программу, чтобы это вовсе не потребовалось.
Чтобы отменить уровень подробности лога по умолчанию для области файла или области компонента, определите макрос LOG_LOCAL_LEVEL.
Для области файла определите этот макрос перед подключением esp_log.h, например:
#define LOG_LOCAL_LEVEL ESP_LOG_VERBOSE
#include "esp_log.h"
В области компонента определите его в файле CMakeLists компонента:
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DLOG_LOCAL_LEVEL=ESP_LOG_VERBOSE")
Для конфигурирования вывода в области модуля runtime, добавьте вызовы функции esp_log_level_set() следующим образом:
esp_log_level_set("*", ESP_LOG_ERROR); // установить уровень ERROR для всех компонентов
esp_log_level_set("wifi", ESP_LOG_WARN); // разрешить логи WARN для стека WiFi
esp_log_level_set("dhcpc", ESP_LOG_INFO); // разрешить логи INFO из клиента DHCP
Замечание: варианты макросов лога "DRAM" и "EARLY", упомянутые выше, не поддерживают установку подробности вывода в лог в области модуля. Эти макросы всегда будут использовать verbosity level по умолчанию, который можно поменять runtime только вызовом esp_log_level("*", level).
Лог на хост через JTAG. По умолчанию библиотека лога использует функцию наподобие vprintf для форматированного вывода в выделенный для программирования и лога UART. Вместо этого простым API-вызовом вывод может быть перенаправлен в JTAG, что сделает вывод в лог в несколько раз быстрее. За подробностями обратитесь в раздел "Logging to Host" документации [2].
[Пример приложения]
Библиотека лога используется в большинстве компонентов примеров и примеров ESP-IDF как основной метод отладки и поиска ошибок. Для демонстрации функционала вывода в лог просмотрите содержимое директории examples каталога установки ESP-IDF. Наиболее подходящие примеры для исследования работы лога:
system/ota storage/sd_card protocols/https_request
[Справочник по API]
Заголовочный файл библиотеки лога components/log/include/esp_log.h.
В следующей таблице приведен общий список API-функций и макросов лога с кратким описанием. Подробное описание с назначением параметров, возвращаемых значений, типов данных см. в документации [1].
API-функции
Функция |
Описание |
esp_log_level_set |
Установит уровень лога для указанного тега. Если лог для указанного компонента был уже разрешен, то эта функция поменяет предыдущую настройку. |
esp_log_level_get |
Получит уровень лога для указанного тега, может использоваться для устранения лишних операторов лога. |
esp_log_set_vprintf |
Установит функцию, используемую для вывода элементов лога. По умолчанию вывод лога производится в UART0 (лог доступен в терминале командой idf.py monitor). Эта функция может использоваться для перенаправления вывода лога в некоторые другие устройства, такие как файл или сеть. Возвратит оригинальный обработчик лога, который может понадобиться для возврата предыдущего направления вывода лога. |
esp_log_timestamp |
Функция, которая вернет метку времени, используемую для вывода в лог. Эта функция используется в расширении макросов ESP_LOGx. На стадии загрузчика второй ступени (2nd stage bootloader) и коде раннего запуска приложения (early application startup) эта функция использует счетчик тактов CPU как источник отсчета времени. Позже, когда заработает планировщик FreeRTOS, про метка времени для лога будет извлекаться из счетчика тиков FreeRTOS. Для отладочного вывода в лог абсолютного времени в настоящий момент переполнение этого счетчика игнорируется. |
esp_log_system_timestamp |
Функция, которая берет системную метку времени для использования в выводе лога. Эта функция используется в макросах ESP_LOGx, чтобы печатать системное время в виде "HH:MM:SS.sss". Системное время инициализируется на 0 в момент startup, оно может быть установлено на корректное время с помощью синхронизации SNTP, или вручную стандартными POSIX-функциями времени. В настоящий момент это не будет использоваться для вывода в лог из двоичного кода (например библиотек Wi-Fi и Bluetooth), оттуда будет печататься время тиков RTOS (что для отслеживания интервалов времени часто удобнее формата HH:MM:SS.sss). |
esp_log_early_timestamp |
Функция, которая берет системную метку времени для использования в выводе лога. Эта функция использует аппаратный счетчик тактов, и не зависит от реализации OS, так что может безопасно использоваться после краха приложения. |
esp_log_write |
Запись сообщения в лог. Эта функция не предназначена для прямого использования. Вместо неё вызывайте макросы ESP_LOGE, ESP_LOGW, ESP_LOGI, ESP_LOGD, ESP_LOGV. Эта функция и эти макросы не должны использоваться в коде обработчика прерывания (ISR). |
esp_log_writev |
Запись сообщения в лог, организованный в виде списка (вариант va_list). Эта функция предоставлена для упрощения интеграции в другой фреймворк лога, чтобы esp_log можно было использовать как точку слива в лог. |
Макросы
Макрос |
Описание |
ESP_LOG_BUFFER_HEX_LEVEL |
Вывод в лог содержимого буфера в виде HEX-значений байт, по 16 байт на каждой строке, на указанном уровне подробности лога LEVEL. |
ESP_LOG_BUFFER_CHAR_LEVEL |
Вывод в лог содержимого буфера в виде символов, по 16 байт на строке, на указанном уровне подробности лога LEVEL. Буфер должен содержать только печатаемые символы. |
ESP_LOG_BUFFER_HEXDUMP |
Дамп буфера в лог на указанном уровне подробности. Выводит и HEX значения, и соответствующие ASCII символы, по 16 байт в строке. |
ESP_LOG_BUFFER_HEX |
Вывод в лог содержимого буфера в виде HEX-значений байт, на уровне подробности Info. |
ESP_LOG_BUFFER_CHAR |
Вывод в лог содержимого буфера в виде ASCII-символов, на уровне подробности Info. Буфер должен содержать только печатаемые символы. |
ESP_EARLY_LOGE |
Макрос для вывода в лог из кода startup, до момента инициализации heap allocator и syscalls. Выводит в лог на уровне ESP_LOG_ERROR. |
ESP_EARLY_LOGW |
То же самое, только на уровне ESP_LOG_WARN. |
ESP_EARLY_LOGI |
То же самое, только на уровне ESP_LOG_INFO. |
ESP_EARLY_LOGD |
То же самое, только на уровне ESP_LOG_DEBUG. |
ESP_EARLY_LOGV |
То же самое, только на уровне ESP_LOG_VERBOSE. |
ESP_LOGE(tag, format, ...) ESP_LOGW(tag, format, ...) ESP_LOGI(tag, format, ...) ESP_LOGD(tag, format, ...) ESP_LOGV(tag, format, ...) ESP_LOG_LEVEL(level, tag, format, ...) |
Макросы, вызываемые из обычного кода для вывода в лог на указанном уровне подробности. |
ESP_LOG_LEVEL_LOCAL |
Макрос, вызываемый из обычного кода для вывода в лог на указанном уровне подробности. Также проверяйте уровень подробности с помощью LOG_LOCAL_LEVEL. |
ESP_DRAM_LOGE |
Макрос для вывода в лог, когда кэш запрещен. Выводит в лог на уровне ESP_LOG_ERROR. |
ESP_DRAM_LOGW |
То же самое, только на уровне ESP_LOG_WARN. |
ESP_DRAM_LOGI |
То же самое, только на уровне ESP_LOG_INFO. |
ESP_DRAM_LOGD |
То же самое, только на уровне ESP_LOG_DEBUG. |
ESP_DRAM_LOGV |
То же самое, только на уровне ESP_LOG_VERBOSE. |
[Ссылки]
1. ESP-IDF Logging library site:espressif.com. 2. ESP-IDF Application Level Tracing library site:espressif.com. |