mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-26 20:26:32 +00:00
6.1.1.14 Add boot loop detection
Add boot loop detection and try to fix
This commit is contained in:
parent
3abdaaffb7
commit
f7c38f24f3
@ -1,4 +1,7 @@
|
|||||||
/* 6.1.1.13 20180828
|
/* 6.1.1.14 20180830
|
||||||
|
* Add boot loop detection and try to fix
|
||||||
|
*
|
||||||
|
* 6.1.1.13 20180828
|
||||||
* Fix 6.1.1.12 regression of Mem and Var default handling (#3618)
|
* Fix 6.1.1.12 regression of Mem and Var default handling (#3618)
|
||||||
* Optimizations
|
* Optimizations
|
||||||
* Change define USE_ALL_SENSORS to USE_SENSORS as it doesn't contain all sensors due to duplicate I2C addresses
|
* Change define USE_ALL_SENSORS to USE_SENSORS as it doesn't contain all sensors due to duplicate I2C addresses
|
||||||
|
@ -236,6 +236,7 @@
|
|||||||
#define D_CMND_SERIALSEND "SerialSend"
|
#define D_CMND_SERIALSEND "SerialSend"
|
||||||
#define D_CMND_SERIALDELIMITER "SerialDelimiter"
|
#define D_CMND_SERIALDELIMITER "SerialDelimiter"
|
||||||
#define D_CMND_BAUDRATE "Baudrate"
|
#define D_CMND_BAUDRATE "Baudrate"
|
||||||
|
#define D_LOG_SOME_SETTINGS_RESET "Some settings have been reset"
|
||||||
|
|
||||||
// Commands xdrv_01_mqtt.ino
|
// Commands xdrv_01_mqtt.ino
|
||||||
#define D_CMND_MQTTHOST "MqttHost"
|
#define D_CMND_MQTTHOST "MqttHost"
|
||||||
|
@ -94,7 +94,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||||||
uint32_t spare28 : 1;
|
uint32_t spare28 : 1;
|
||||||
uint32_t spare29 : 1;
|
uint32_t spare29 : 1;
|
||||||
uint32_t spare30 : 1;
|
uint32_t spare30 : 1;
|
||||||
uint32_t spare31 : 1;
|
uint32_t user_esp8285_enable : 1; // bit 31 (v6.1.1.14)
|
||||||
};
|
};
|
||||||
} SysBitfield3;
|
} SysBitfield3;
|
||||||
|
|
||||||
@ -341,7 +341,10 @@ struct RTCMEM {
|
|||||||
unsigned long energy_kWhtotal; // 008
|
unsigned long energy_kWhtotal; // 008
|
||||||
unsigned long pulse_counter[MAX_COUNTERS]; // 00C
|
unsigned long pulse_counter[MAX_COUNTERS]; // 00C
|
||||||
power_t power; // 01C
|
power_t power; // 01C
|
||||||
// 020 next free location
|
uint16_t extended_valid; // 020 Extended valid flag (v6.1.1.14)
|
||||||
|
uint8_t fast_reboot_count; // 022
|
||||||
|
uint8_t free_023[57]; // 023
|
||||||
|
// 05C next free location (64 (=core) + 100 (=tasmota offset) + 92 (=0x5C RTCMEM struct) = 256 bytes (max = 512))
|
||||||
} RtcSettings;
|
} RtcSettings;
|
||||||
|
|
||||||
struct TIME_T {
|
struct TIME_T {
|
||||||
|
@ -84,6 +84,7 @@ void RtcSettingsSave()
|
|||||||
{
|
{
|
||||||
if (GetRtcSettingsCrc() != rtc_settings_crc) {
|
if (GetRtcSettingsCrc() != rtc_settings_crc) {
|
||||||
RtcSettings.valid = RTC_MEM_VALID;
|
RtcSettings.valid = RTC_MEM_VALID;
|
||||||
|
RtcSettings.extended_valid = RTC_MEM_VALID;
|
||||||
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
|
ESP.rtcUserMemoryWrite(100, (uint32_t*)&RtcSettings, sizeof(RTCMEM));
|
||||||
rtc_settings_crc = GetRtcSettingsCrc();
|
rtc_settings_crc = GetRtcSettingsCrc();
|
||||||
#ifdef DEBUG_THEO
|
#ifdef DEBUG_THEO
|
||||||
@ -103,12 +104,14 @@ void RtcSettingsLoad()
|
|||||||
if (RtcSettings.valid != RTC_MEM_VALID) {
|
if (RtcSettings.valid != RTC_MEM_VALID) {
|
||||||
memset(&RtcSettings, 0, sizeof(RTCMEM));
|
memset(&RtcSettings, 0, sizeof(RTCMEM));
|
||||||
RtcSettings.valid = RTC_MEM_VALID;
|
RtcSettings.valid = RTC_MEM_VALID;
|
||||||
|
RtcSettings.extended_valid = RTC_MEM_VALID;
|
||||||
RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday;
|
RtcSettings.energy_kWhtoday = Settings.energy_kWhtoday;
|
||||||
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
|
RtcSettings.energy_kWhtotal = Settings.energy_kWhtotal;
|
||||||
for (byte i = 0; i < MAX_COUNTERS; i++) {
|
for (byte i = 0; i < MAX_COUNTERS; i++) {
|
||||||
RtcSettings.pulse_counter[i] = Settings.pulse_counter[i];
|
RtcSettings.pulse_counter[i] = Settings.pulse_counter[i];
|
||||||
}
|
}
|
||||||
RtcSettings.power = Settings.power;
|
RtcSettings.power = Settings.power;
|
||||||
|
// RtcSettings.fast_reboot_count = 0; // Explicit by memset
|
||||||
RtcSettingsSave();
|
RtcSettingsSave();
|
||||||
}
|
}
|
||||||
rtc_settings_crc = GetRtcSettingsCrc();
|
rtc_settings_crc = GetRtcSettingsCrc();
|
||||||
@ -119,6 +122,11 @@ boolean RtcSettingsValid()
|
|||||||
return (RTC_MEM_VALID == RtcSettings.valid);
|
return (RTC_MEM_VALID == RtcSettings.valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean RtcSettingsExtendedValid()
|
||||||
|
{
|
||||||
|
return (RTC_MEM_VALID == RtcSettings.extended_valid);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Config - Flash
|
* Config - Flash
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -85,6 +85,7 @@ typedef unsigned long power_t; // Power (Relay) type
|
|||||||
|
|
||||||
#define STATES 20 // Number of states per second using 50 mSec interval
|
#define STATES 20 // Number of states per second using 50 mSec interval
|
||||||
#define IMMINENT_RESET_FACTOR 10 // Factor to extent button hold time for imminent Reset to default 40 seconds using KEY_HOLD_TIME of 40
|
#define IMMINENT_RESET_FACTOR 10 // Factor to extent button hold time for imminent Reset to default 40 seconds using KEY_HOLD_TIME of 40
|
||||||
|
#define BOOT_LOOP_TIME 10 // Number of seconds to stop detecting boot loops
|
||||||
#define SYSLOG_TIMER 600 // Seconds to restore syslog_level
|
#define SYSLOG_TIMER 600 // Seconds to restore syslog_level
|
||||||
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
|
#define SERIALLOG_TIMER 600 // Seconds to disable SerialLog
|
||||||
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
|
#define OTA_ATTEMPTS 5 // Number of times to try fetching the new firmware
|
||||||
|
@ -1567,6 +1567,11 @@ void PerformEverySecond()
|
|||||||
{
|
{
|
||||||
uptime++;
|
uptime++;
|
||||||
|
|
||||||
|
if (BOOT_LOOP_TIME == uptime) {
|
||||||
|
RtcSettings.fast_reboot_count = 0;
|
||||||
|
RtcSettingsSave();
|
||||||
|
}
|
||||||
|
|
||||||
if ((4 == uptime) && (SONOFF_IFAN02 == Settings.module)) { // Microcontroller needs 3 seconds before accepting commands
|
if ((4 == uptime) && (SONOFF_IFAN02 == Settings.module)) { // Microcontroller needs 3 seconds before accepting commands
|
||||||
SetDevicePower(1, SRC_RETRY); // Sync with default power on state microcontroller being Light ON and Fan OFF
|
SetDevicePower(1, SRC_RETRY); // Sync with default power on state microcontroller being Light ON and Fan OFF
|
||||||
SetDevicePower(power, SRC_RETRY); // Set required power on state
|
SetDevicePower(power, SRC_RETRY); // Set required power on state
|
||||||
@ -2313,7 +2318,7 @@ void GpioInit()
|
|||||||
pin[i] = 99;
|
pin[i] = 99;
|
||||||
}
|
}
|
||||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||||
mpin = my_module.gp.io[i];
|
mpin = ValidGPIO(i, my_module.gp.io[i]);
|
||||||
|
|
||||||
// snprintf_P(log_data, sizeof(log_data), PSTR("DBG: gpio pin %d, mpin %d"), i, mpin);
|
// snprintf_P(log_data, sizeof(log_data), PSTR("DBG: gpio pin %d, mpin %d"), i, mpin);
|
||||||
// AddLog(LOG_LEVEL_DEBUG);
|
// AddLog(LOG_LEVEL_DEBUG);
|
||||||
@ -2323,7 +2328,7 @@ void GpioInit()
|
|||||||
bitSet(switch_no_pullup, mpin - GPIO_SWT1_NP);
|
bitSet(switch_no_pullup, mpin - GPIO_SWT1_NP);
|
||||||
mpin -= (GPIO_SWT1_NP - GPIO_SWT1);
|
mpin -= (GPIO_SWT1_NP - GPIO_SWT1);
|
||||||
}
|
}
|
||||||
if ((mpin >= GPIO_KEY1_NP) && (mpin < (GPIO_KEY1_NP + MAX_KEYS))) {
|
else if ((mpin >= GPIO_KEY1_NP) && (mpin < (GPIO_KEY1_NP + MAX_KEYS))) {
|
||||||
bitSet(key_no_pullup, mpin - GPIO_KEY1_NP);
|
bitSet(key_no_pullup, mpin - GPIO_KEY1_NP);
|
||||||
mpin -= (GPIO_KEY1_NP - GPIO_KEY1);
|
mpin -= (GPIO_KEY1_NP - GPIO_KEY1);
|
||||||
}
|
}
|
||||||
@ -2486,6 +2491,11 @@ void setup()
|
|||||||
{
|
{
|
||||||
byte idx;
|
byte idx;
|
||||||
|
|
||||||
|
RtcSettingsLoad();
|
||||||
|
if (!RtcSettingsExtendedValid()) { RtcSettings.fast_reboot_count = 0; }
|
||||||
|
RtcSettings.fast_reboot_count++;
|
||||||
|
RtcSettingsSave();
|
||||||
|
|
||||||
Serial.begin(baudrate);
|
Serial.begin(baudrate);
|
||||||
delay(10);
|
delay(10);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
@ -2517,10 +2527,25 @@ void setup()
|
|||||||
save_data_counter = Settings.save_data;
|
save_data_counter = Settings.save_data;
|
||||||
sleep = Settings.sleep;
|
sleep = Settings.sleep;
|
||||||
|
|
||||||
if ((resetInfo.reason == REASON_WDT_RST) || (resetInfo.reason == REASON_EXCEPTION_RST) || (resetInfo.reason == REASON_SOFT_WDT_RST) || OsWatchBlockedLoop()) {
|
// Disable functionality as possible cause of fast reboot within BOOT_LOOP_TIME seconds (Exception or WDT)
|
||||||
for (byte i = 0; i < MAX_RULE_SETS; i++) {
|
if (RtcSettings.fast_reboot_count > 1) { // Restart twice
|
||||||
if (bitRead(Settings.rule_stop, i)) { bitWrite(Settings.rule_enabled, i, 0); }
|
Settings.flag3.user_esp8285_enable = 0; // Disable ESP8285 Generic GPIOs interfering with flash SPI
|
||||||
|
if (RtcSettings.fast_reboot_count > 2) { // Restart 3 times
|
||||||
|
for (byte i = 0; i < MAX_RULE_SETS; i++) {
|
||||||
|
if (bitRead(Settings.rule_stop, i)) {
|
||||||
|
bitWrite(Settings.rule_enabled, i, 0); // Disable rules causing boot loop
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (RtcSettings.fast_reboot_count > 3) { // Restarted 4 times
|
||||||
|
Settings.rule_enabled = 0; // Disable all rules
|
||||||
|
}
|
||||||
|
if (RtcSettings.fast_reboot_count > 4) { // Restarted 5 times
|
||||||
|
Settings.module = SONOFF_BASIC; // Use default module
|
||||||
|
Settings.last_module = SONOFF_BASIC; // Use default module
|
||||||
|
}
|
||||||
|
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION D_LOG_SOME_SETTINGS_RESET " (%d)"), RtcSettings.fast_reboot_count);
|
||||||
|
AddLog(LOG_LEVEL_DEBUG);
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings.bootcount++;
|
Settings.bootcount++;
|
||||||
|
@ -226,7 +226,7 @@ enum SupportedModules {
|
|||||||
|
|
||||||
#define MAX_GPIO_PIN 18 // Number of supported GPIO
|
#define MAX_GPIO_PIN 18 // Number of supported GPIO
|
||||||
|
|
||||||
const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcontrolD6D7D5D8D0A0";
|
const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcFLFLolD6D7D5D8D0A0";
|
||||||
|
|
||||||
typedef struct MYIO {
|
typedef struct MYIO {
|
||||||
uint8_t io[MAX_GPIO_PIN];
|
uint8_t io[MAX_GPIO_PIN];
|
||||||
@ -514,7 +514,10 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
|||||||
GPIO_USER, // GPIO03 RX Serial TXD and Optional sensor
|
GPIO_USER, // GPIO03 RX Serial TXD and Optional sensor
|
||||||
GPIO_USER, // GPIO04 D2 Wemos I2C SDA
|
GPIO_USER, // GPIO04 D2 Wemos I2C SDA
|
||||||
GPIO_USER, // GPIO05 D1 Wemos I2C SCL / Wemos Relay Shield (0 = Off, 1 = On) / Wemos WS2812B RGB led Shield
|
GPIO_USER, // GPIO05 D1 Wemos I2C SCL / Wemos Relay Shield (0 = Off, 1 = On) / Wemos WS2812B RGB led Shield
|
||||||
0, 0, 0, 0, 0, 0, // Flash connection
|
0, 0, 0, // Flash connection
|
||||||
|
GPIO_USER, // Flash connection or GPIO09 on ESP8285 only!
|
||||||
|
GPIO_USER, // Flash connection or GPIO10 on ESP8285 only!
|
||||||
|
0, // Flash connection
|
||||||
GPIO_USER, // GPIO12 D6
|
GPIO_USER, // GPIO12 D6
|
||||||
GPIO_USER, // GPIO13 D7
|
GPIO_USER, // GPIO13 D7
|
||||||
GPIO_USER, // GPIO14 D5
|
GPIO_USER, // GPIO14 D5
|
||||||
@ -987,6 +990,27 @@ const mytmplt kModules[MAXMODULE] PROGMEM = {
|
|||||||
0 // ADC0 Analog input (A0)
|
0 // ADC0 Analog input (A0)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ "Shelly 1", // Shelly1 Open Source (ESP8266 - 2MB) - https://shelly.cloud/shelly1-open-source/
|
||||||
|
GPIO_KEY1, // GPIO00 Button
|
||||||
|
GPIO_USER, // GPIO01 Serial RXD and Optional sensor
|
||||||
|
0,
|
||||||
|
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
|
||||||
|
GPIO_REL1, // GPIO04 Relay (0 = Off, 1 = On)
|
||||||
|
GPIO_SWT1_NP, // GPIO05 Switch
|
||||||
|
0, 0, 0, 0, 0, 0, // Flash connection
|
||||||
|
0, 0, 0, 0, 0, 0
|
||||||
|
},
|
||||||
|
{ "Shelly 2", // Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/
|
||||||
|
// As Gnd is connected to AC no user GPIO allowed
|
||||||
|
0, 0, 0, 0,
|
||||||
|
GPIO_REL1, // GPIO04 Relay 1 (0 = Off, 1 = On)
|
||||||
|
GPIO_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On)
|
||||||
|
0, 0, 0, 0, 0, 0, // Flash connection
|
||||||
|
GPIO_SWT1_NP, // GPIO12 Switch 1
|
||||||
|
0,
|
||||||
|
GPIO_SWT2_NP, // GPIO14 Switch 2
|
||||||
|
0, 0, 0
|
||||||
|
},
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#endif // _SONOFF_TEMPLATE_H_
|
#endif // _SONOFF_TEMPLATE_H_
|
@ -20,7 +20,7 @@
|
|||||||
#ifndef _SONOFF_VERSION_H_
|
#ifndef _SONOFF_VERSION_H_
|
||||||
#define _SONOFF_VERSION_H_
|
#define _SONOFF_VERSION_H_
|
||||||
|
|
||||||
#define VERSION 0x0601010D
|
#define VERSION 0x0601010E
|
||||||
|
|
||||||
#define D_PROGRAMNAME "Sonoff-Tasmota"
|
#define D_PROGRAMNAME "Sonoff-Tasmota"
|
||||||
#define D_AUTHOR "Theo Arends"
|
#define D_AUTHOR "Theo Arends"
|
||||||
|
@ -717,6 +717,15 @@ void ShowSource(int source)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t ValidGPIO(uint8_t pin, uint8_t gpio)
|
||||||
|
{
|
||||||
|
uint8_t result = gpio;
|
||||||
|
if ((WEMOS == Settings.module) && (!Settings.flag3.user_esp8285_enable)) {
|
||||||
|
if ((pin == 9) || (pin == 10)) { result = GPIO_NONE; } // Disable possible flash GPIO9 and GPIO10
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* Sleep aware time scheduler functions borrowed from ESPEasy
|
* Sleep aware time scheduler functions borrowed from ESPEasy
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
|
@ -789,7 +789,7 @@ void HandleModuleConfiguration()
|
|||||||
page += FPSTR(HTTP_SCRIPT_MODULE3);
|
page += FPSTR(HTTP_SCRIPT_MODULE3);
|
||||||
|
|
||||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) {
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("sk(%d,%d);"), my_module.gp.io[i], i); // g0 - g16
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("sk(%d,%d);"), my_module.gp.io[i], i); // g0 - g16
|
||||||
page += mqtt_data;
|
page += mqtt_data;
|
||||||
}
|
}
|
||||||
@ -803,10 +803,10 @@ void HandleModuleConfiguration()
|
|||||||
page.replace(F("{mt"), stemp);
|
page.replace(F("{mt"), stemp);
|
||||||
page += F("<br/><table>");
|
page += F("<br/><table>");
|
||||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||||
if (GPIO_USER == cmodule.gp.io[i]) {
|
if (GPIO_USER == ValidGPIO(i, cmodule.gp.io[i])) {
|
||||||
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
snprintf_P(stemp, 3, PINS_WEMOS +i*2);
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:146px'><select id='g%d' name='g%d'></select></td></tr>"),
|
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("<tr><td style='width:190px'>%s <b>" D_GPIO "%d</b> %s</td><td style='width:146px'><select id='g%d' name='g%d'></select></td></tr>"),
|
||||||
(WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
(WEMOS==Settings.module)?stemp:"", i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(9==i)? "<font color='red'>ESP8285</font>" :(10==i)? "<font color='red'>ESP8285</font>" :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1i":(14==i)? D_SENSOR :"", i, i);
|
||||||
page += mqtt_data;
|
page += mqtt_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -457,7 +457,7 @@ boolean TimerCommand()
|
|||||||
}
|
}
|
||||||
if (XdrvMailbox.payload == 2) {
|
if (XdrvMailbox.payload == 2) {
|
||||||
Settings.flag3.timers_enable = !Settings.flag3.timers_enable;
|
Settings.flag3.timers_enable = !Settings.flag3.timers_enable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag3.timers_enable));
|
snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag3.timers_enable));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user