mirror of
https://github.com/esphome/esphome.git
synced 2026-06-04 09:22:23 +08:00
[debug] Fix missing reset reason for RP2040/RP2350 (#14740)
This commit is contained in:
@@ -1,23 +1,81 @@
|
|||||||
#include "debug_component.h"
|
#include "debug_component.h"
|
||||||
#ifdef USE_RP2040
|
#ifdef USE_RP2040
|
||||||
|
#include "esphome/core/defines.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include <hardware/watchdog.h>
|
||||||
|
#if defined(PICO_RP2350)
|
||||||
|
#include <hardware/structs/powman.h>
|
||||||
|
#else
|
||||||
|
#include <hardware/structs/vreg_and_chip_reset.h>
|
||||||
|
#endif
|
||||||
|
#ifdef USE_RP2040_CRASH_HANDLER
|
||||||
|
#include "esphome/components/rp2040/crash_handler.h"
|
||||||
|
#endif
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace debug {
|
namespace debug {
|
||||||
|
|
||||||
static const char *const TAG = "debug";
|
static const char *const TAG = "debug";
|
||||||
|
|
||||||
const char *DebugComponent::get_reset_reason_(std::span<char, RESET_REASON_BUFFER_SIZE> buffer) { return ""; }
|
const char *DebugComponent::get_reset_reason_(std::span<char, RESET_REASON_BUFFER_SIZE> buffer) {
|
||||||
|
char *buf = buffer.data();
|
||||||
|
const size_t size = RESET_REASON_BUFFER_SIZE;
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
#if defined(PICO_RP2350)
|
||||||
|
uint32_t chip_reset = powman_hw->chip_reset;
|
||||||
|
if (chip_reset & 0x04000000) // HAD_GLITCH_DETECT
|
||||||
|
pos = buf_append_str(buf, size, pos, "Power supply glitch|");
|
||||||
|
if (chip_reset & 0x00040000) // HAD_RUN_LOW
|
||||||
|
pos = buf_append_str(buf, size, pos, "RUN pin|");
|
||||||
|
if (chip_reset & 0x00020000) // HAD_BOR
|
||||||
|
pos = buf_append_str(buf, size, pos, "Brown-out|");
|
||||||
|
if (chip_reset & 0x00010000) // HAD_POR
|
||||||
|
pos = buf_append_str(buf, size, pos, "Power-on reset|");
|
||||||
|
#else
|
||||||
|
uint32_t chip_reset = vreg_and_chip_reset_hw->chip_reset;
|
||||||
|
if (chip_reset & 0x00010000) // HAD_RUN
|
||||||
|
pos = buf_append_str(buf, size, pos, "RUN pin|");
|
||||||
|
if (chip_reset & 0x00000100) // HAD_POR
|
||||||
|
pos = buf_append_str(buf, size, pos, "Power-on reset|");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (watchdog_caused_reboot()) {
|
||||||
|
bool handled = false;
|
||||||
|
#ifdef USE_RP2040_CRASH_HANDLER
|
||||||
|
if (rp2040::crash_handler_has_data()) {
|
||||||
|
pos = buf_append_str(buf, size, pos, "Crash (HardFault)|");
|
||||||
|
handled = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!handled) {
|
||||||
|
if (watchdog_enable_caused_reboot()) {
|
||||||
|
pos = buf_append_str(buf, size, pos, "Watchdog timeout|");
|
||||||
|
} else {
|
||||||
|
pos = buf_append_str(buf, size, pos, "Software reset|");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove trailing '|'
|
||||||
|
if (pos > 0 && buf[pos - 1] == '|') {
|
||||||
|
buf[pos - 1] = '\0';
|
||||||
|
} else if (pos == 0) {
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
const char *DebugComponent::get_wakeup_cause_(std::span<char, RESET_REASON_BUFFER_SIZE> buffer) { return ""; }
|
const char *DebugComponent::get_wakeup_cause_(std::span<char, RESET_REASON_BUFFER_SIZE> buffer) { return ""; }
|
||||||
|
|
||||||
uint32_t DebugComponent::get_free_heap_() { return rp2040.getFreeHeap(); }
|
uint32_t DebugComponent::get_free_heap_() { return ::rp2040.getFreeHeap(); }
|
||||||
|
|
||||||
size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE> buffer, size_t pos) {
|
size_t DebugComponent::get_device_info_(std::span<char, DEVICE_INFO_BUFFER_SIZE> buffer, size_t pos) {
|
||||||
constexpr size_t size = DEVICE_INFO_BUFFER_SIZE;
|
constexpr size_t size = DEVICE_INFO_BUFFER_SIZE;
|
||||||
char *buf = buffer.data();
|
char *buf = buffer.data();
|
||||||
|
|
||||||
uint32_t cpu_freq = rp2040.f_cpu();
|
uint32_t cpu_freq = ::rp2040.f_cpu();
|
||||||
ESP_LOGD(TAG, "CPU Frequency: %" PRIu32, cpu_freq);
|
ESP_LOGD(TAG, "CPU Frequency: %" PRIu32, cpu_freq);
|
||||||
pos = buf_append_printf(buf, size, pos, "|CPU Frequency: %" PRIu32, cpu_freq);
|
pos = buf_append_printf(buf, size, pos, "|CPU Frequency: %" PRIu32, cpu_freq);
|
||||||
|
|
||||||
|
|||||||
@@ -942,6 +942,28 @@ __attribute__((format(printf, 4, 5))) inline size_t buf_append_printf(char *buf,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// Safely append a string to buffer without format parsing, returning new position (capped at size).
|
||||||
|
/// More efficient than buf_append_printf for plain string literals.
|
||||||
|
/// @param buf Output buffer
|
||||||
|
/// @param size Total buffer size
|
||||||
|
/// @param pos Current position in buffer
|
||||||
|
/// @param str String to append (must not be null)
|
||||||
|
/// @return New position after appending (capped at size on overflow)
|
||||||
|
inline size_t buf_append_str(char *buf, size_t size, size_t pos, const char *str) {
|
||||||
|
if (pos >= size) {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
size_t remaining = size - pos - 1; // reserve space for null terminator
|
||||||
|
size_t len = strlen(str);
|
||||||
|
if (len > remaining) {
|
||||||
|
len = remaining;
|
||||||
|
}
|
||||||
|
memcpy(buf + pos, str, len);
|
||||||
|
pos += len;
|
||||||
|
buf[pos] = '\0';
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
/// Concatenate a name with a separator and suffix using an efficient stack-based approach.
|
/// Concatenate a name with a separator and suffix using an efficient stack-based approach.
|
||||||
/// This avoids multiple heap allocations during string construction.
|
/// This avoids multiple heap allocations during string construction.
|
||||||
/// Maximum name length supported is 120 characters for friendly names.
|
/// Maximum name length supported is 120 characters for friendly names.
|
||||||
|
|||||||
Reference in New Issue
Block a user