ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
logger_esp32.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32
2#include "logger.h"
3
5#include <esp_log.h>
6#include <esp_idf_version.h>
7
8#include <driver/uart.h>
9#include <soc/soc_caps.h>
10
11#ifdef USE_LOGGER_UART_SELECTION_USB_SERIAL_JTAG
12#include <driver/usb_serial_jtag.h>
13#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
14#include <esp_vfs_dev.h>
15#include <esp_vfs_usb_serial_jtag.h>
16#else
17#include <driver/usb_serial_jtag_vfs.h>
18#endif
19#endif
20#if defined(CONFIG_PM_ENABLE) && defined(CONFIG_FREERTOS_USE_TICKLESS_IDLE) && \
21 (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0))
22#include "esp_sleep.h"
23#endif
24#include "freertos/FreeRTOS.h"
25
26#include <fcntl.h>
27#include <cstdint>
28#include <cstdio>
29
30#include "esphome/core/log.h"
31
32namespace esphome::logger {
33
34ESPHOME_LOG_TAG(TAG, "logger");
35
36#ifdef USE_LOGGER_UART_SELECTION_USB_SERIAL_JTAG
37static void init_usb_serial_jtag() {
38 setvbuf(stdin, NULL, _IONBF, 0); // Disable buffering on stdin
39
40#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
41 // Minicom, screen, idf_monitor send CR when ENTER key is pressed
42 esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
43 // Move the caret to the beginning of the next line on '\n'
44 esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
45#else
46 // Minicom, screen, idf_monitor send CR when ENTER key is pressed
47 usb_serial_jtag_vfs_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
48 // Move the caret to the beginning of the next line on '\n'
49 usb_serial_jtag_vfs_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
50#endif
51
52 // Enable non-blocking mode on stdin and stdout
53 fcntl(fileno(stdout), F_SETFL, 0);
54 fcntl(fileno(stdin), F_SETFL, 0);
55
56 usb_serial_jtag_driver_config_t usb_serial_jtag_config{};
57 usb_serial_jtag_config.rx_buffer_size = 512;
58 usb_serial_jtag_config.tx_buffer_size = 512;
59
60 esp_err_t ret = ESP_OK;
61 // Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes
62 ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config);
63 if (ret != ESP_OK) {
64 return;
65 }
66
67 // Tell vfs to use usb-serial-jtag driver
68#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 3, 0)
69 esp_vfs_usb_serial_jtag_use_driver();
70#else
71 usb_serial_jtag_vfs_use_driver();
72#endif
73}
74#endif
75
76void init_uart(uart_port_t uart_num, uint32_t baud_rate, int tx_buffer_size) {
77 uart_config_t uart_config{};
78 uart_config.baud_rate = (int) baud_rate;
79 uart_config.data_bits = UART_DATA_8_BITS;
80 uart_config.parity = UART_PARITY_DISABLE;
81 uart_config.stop_bits = UART_STOP_BITS_1;
82 uart_config.flow_ctrl = UART_HW_FLOWCTRL_DISABLE;
83#if SOC_UART_SUPPORT_XTAL_CLK
84 uart_config.source_clk = UART_SCLK_XTAL;
85#else
86 uart_config.source_clk = UART_SCLK_DEFAULT;
87#endif
88 uart_param_config(uart_num, &uart_config);
89 // The logger only writes to UART, never reads, so use the minimum RX buffer.
90 // ESP-IDF requires rx_buffer_size > UART_HW_FIFO_LEN (128 bytes).
91 const int min_rx_buffer_size = UART_HW_FIFO_LEN(uart_num) + 1;
92 uart_driver_install(uart_num, min_rx_buffer_size, tx_buffer_size, 0, nullptr, 0);
93#if defined(CONFIG_PM_ENABLE) && defined(CONFIG_FREERTOS_USE_TICKLESS_IDLE) && \
94 (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0))
95 // Always flush before going to light sleep. Could be disabled for devices
96 // without TOP_PD or if source_clk = UART_SCLK_RTC
97 esp_sleep_set_console_uart_handling_mode(ESP_SLEEP_ALWAYS_FLUSH_UART);
98#endif
99}
100
102 if (this->baud_rate_ > 0) {
103 this->uart_num_ = UART_NUM_0;
104 switch (this->uart_) {
106 this->uart_num_ = UART_NUM_0;
107 init_uart(this->uart_num_, baud_rate_, ESPHOME_LOGGER_TX_BUFFER_SIZE);
108 break;
110 this->uart_num_ = UART_NUM_1;
111 init_uart(this->uart_num_, baud_rate_, ESPHOME_LOGGER_TX_BUFFER_SIZE);
112 break;
113#ifdef USE_ESP32_VARIANT_ESP32
115 this->uart_num_ = UART_NUM_2;
116 init_uart(this->uart_num_, baud_rate_, ESPHOME_LOGGER_TX_BUFFER_SIZE);
117 break;
118#endif
119#ifdef USE_LOGGER_USB_CDC
121 break;
122#endif
123#ifdef USE_LOGGER_USB_SERIAL_JTAG
125#ifdef USE_LOGGER_UART_SELECTION_USB_SERIAL_JTAG
126 init_usb_serial_jtag();
127#endif
128 break;
129#endif
130 }
131 }
132
133 global_logger = this;
134 esp_log_set_vprintf(esp_idf_log_vprintf_);
135
136 ESP_LOGI(TAG, "Log initialized");
137#ifdef USE_ESP32_CRASH_HANDLER
139#endif
140}
141
142const LogString *Logger::get_uart_selection_() {
143 switch (this->uart_) {
145 return LOG_STR("UART0");
147 return LOG_STR("UART1");
148#ifdef USE_ESP32_VARIANT_ESP32
150 return LOG_STR("UART2");
151#endif
152#ifdef USE_LOGGER_USB_CDC
154 return LOG_STR("USB_CDC");
155#endif
156#ifdef USE_LOGGER_USB_SERIAL_JTAG
158 return LOG_STR("USB_SERIAL_JTAG");
159#endif
160 default:
161 return LOG_STR("UNKNOWN");
162 }
163}
164
165#ifdef USE_CRASH_HANDLER
168 // A level that drops the lines would throw the record away unseen; keep it for a client that can see it
169 if (global_logger->get_log_level(esp32::CRASH_LOG_TAG) < ESPHOME_LOG_LEVEL_ERROR)
170 return;
173}
174#endif
175
176} // namespace esphome::logger
177#endif
UARTSelection uart_
Definition logger.h:362
const LogString * get_uart_selection_()
uint8_t get_log_level()
Definition logger.h:180
void pre_setup()
Set up this component.
uart_port_t uart_num_
Definition logger.h:341
int ret
constexpr const char * CRASH_LOG_TAG
The tag the crash record is logged under, so a client can check the level in force for it.
bool crash_handler_has_data()
Returns true if crash data was found this boot, reading it first if needed.
void crash_handler_log()
Log crash data if a crash was detected on previous boot.
void crash_handler_clear()
Clear the magic marker and mark crash data as consumed.
bool crash_log_pending()
Whether a crash record from before this boot is waiting to be reported.
@ UART_SELECTION_UART2
Definition logger.h:118
@ UART_SELECTION_USB_SERIAL_JTAG
Definition logger.h:124
@ UART_SELECTION_USB_CDC
Definition logger.h:121
@ UART_SELECTION_UART0
Definition logger.h:112
@ UART_SELECTION_UART1
Definition logger.h:116
Logger * global_logger
Definition logger.cpp:276
void init_uart(uart_port_t uart_num, uint32_t baud_rate, int tx_buffer_size)
void log_crash_to_client()
Log the previous crash for a client that just subscribed to the logs.
ESPHOME_LOG_TAG(TAG, "logger")
int HOT esp_idf_log_vprintf_(const char *format, va_list args)
Definition log.cpp:64
static void uint32_t