6#ifdef USE_CRASH_HANDLER
10#include <zephyr/device.h>
11#include <zephyr/drivers/uart.h>
12#include <zephyr/sys/printk.h>
13#include <zephyr/usb/usb_device.h>
14#ifdef USE_LOGGER_EARLY_MESSAGE
21#if KERNEL_VERSION_NUMBER >= 0x030700
32#if defined(CONFIG_THREAD_NAME)
33 char thread[CONFIG_THREAD_MAX_NAME_LEN];
39#ifdef USE_LOGGER_UART_SELECTION_USB_CDC
44 static bool opened =
false;
46 uart_line_ctrl_get(this->
uart_dev_, UART_LINE_CTRL_DTR, &dtr);
56#ifdef USE_CRASH_HANDLER
71 static const struct device *uart_dev =
nullptr;
72 switch (this->
uart_) {
74 uart_dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(uart0));
77 uart_dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(uart1));
79#ifdef USE_LOGGER_USB_CDC
81#ifdef CONFIG_USB_DEVICE_STACK
82 uart_dev = DEVICE_DT_GET_OR_NULL(DT_NODELABEL(cdc_acm_uart0));
83 if (device_is_ready(uart_dev)) {
90 if (device_is_ready(uart_dev)) {
92#if defined(USE_LOGGER_WAIT_FOR_CDC) && defined(USE_LOGGER_UART_SELECTION_USB_CDC)
94 int32_t
count = (10 * 100);
95 while (dtr == 0 &&
count-- > 0) {
96 uart_line_ctrl_get(this->
uart_dev_, UART_LINE_CTRL_DTR, &dtr);
105 ESP_LOGI(TAG,
"Log initialized");
106#ifdef USE_LOGGER_EARLY_MESSAGE
107 char reason_buffer[zephyr::RESET_REASON_BUFFER_SIZE];
108 const char *reset_reason =
zephyr::get_reset_reason(std::span<char, zephyr::RESET_REASON_BUFFER_SIZE>(reason_buffer));
109 ESP_LOGI(TAG,
"Reset reason: %s", reset_reason);
112#ifdef USE_CRASH_HANDLER
113#ifdef USE_LOGGER_UART_SELECTION_USB_CDC
129 printk(
"%.*s",
static_cast<int>(
len), msg);
134 for (uint16_t i = 0; i <
len; ++i) {
140 switch (this->
uart_) {
142 return LOG_STR(
"UART0");
144 return LOG_STR(
"UART1");
145#ifdef USE_LOGGER_USB_CDC
147 return LOG_STR(
"USB_CDC");
150 return LOG_STR(
"UNKNOWN");
154static const uint8_t REASON_BUF_SIZE = 32;
156static const char *reason_to_str(
unsigned int reason,
char *buf) {
158 case K_ERR_CPU_EXCEPTION:
159 return "CPU exception";
160 case K_ERR_SPURIOUS_IRQ:
161 return "Unhandled interrupt";
162 case K_ERR_STACK_CHK_FAIL:
163 return "Stack overflow";
164 case K_ERR_KERNEL_OOPS:
165 return "Kernel oops";
166 case K_ERR_KERNEL_PANIC:
167 return "Kernel panic";
169 snprintf(buf, REASON_BUF_SIZE,
"Unknown error (%u)", reason);
175 ESP_LOGD(TAG,
"Crash buffer address %p", &
crash_buf);
177 char reason_buf[REASON_BUF_SIZE];
178 ESP_LOGE(TAG,
"Last crash:");
179 ESP_LOGE(TAG,
"Reason=%s PC=0x%08x LR=0x%08x", reason_to_str(
crash_buf.reason, reason_buf),
crash_buf.pc,
181#if defined(CONFIG_THREAD_NAME)
182 ESP_LOGE(TAG,
"Thread: %s",
crash_buf.thread);
184 int32_t
count = (2 * 100);
185 while (
count-- > 0) {
199#if defined(CONFIG_THREAD_NAME)
200 auto thread = k_current_get();
201 const char *name = k_thread_name_get(thread);
212#ifdef USE_CRASH_HANDLER
uint32_t get_config_hash()
Get the config hash as a 32-bit integer.
void schedule_dump_config()
void write_msg_(const char *msg, uint16_t len)
const LogString * get_uart_selection_()
void pre_setup()
Set up this component.
struct @66::@67 __attribute__
Wake the main loop task from an ISR. ISR-safe.
void k_sys_fatal_error_handler(unsigned int reason, const esphome::logger::FatalErrorEsf *esf)
bool crash_log_pending()
Whether a crash record from before this boot is waiting to be reported.
void k_sys_fatal_error_handler(unsigned int reason, const FatalErrorEsf *esf)
void log_crash_to_client()
Log the previous crash for a client that just subscribed to the logs.
ESPHOME_LOG_TAG(TAG, "logger")
bool coredump_pending()
Whether a dump from before this boot is waiting to be printed.
void print_coredump()
A log reader is present: serial at boot, USB CDC when the port opens, an API or MQTT client subscribi...
constexpr const char * CRASH_LOG_TAG
The tag the dump is logged under, so a client can check the level in force for it.
void stop_coredump()
The reader went away (the USB port was closed); the print stops and the dump stays for the next one.
const char * get_reset_reason(std::span< char, RESET_REASON_BUFFER_SIZE > buffer)
void HOT delay(uint32_t ms)
Application App
Global storage of Application pointer - only one Application can exist.