[debug] Show source of last software reboot (#8595)

This commit is contained in:
Clyde Stubbs 2025-05-05 14:31:37 +10:00 committed by GitHub
parent e7a2b395fd
commit b8d83d0765
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 37 additions and 3 deletions

View File

@ -1,6 +1,7 @@
#include "debug_component.h"
#include <algorithm>
#include "esphome/core/application.h"
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"

View File

@ -34,6 +34,7 @@ class DebugComponent : public PollingComponent {
#endif
void set_loop_time_sensor(sensor::Sensor *loop_time_sensor) { loop_time_sensor_ = loop_time_sensor; }
#ifdef USE_ESP32
void on_shutdown() override;
void set_psram_sensor(sensor::Sensor *psram_sensor) { this->psram_sensor_ = psram_sensor; }
#endif // USE_ESP32
void set_cpu_frequency_sensor(sensor::Sensor *cpu_frequency_sensor) {

View File

@ -1,6 +1,7 @@
#include "debug_component.h"
#ifdef USE_ESP32
#include "esphome/core/application.h"
#include "esphome/core/log.h"
#include "esphome/core/hal.h"
#include <esp_sleep.h>
@ -10,12 +11,12 @@
#include <esp_chip_info.h>
#include <esp_partition.h>
#include <map>
#ifdef USE_ARDUINO
#include <Esp.h>
#endif
#include <map>
namespace esphome {
namespace debug {
@ -42,16 +43,39 @@ static const char *const RESET_REASONS[] = {
"CPU lock up",
};
static const char *const REBOOT_KEY = "reboot_source";
static const size_t REBOOT_MAX_LEN = 24;
// on shutdown, store the source of the reboot request
void DebugComponent::on_shutdown() {
auto *component = App.get_current_component();
char buffer[REBOOT_MAX_LEN]{};
auto pref = global_preferences->make_preference(REBOOT_MAX_LEN, fnv1_hash(REBOOT_KEY + App.get_name()));
if (component != nullptr) {
strncpy(buffer, component->get_component_source(), REBOOT_MAX_LEN - 1);
}
ESP_LOGD(TAG, "Storing reboot source: %s", buffer);
pref.save(&buffer);
global_preferences->sync();
}
std::string DebugComponent::get_reset_reason_() {
std::string reset_reason;
unsigned reason = esp_reset_reason();
if (reason < sizeof(RESET_REASONS) / sizeof(RESET_REASONS[0])) {
reset_reason = RESET_REASONS[reason];
if (reason == ESP_RST_SW) {
auto pref = global_preferences->make_preference(REBOOT_MAX_LEN, fnv1_hash(REBOOT_KEY + App.get_name()));
char buffer[REBOOT_MAX_LEN]{};
if (pref.load(&buffer)) {
reset_reason = "Reboot request from " + std::string(buffer);
}
}
} else {
reset_reason = "unknown source";
}
ESP_LOGD(TAG, "Reset Reason: %s", reset_reason.c_str());
return "Reset by " + reset_reason;
return reset_reason;
}
static const char *const WAKEUP_CAUSES[] = {

View File

@ -70,6 +70,7 @@ void Application::loop() {
this->feed_wdt();
for (Component *component : this->looping_components_) {
{
this->set_current_component(component);
WarnIfComponentBlockingGuard guard{component};
component->call();
}

View File

@ -97,6 +97,9 @@ class Application {
this->compilation_time_ = compilation_time;
}
void set_current_component(Component *component) { this->current_component_ = component; }
Component *get_current_component() { return this->current_component_; }
#ifdef USE_BINARY_SENSOR
void register_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
this->binary_sensors_.push_back(binary_sensor);
@ -547,6 +550,7 @@ class Application {
uint32_t loop_interval_{16};
size_t dump_config_at_{SIZE_MAX};
uint32_t app_state_{0};
Component *current_component_{nullptr};
};
/// Global storage of Application pointer - only one Application can exist.

View File

@ -1,4 +1,6 @@
#include "scheduler.h"
#include "application.h"
#include "esphome/core/defines.h"
#include "esphome/core/log.h"
#include "esphome/core/helpers.h"
@ -215,6 +217,7 @@ void HOT Scheduler::call() {
this->pop_raw_();
continue;
}
App.set_current_component(item->component);
#ifdef ESPHOME_DEBUG_SCHEDULER
ESP_LOGV(TAG, "Running %s '%s/%s' with interval=%" PRIu32 " next_execution=%" PRIu64 " (now=%" PRIu64 ")",