Merge remote-tracking branch 'upstream/fix-rp2040-debug-reset-reason' into integration

This commit is contained in:
J. Nick Koston
2026-03-12 12:17:08 -10:00
2 changed files with 86 additions and 1 deletions
+64 -1
View File
@@ -2,12 +2,75 @@
#ifdef USE_RP2040
#include "esphome/core/log.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
namespace esphome {
namespace 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 & 0x10000000) // HAD_WATCHDOG_RESET_RSM
pos = buf_append_str(buf, size, pos, "Watchdog (RSM)|");
if (chip_reset & 0x08000000) // HAD_HZD_SYS_RESET_REQ
pos = buf_append_str(buf, size, pos, "Hazard debugger reset|");
if (chip_reset & 0x04000000) // HAD_GLITCH_DETECT
pos = buf_append_str(buf, size, pos, "Power supply glitch|");
if (chip_reset & 0x02000000) // HAD_SWCORE_PD
pos = buf_append_str(buf, size, pos, "Switched core powerdown|");
if (chip_reset & 0x01000000) // HAD_WATCHDOG_RESET_SWCORE
pos = buf_append_str(buf, size, pos, "Watchdog (SWCORE)|");
if (chip_reset & 0x00800000) // HAD_WATCHDOG_RESET_POWMAN
pos = buf_append_str(buf, size, pos, "Watchdog (POWMAN)|");
if (chip_reset & 0x00400000) // HAD_WATCHDOG_RESET_POWMAN_ASYNC
pos = buf_append_str(buf, size, pos, "Watchdog (POWMAN async)|");
if (chip_reset & 0x00200000) // HAD_RESCUE
pos = buf_append_str(buf, size, pos, "Rescue reset|");
if (chip_reset & 0x00080000) // HAD_DP_RESET_REQ
pos = buf_append_str(buf, size, pos, "Debugger reset|");
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 & 0x00100000) // HAD_PSM_RESTART
pos = buf_append_str(buf, size, pos, "Debug port restart|");
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()) {
if (watchdog_enable_caused_reboot()) {
pos = buf_append_str(buf, size, pos, "Watchdog timeout|");
} else {
pos = buf_append_str(buf, size, pos, "Watchdog reboot|");
}
}
// 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 ""; }
+22
View File
@@ -1074,6 +1074,28 @@ __attribute__((format(printf, 4, 5))) inline size_t buf_append_printf(char *buf,
}
#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
/// @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.
/// This avoids multiple heap allocations during string construction.
/// Maximum name length supported is 120 characters for friendly names.