Программирование ARM Библиотека ESP-IDF для вывода в лог Sat, April 20 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

Библиотека ESP-IDF для вывода в лог Печать
Добавил(а) microsin   

Библиотека лога предоставляет 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.

 

Добавить комментарий


Защитный код
Обновить

Top of Page