8#include <zephyr/version.h>
11#include <zephyr/debug/coredump.h>
21static constexpr size_t LINE_OVERHEAD = 64;
22static constexpr size_t CHUNK_SIZE =
23 std::min<size_t>(64, (ESPHOME_LOGGER_TX_BUFFER_SIZE - LINE_OVERHEAD) / 2 / 16 * 16);
24static_assert(CHUNK_SIZE >= 16,
"logger line buffer too small for a coredump line");
26static constexpr uint32_t START_DELAY_MS = 1000;
27static constexpr uint32_t START_DELAY_ID = 0;
29static constexpr uint32_t LINE_INTERVAL_MS = 10;
32static Coredump *global_coredump =
nullptr;
33static bool reader_present =
false;
38 reader_present =
true;
39 if (global_coredump !=
nullptr)
44 reader_present =
false;
45 if (global_coredump !=
nullptr)
50 global_coredump =
this;
54 const int size = coredump_query(COREDUMP_QUERY_GET_STORED_DUMP_SIZE,
nullptr);
61 this->
verify_ = coredump_cmd(COREDUMP_CMD_VERIFY_STORED_DUMP,
nullptr);
87 ESP_LOGE(TAG,
"Stored coredump verification failed: %d", this->
verify_);
92 ESP_LOGE(TAG,
"#CD:BEGIN#");
94 uint8_t buf[CHUNK_SIZE];
96 coredump_cmd_copy_arg arg{
static_cast<off_t
>(this->
offset_), buf,
98 const int ret = coredump_cmd(COREDUMP_CMD_COPY_STORED_DUMP, &arg);
104 ESP_LOGE(TAG,
"#CD:END#");
113 ESP_LOGE(TAG,
"Failed to copy coredump: %d", err);
115 const int erase = coredump_cmd(COREDUMP_CMD_ERASE_STORED_DUMP,
nullptr);
117 ESP_LOGE(TAG,
"Failed to erase coredump: %d", erase);
130 " Size: %" PRIu32
"\n"
134 coredump_query(COREDUMP_QUERY_GET_ERROR,
nullptr));
141#ifdef USE_ZEPHYR_COREDUMP_SP_FIX
145#if KERNEL_VERSION_NUMBER >= 0x030700
148using esf_t = z_arch_esf_t;
151static constexpr uint8_t EXC_RETURN_STACK_FRAME_TYPE_POS = 4;
152static constexpr uint32_t EXC_RETURN_STACK_FRAME_TYPE_EXTENDED = 0;
158 global_exc_return = exc_return;
167#if defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) || defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE)
168 if (esf ==
nullptr) {
172 z_arm_coredump_fault_sp +=
sizeof(esf->basic);
173#if defined(CONFIG_FPU) && defined(CONFIG_FPU_SHARING)
175 if ((global_exc_return & BIT(EXC_RETURN_STACK_FRAME_TYPE_POS)) == EXC_RETURN_STACK_FRAME_TYPE_EXTENDED) {
176 z_arm_coredump_fault_sp +=
sizeof(esf->fpu);
179#ifndef CONFIG_ARMV8_M_MAINLINE
181 if ((esf->basic.xpsr & SCB_CCR_STKALIGN_Msk) == SCB_CCR_STKALIGN_Msk) {
182 z_arm_coredump_fault_sp |= 0x4;
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
bool cancel_timeout(const char *name)
Cancel a timeout function.
void enable_loop()
Enable this component's loop.
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
void disable_loop()
Disable this component's loop.
void start_print_()
Start printing after a short delay, one line per loop so the USB CDC transmit buffer and the main loo...
void dump_config() override
void __real_z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, _callee_saved_t *callee_regs)
void __wrap_z_arm_fault(uint32_t msp, uint32_t psp, uint32_t exc_return, _callee_saved_t *callee_regs)
void __real_z_arm_fatal_error(unsigned int reason, const esf_t *esf)
void __wrap_z_arm_fatal_error(unsigned int reason, const esf_t *esf)
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...
ESPHOME_LOG_TAG(TAG, "zephyr_coredump")
void stop_coredump()
The reader went away (the USB port was closed); the print stops and the dump stays for the next one.
constexpr size_t format_hex_size(size_t byte_count)
Calculate buffer size needed for format_hex_to: "XXXXXXXX...\0" = bytes * 2 + 1.
char * format_hex_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length)
Format byte array as lowercase hex to buffer (base implementation).
Application App
Global storage of Application pointer - only one Application can exist.