mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-27 12:46:34 +00:00
Redesign Exception reporting
Redesign Exception reporting removing exception details from both MQTT info and Status 1. Now consolidated in Status 12 if available.
This commit is contained in:
parent
2381f9781c
commit
29d5d68ca0
@ -107,12 +107,6 @@ String GetResetReason(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String GetResetReasonInfo(void)
|
|
||||||
{
|
|
||||||
// "Fatal exception:0 flag:2 (EXCEPTION) epc1:0x704022a7 epc2:0x00000000 epc3:0x00000000 excvaddr:0x00000000 depc:0x00000000"
|
|
||||||
return (ResetReason() == REASON_EXCEPTION_RST) ? ESP.getResetInfo() : GetResetReason();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Miscellaneous
|
* Miscellaneous
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -334,6 +334,9 @@ void CmndStatus(void)
|
|||||||
if ((!Settings.flag.mqtt_enabled) && (6 == payload)) { payload = 99; } // SetOption3 - Enable MQTT
|
if ((!Settings.flag.mqtt_enabled) && (6 == payload)) { payload = 99; } // SetOption3 - Enable MQTT
|
||||||
if (!energy_flg && (9 == payload)) { payload = 99; }
|
if (!energy_flg && (9 == payload)) { payload = 99; }
|
||||||
|
|
||||||
|
bool exception_flg = (ResetReason() == REASON_EXCEPTION_RST);
|
||||||
|
if (!exception_flg && (12 == payload)) { payload = 99; }
|
||||||
|
|
||||||
if ((0 == payload) || (99 == payload)) {
|
if ((0 == payload) || (99 == payload)) {
|
||||||
uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present;
|
uint32_t maxfn = (devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!devices_present) ? 1 : devices_present;
|
||||||
#ifdef USE_SONOFF_IFAN
|
#ifdef USE_SONOFF_IFAN
|
||||||
@ -369,7 +372,7 @@ void CmndStatus(void)
|
|||||||
D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\""
|
D_JSON_RESTARTREASON "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\",\"" D_JSON_STARTUPUTC "\":\"%s\",\"" D_CMND_SLEEP "\":%d,\""
|
||||||
D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
D_JSON_CONFIG_HOLDER "\":%d,\"" D_JSON_BOOTCOUNT "\":%d,\"" D_JSON_SAVECOUNT "\":%d,\"" D_JSON_SAVEADDRESS "\":\"%X\"}}"),
|
||||||
baudrate, Settings.mqtt_grptopic, Settings.ota_url,
|
baudrate, Settings.mqtt_grptopic, Settings.ota_url,
|
||||||
GetResetReasonInfo().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep,
|
GetResetReason().c_str(), GetUptime().c_str(), GetDateAndTime(DT_RESTART).c_str(), Settings.sleep,
|
||||||
Settings.cfg_holder, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
Settings.cfg_holder, Settings.bootcount, Settings.save_flag, GetSettingsAddress());
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "1"));
|
||||||
}
|
}
|
||||||
@ -483,11 +486,13 @@ void CmndStatus(void)
|
|||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "11"));
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "11"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((0 == payload) || (12 == payload)) {
|
if (exception_flg) {
|
||||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS12_STATUS "\":"));
|
if ((0 == payload) || (12 == payload)) {
|
||||||
CrashDump();
|
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS12_STATUS "\":"));
|
||||||
ResponseJsonEnd();
|
CrashDump();
|
||||||
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "12"));
|
ResponseJsonEnd();
|
||||||
|
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "12"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_SCRIPT_STATUS
|
#ifdef USE_SCRIPT_STATUS
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
support_crash_recorder.ino - record the call stack in RTC in cas of crash
|
support_crash_recorder.ino - record the call stack in RTC in case of crash
|
||||||
|
|
||||||
Copyright (C) 2019 Stephan Hadinger, Theo Arends,
|
Copyright (C) 2019 Stephan Hadinger, Theo Arends,
|
||||||
|
|
||||||
@ -17,30 +17,30 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const uint32_t dump_max_len = 63; // dump only 64 call addresses
|
const uint32_t crash_magic = 0x53415400; // Stack trace magic number (TASx)
|
||||||
|
const uint32_t crash_rtc_offset = 32; // Offset in RTC memory skipping OTA used block
|
||||||
|
const uint32_t crash_dump_max_len = 31; // Dump only 31 call addresses to satisfy max JSON length of about 600 characters
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save crash information in RTC memory
|
* Save crash information in RTC memory
|
||||||
* This function is called automatically if ESP8266 suffers an exception
|
* This function is called automatically if ESP8266 suffers an exception
|
||||||
* It should be kept quick / consise to be able to execute before hardware wdt may kick in
|
* It should be kept quick / consise to be able to execute before hardware wdt may kick in
|
||||||
*/
|
*/
|
||||||
extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) {
|
extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack, uint32_t stack_end )
|
||||||
|
{
|
||||||
uint32_t addr_written = 0; // how many addresses have we already written in RTC
|
uint32_t addr_written = 0; // how many addresses have we already written in RTC
|
||||||
uint32_t value; // 4 bytes buffer to write to RTC
|
uint32_t value; // 4 bytes buffer to write to RTC
|
||||||
|
|
||||||
for (uint32_t i = stack; i < stack_end; i += 4) {
|
for (uint32_t i = stack; i < stack_end; i += 4) {
|
||||||
value = *((uint32_t*) i); // load value from stack
|
value = *((uint32_t*) i); // load value from stack
|
||||||
if ((value >= 0x40000000) && (value < 0x40300000)) { // keep only addresses in code area
|
if ((value >= 0x40000000) && (value < 0x40300000)) { // keep only addresses in code area
|
||||||
ESP.rtcUserMemoryWrite(addr_written, (uint32_t*)&value, sizeof(value));
|
ESP.rtcUserMemoryWrite(crash_rtc_offset + addr_written, (uint32_t*)&value, sizeof(value));
|
||||||
addr_written++;
|
addr_written++;
|
||||||
if (addr_written >= dump_max_len) { break; } // we store only 63 addresses
|
if (addr_written >= crash_dump_max_len) { break; } // we store only 31 addresses
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// fill the rest of RTC with the amount of addresses
|
value = crash_magic + addr_written;
|
||||||
value = addr_written;
|
ESP.rtcUserMemoryWrite(crash_rtc_offset + crash_dump_max_len, (uint32_t*)&value, sizeof(value));
|
||||||
while (addr_written < dump_max_len +1) {
|
|
||||||
ESP.rtcUserMemoryWrite(addr_written++, (uint32_t*)&value, sizeof(value));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a crash to test the crash recorder
|
// Generate a crash to test the crash recorder
|
||||||
@ -51,26 +51,39 @@ void CmndCrash(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear the RTC dump counter when we do a normal reboot, this avoids garbage data to stay in RTC
|
// Clear the RTC dump counter when we do a normal reboot, this avoids garbage data to stay in RTC
|
||||||
void CrashDumpClear(void) {
|
void CrashDumpClear(void)
|
||||||
|
{
|
||||||
uint32_t value = 0;
|
uint32_t value = 0;
|
||||||
ESP.rtcUserMemoryWrite(dump_max_len, (uint32_t*)&value, sizeof(value));
|
ESP.rtcUserMemoryWrite(crash_rtc_offset + crash_dump_max_len, (uint32_t*)&value, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* CmndCrashDump - dump the crash history - called by `Status 12`
|
* CmndCrashDump - dump the crash history - called by `Status 12`
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
|
||||||
void CrashDump(void)
|
void CrashDump(void)
|
||||||
{
|
{
|
||||||
ResponseAppend_P(PSTR("{\"call_chain\":["));
|
ResponseAppend_P(PSTR("{\"Exception\":%d,\"Reason\":\"%s\",\"EPC\":[\"%08x\",\"%08x\",\"%08x\"],\"EXCVADDR\":\"%08x\",\"DEPC\":\"%08x\""),
|
||||||
|
resetInfo.exccause, // Exception Cause
|
||||||
|
GetResetReason().c_str(), // Reset Reason
|
||||||
|
resetInfo.epc1, // Exception Progam Counter
|
||||||
|
resetInfo.epc2, // Exception Progam Counter - High-Priority Interrupt 1
|
||||||
|
resetInfo.epc3, // Exception Progam Counter - High-Priority Interrupt 2
|
||||||
|
resetInfo.excvaddr, // Exception Virtual Address Register - Virtual address that caused last fetch, load, or store exception
|
||||||
|
resetInfo.depc); // Double Exception Program Counter
|
||||||
|
|
||||||
uint32_t value;
|
uint32_t value;
|
||||||
ESP.rtcUserMemoryRead(dump_max_len, (uint32_t*)&value, sizeof(value));
|
ESP.rtcUserMemoryRead(crash_rtc_offset + crash_dump_max_len, (uint32_t*)&value, sizeof(value));
|
||||||
uint32_t count = value & 0x3F;
|
if (crash_magic == (value & 0xFFFFFF00)) {
|
||||||
|
ResponseAppend_P(PSTR(",\"CallChain\":["));
|
||||||
for (uint32_t i = 0; i < count; i++) {
|
uint32_t count = value & 0x3F;
|
||||||
ESP.rtcUserMemoryRead(i, (uint32_t*)&value, sizeof(value));
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
if (i > 0) { ResponseAppend_P(PSTR(",")); }
|
ESP.rtcUserMemoryRead(crash_rtc_offset +i, (uint32_t*)&value, sizeof(value));
|
||||||
ResponseAppend_P(PSTR("\"%08x\""), value);
|
if (i > 0) { ResponseAppend_P(PSTR(",")); }
|
||||||
|
ResponseAppend_P(PSTR("\"%08x\""), value);
|
||||||
|
}
|
||||||
|
ResponseAppend_P(PSTR("]"));
|
||||||
}
|
}
|
||||||
ResponseAppend_P(PSTR("]}"));
|
|
||||||
|
ResponseJsonEnd();
|
||||||
}
|
}
|
||||||
|
@ -555,7 +555,7 @@ void MqttConnected(void)
|
|||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"));
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "2"));
|
||||||
}
|
}
|
||||||
#endif // USE_WEBSERVER
|
#endif // USE_WEBSERVER
|
||||||
Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"), GetResetReasonInfo().c_str());
|
Response_P(PSTR("{\"" D_JSON_RESTARTREASON "\":\"%s\"}"), GetResetReason().c_str());
|
||||||
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3"));
|
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3"));
|
||||||
MqttPublishAllPowerState();
|
MqttPublishAllPowerState();
|
||||||
if (Settings.tele_period) {
|
if (Settings.tele_period) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user