Skip to content

Commit

Permalink
[Crash info] Report last scheduled task before reboot
Browse files Browse the repository at this point in the history
Just for testing/debugging purposes, the last executed task from the scheduled is logged into RTC memory.
This decoded string is also logged at boot and shown in the system info page.

It still demands quite some expertise to interpret but maybe we can find some pattern to where the crashes occur most often.
  • Loading branch information
TD-er committed Jul 13, 2019
1 parent e0b98eb commit 8d145e0
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 6 deletions.
4 changes: 3 additions & 1 deletion src/ESPEasy-Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -1694,7 +1694,7 @@ struct RTCStruct
{
RTCStruct() : ID1(0), ID2(0), unused1(false), factoryResetCounter(0),
deepSleepState(0), bootFailedCount(0), flashDayCounter(0),
flashCounter(0), bootCounter(0) {}
flashCounter(0), bootCounter(0), lastMixedSchedulerId(0) {}
byte ID1;
byte ID2;
boolean unused1;
Expand All @@ -1704,6 +1704,7 @@ struct RTCStruct
byte flashDayCounter;
unsigned long flashCounter;
unsigned long bootCounter;
unsigned long lastMixedSchedulerId;
} RTC;

int deviceCount = -1;
Expand Down Expand Up @@ -1788,6 +1789,7 @@ unsigned long createSystemEventMixedId(PluginPtrType ptr_type, uint16_t crc16);


byte lastBootCause = BOOT_CAUSE_MANUAL_REBOOT;
unsigned long lastMixedSchedulerId_beforereboot = 0;

#if defined(ESP32)
enum WiFiDisconnectReason
Expand Down
4 changes: 3 additions & 1 deletion src/ESPEasy.ino
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ void setup()
{
RTC.bootFailedCount++;
RTC.bootCounter++;
lastMixedSchedulerId_beforereboot = RTC.lastMixedSchedulerId;
readUserVarFromRTC();

if (RTC.deepSleepState == 1)
Expand All @@ -194,7 +195,8 @@ void setup()
log = F("INIT : Warm boot #");

log += RTC.bootCounter;

log += F(" Last Task: ");
log += decodeSchedulerId(lastMixedSchedulerId_beforereboot);
}
//cold boot (RTC memory empty)
else
Expand Down
2 changes: 1 addition & 1 deletion src/ESPEasy_checks.ino
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ void run_compiletime_checks() {
check_size<NotificationStruct, 3u>();
check_size<NodeStruct, 24u>();
check_size<systemTimerStruct, 28u>();
check_size<RTCStruct, 16u>();
check_size<RTCStruct, 20u>();
check_size<rulesTimerStatus, 12u>();
check_size<portStatusStruct, 4u>();
check_size<ResetFactoryDefaultPreference_struct, 4u>();
Expand Down
43 changes: 40 additions & 3 deletions src/Scheduler.ino
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,39 @@ unsigned long getMixedId(unsigned long timerType, unsigned long id) {
return (timerType << TIMER_ID_SHIFT) + id;
}

unsigned long decodeSchedulerId(unsigned long mixed_id, unsigned long& timerType) {
timerType = (mixed_id >> TIMER_ID_SHIFT);
const unsigned long mask = (1 << TIMER_ID_SHIFT) -1;
return mixed_id & mask;
}

String decodeSchedulerId(unsigned long mixed_id) {
if (mixed_id == 0) {
return F("Background Task");
}
unsigned long timerType = 0;
const unsigned long id = decodeSchedulerId(mixed_id, timerType);
String result;
result.reserve(32);
switch (timerType) {
case CONST_INTERVAL_TIMER:
result = F("Const Interval");
break;
case PLUGIN_TASK_TIMER:
result = F("Plugin Task");
break;
case TASK_DEVICE_TIMER:
result = F("Task Device");
break;
case GPIO_TIMER:
result = F("GPIO");
break;
}
result += F(" timer, id: ");
result += String(id);
return result;
}

/*********************************************************************************************\
* Handle scheduled timers.
\*********************************************************************************************/
Expand All @@ -48,6 +81,10 @@ void handle_schedule() {
// Make sure system event queue will be looked at every now and then.
mixed_id = msecTimerHandler.getNextId(timer);
}
if (RTC.lastMixedSchedulerId != mixed_id) {
RTC.lastMixedSchedulerId = mixed_id;
saveToRTC();
}
if (mixed_id == 0) {
// No id ready to run right now.
// Events are not that important to run immediately.
Expand All @@ -58,9 +95,9 @@ void handle_schedule() {
STOP_TIMER(HANDLE_SCHEDULER_IDLE);
return;
}
const unsigned long timerType = (mixed_id >> TIMER_ID_SHIFT);
const unsigned long mask = (1 << TIMER_ID_SHIFT) -1;
const unsigned long id = mixed_id & mask;

unsigned long timerType = 0;
const unsigned long id = decodeSchedulerId(mixed_id, timerType);

delay(0); // See: https://github.com/letscontrolit/ESPEasy/issues/1818#issuecomment-425351328

Expand Down
2 changes: 2 additions & 0 deletions src/StringProvider.ino
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ String getLabel(LabelType::Enum label) {
case LabelType::BOOT_TYPE: return F("Last Boot Cause");
case LabelType::BOOT_COUNT: return F("Boot Count");
case LabelType::RESET_REASON: return F("Reset Reason");
case LabelType::LAST_TASK_BEFORE_REBOOT: return F("Last Task");

case LabelType::WIFI_CONNECTION: return F("WiFi Connection");
case LabelType::WIFI_RSSI: return F("RSSI");
Expand Down Expand Up @@ -123,6 +124,7 @@ String getValue(LabelType::Enum label) {
case LabelType::BOOT_TYPE: return getLastBootCauseString();
case LabelType::BOOT_COUNT: break;
case LabelType::RESET_REASON: return getResetReasonString();
case LabelType::LAST_TASK_BEFORE_REBOOT: return decodeSchedulerId(lastMixedSchedulerId_beforereboot);

case LabelType::WIFI_CONNECTION: break;
case LabelType::WIFI_RSSI: return String(WiFi.RSSI());
Expand Down
1 change: 1 addition & 0 deletions src/StringProviderTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum Enum : short {
BOOT_TYPE, // Cold boot
BOOT_COUNT, // 0
RESET_REASON, // Software/System restart
LAST_TASK_BEFORE_REBOOT, // Last scheduled task.

WIFI_CONNECTION, // 802.11G
WIFI_RSSI, // -67
Expand Down
1 change: 1 addition & 0 deletions src/WebServer.ino
Original file line number Diff line number Diff line change
Expand Up @@ -6866,6 +6866,7 @@ void handle_sysinfo() {
TXBuffer += RTC.bootCounter;
TXBuffer += ')';
addRowLabelValue(LabelType::RESET_REASON);
addRowLabelValue(LabelType::LAST_TASK_BEFORE_REBOOT);

addTableSeparator(F("Network"), 2, 3, F("Wifi"));

Expand Down

0 comments on commit 8d145e0

Please sign in to comment.