mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
improved crash detection
This commit is contained in:
@@ -8,9 +8,19 @@
|
||||
|
||||
#include "MyESP.h"
|
||||
|
||||
#ifdef CRASH
|
||||
EEPROM_Rotate EEPROMr;
|
||||
#endif
|
||||
|
||||
union system_rtcmem_t {
|
||||
struct {
|
||||
uint8_t stability_counter;
|
||||
uint8_t reset_reason;
|
||||
uint16_t _reserved_;
|
||||
} parts;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
uint8_t RtcmemSize = (sizeof(RtcmemData) / 4u);
|
||||
auto Rtcmem = reinterpret_cast<volatile RtcmemData *>(RTCMEM_ADDR);
|
||||
|
||||
// constructor
|
||||
MyESP::MyESP() {
|
||||
@@ -57,6 +67,9 @@ MyESP::MyESP() {
|
||||
_ota_post_callback = NULL;
|
||||
|
||||
_suspendOutput = false;
|
||||
|
||||
_rtcmem_status = false;
|
||||
_systemStable = true;
|
||||
}
|
||||
|
||||
MyESP::~MyESP() {
|
||||
@@ -361,7 +374,6 @@ void MyESP::setOTA(ota_callback_f OTACallback_pre, ota_callback_f OTACallback_po
|
||||
void MyESP::_OTACallback() {
|
||||
myDebug_P(PSTR("[OTA] Start"));
|
||||
|
||||
#ifdef CRASH
|
||||
// If we are not specifically reserving the sectors we are using as
|
||||
// EEPROM in the memory layout then any OTA upgrade will overwrite
|
||||
// all but the last one.
|
||||
@@ -374,7 +386,6 @@ void MyESP::_OTACallback() {
|
||||
// See onError callback below.
|
||||
EEPROMr.rotate(false);
|
||||
EEPROMr.commit();
|
||||
#endif
|
||||
|
||||
if (_ota_pre_callback) {
|
||||
(_ota_pre_callback)(); // call custom function
|
||||
@@ -391,7 +402,11 @@ void MyESP::_ota_setup() {
|
||||
ArduinoOTA.setHostname(_app_hostname);
|
||||
|
||||
ArduinoOTA.onStart([this]() { _OTACallback(); });
|
||||
ArduinoOTA.onEnd([this]() { myDebug_P(PSTR("[OTA] Done, restarting...")); });
|
||||
ArduinoOTA.onEnd([this]() {
|
||||
myDebug_P(PSTR("[OTA] Done, restarting..."));
|
||||
_deferredReset(100, CUSTOM_RESET_OTA);
|
||||
});
|
||||
|
||||
ArduinoOTA.onProgress([this](unsigned int progress, unsigned int total) {
|
||||
static unsigned int _progOld;
|
||||
unsigned int _prog = (progress / (total / 100));
|
||||
@@ -413,10 +428,8 @@ void MyESP::_ota_setup() {
|
||||
else if (error == OTA_END_ERROR)
|
||||
myDebug_P(PSTR("[OTA] End Failed"));
|
||||
|
||||
#ifdef CRASH
|
||||
// There's been an error, reenable rotation
|
||||
EEPROMr.rotate(true);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
@@ -430,10 +443,8 @@ void MyESP::setBoottime(const char * boottime) {
|
||||
|
||||
// eeprom
|
||||
void MyESP::_eeprom_setup() {
|
||||
#ifdef CRASH
|
||||
EEPROMr.size(4);
|
||||
EEPROMr.begin(SPI_FLASH_SEC_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set callback of sketch function to process project messages
|
||||
@@ -449,7 +460,6 @@ void MyESP::_telnetConnected() {
|
||||
_consoleShowHelp(); // Show the initial message
|
||||
|
||||
// show crash dump if just restarted after a fatal crash
|
||||
#ifdef CRASH
|
||||
uint32_t crash_time;
|
||||
EEPROMr.get(SAVE_CRASH_EEPROM_OFFSET + SAVE_CRASH_CRASH_TIME, crash_time);
|
||||
if ((crash_time != 0) && (crash_time != 0xFFFFFFFF)) {
|
||||
@@ -461,7 +471,6 @@ void MyESP::_telnetConnected() {
|
||||
EEPROMr.commit();
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
// call callback
|
||||
if (_telnet_callback) {
|
||||
@@ -505,9 +514,7 @@ void MyESP::_consoleShowHelp() {
|
||||
myDebug_P(PSTR("* Commands:"));
|
||||
myDebug_P(PSTR("* ?=help, CTRL-D/quit=exit telnet session"));
|
||||
myDebug_P(PSTR("* set, system, reboot"));
|
||||
#ifdef CRASH
|
||||
myDebug_P(PSTR("* crash <dump | clear>"));
|
||||
#endif
|
||||
|
||||
// print custom commands if available. Taken from progmem
|
||||
if (_telnetcommand_callback) {
|
||||
@@ -601,6 +608,7 @@ void MyESP::_printSetCommands() {
|
||||
// reset / restart
|
||||
void MyESP::resetESP() {
|
||||
myDebug_P(PSTR("* Reboot ESP..."));
|
||||
_deferredReset(100, CUSTOM_RESET_TERMINAL);
|
||||
end();
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ESP.restart();
|
||||
@@ -792,8 +800,7 @@ void MyESP::_telnetCommand(char * commandLine) {
|
||||
}
|
||||
|
||||
|
||||
// crash command
|
||||
#ifdef CRASH
|
||||
// crash command
|
||||
if ((strcmp(ptrToCommandName, "crash") == 0) && (wc == 2)) {
|
||||
char * cmd = _telnet_readWord(false);
|
||||
if (strcmp(cmd, "dump") == 0) {
|
||||
@@ -805,7 +812,6 @@ void MyESP::_telnetCommand(char * commandLine) {
|
||||
}
|
||||
return; // don't call custom command line callback
|
||||
}
|
||||
#endif
|
||||
|
||||
// call callback function
|
||||
(_telnetcommand_callback)(wc, commandLine);
|
||||
@@ -864,6 +870,137 @@ unsigned long MyESP::_getUptime() {
|
||||
return uptime_seconds;
|
||||
}
|
||||
|
||||
// reason code
|
||||
void MyESP::_rtcmemInit() {
|
||||
memset((uint32_t *)RTCMEM_ADDR, 0, sizeof(uint32_t) * RTCMEM_BLOCKS);
|
||||
Rtcmem->magic = RTCMEM_MAGIC;
|
||||
}
|
||||
|
||||
uint8_t MyESP::_getSystemStabilityCounter() {
|
||||
system_rtcmem_t data;
|
||||
data.value = Rtcmem->sys;
|
||||
return data.parts.stability_counter;
|
||||
}
|
||||
|
||||
void MyESP::_setSystemStabilityCounter(uint8_t counter) {
|
||||
system_rtcmem_t data;
|
||||
data.value = Rtcmem->sys;
|
||||
data.parts.stability_counter = counter;
|
||||
Rtcmem->sys = data.value;
|
||||
}
|
||||
|
||||
uint8_t MyESP::_getSystemResetReason() {
|
||||
system_rtcmem_t data;
|
||||
data.value = Rtcmem->sys;
|
||||
return data.parts.reset_reason;
|
||||
}
|
||||
|
||||
void MyESP::_setSystemResetReason(uint8_t reason) {
|
||||
system_rtcmem_t data;
|
||||
data.value = Rtcmem->sys;
|
||||
data.parts.reset_reason = reason;
|
||||
Rtcmem->sys = data.value;
|
||||
}
|
||||
|
||||
uint32_t MyESP::getSystemResetReason() {
|
||||
return resetInfo.reason;
|
||||
}
|
||||
|
||||
void MyESP::_rtcmemSetup() {
|
||||
_rtcmem_status = _rtcmemStatus();
|
||||
if (!_rtcmem_status) {
|
||||
_rtcmemInit();
|
||||
}
|
||||
}
|
||||
|
||||
void MyESP::_setCustomResetReason(uint8_t reason) {
|
||||
_setSystemResetReason(reason);
|
||||
}
|
||||
|
||||
// Treat memory as dirty on cold boot, hardware wdt reset and rst pin
|
||||
bool MyESP::_rtcmemStatus() {
|
||||
bool readable;
|
||||
|
||||
switch (getSystemResetReason()) {
|
||||
case REASON_EXT_SYS_RST:
|
||||
case REASON_WDT_RST:
|
||||
case REASON_DEFAULT_RST:
|
||||
readable = false;
|
||||
break;
|
||||
default:
|
||||
readable = true;
|
||||
}
|
||||
|
||||
readable = readable and (RTCMEM_MAGIC == Rtcmem->magic);
|
||||
|
||||
return readable;
|
||||
}
|
||||
|
||||
bool MyESP::rtcmemStatus() {
|
||||
return _rtcmem_status;
|
||||
}
|
||||
|
||||
unsigned char MyESP::_getCustomResetReason() {
|
||||
static unsigned char status = 255;
|
||||
if (status == 255) {
|
||||
if (_rtcmemStatus())
|
||||
status = _getSystemResetReason();
|
||||
if (status > 0)
|
||||
_setCustomResetReason(0);
|
||||
if (status > CUSTOM_RESET_MAX)
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void MyESP::_deferredReset(unsigned long delaytime, unsigned char reason) {
|
||||
delay(delaytime);
|
||||
_setCustomResetReason(reason);
|
||||
}
|
||||
|
||||
// Call this method on boot with start=true to increase the crash counter
|
||||
// Call it again once the system is stable to decrease the counter
|
||||
// If the counter reaches SYSTEM_CHECK_MAX then the system is flagged as unstable
|
||||
// setting _systemOK = false;
|
||||
//
|
||||
// An unstable system will only have serial access, WiFi in AP mode and OTA
|
||||
void MyESP::_setSystemCheck(bool stable) {
|
||||
uint8_t value = 0;
|
||||
|
||||
if (stable) {
|
||||
value = 0; // system is ok
|
||||
// myDebug_P(PSTR("[SYSTEM] System OK\n"));
|
||||
} else {
|
||||
if (!rtcmemStatus()) {
|
||||
_setSystemStabilityCounter(1);
|
||||
return;
|
||||
}
|
||||
|
||||
value = _getSystemStabilityCounter();
|
||||
|
||||
if (++value > SYSTEM_CHECK_MAX) {
|
||||
_systemStable = false;
|
||||
value = 0; // system is unstable
|
||||
myDebug_P(PSTR("[SYSTEM] Warning, system UNSTABLE\n"));
|
||||
}
|
||||
}
|
||||
|
||||
_setSystemStabilityCounter(value);
|
||||
}
|
||||
|
||||
bool MyESP::getSystemCheck() {
|
||||
return _systemStable;
|
||||
}
|
||||
|
||||
void MyESP::_systemCheckLoop() {
|
||||
static bool checked = false;
|
||||
if (!checked && (millis() > SYSTEM_CHECK_TIME)) {
|
||||
_setSystemCheck(true); // Flag system as stable
|
||||
checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// print out ESP system stats
|
||||
// for battery power is ESP.getVcc()
|
||||
void MyESP::showSystemStats() {
|
||||
@@ -892,6 +1029,10 @@ void MyESP::showSystemStats() {
|
||||
|
||||
myDebug_P(PSTR(" [APP] System Load: %d%%"), getSystemLoadAverage());
|
||||
|
||||
if (!getSystemCheck()) {
|
||||
myDebug_P(PSTR(" [SYSTEM] Device is in SAFE MODE"));
|
||||
}
|
||||
|
||||
if (isAPmode()) {
|
||||
myDebug_P(PSTR(" [WIFI] Device is in AP mode with SSID %s"), jw.getAPSSID().c_str());
|
||||
} else {
|
||||
@@ -902,7 +1043,6 @@ void MyESP::showSystemStats() {
|
||||
|
||||
myDebug_P(PSTR(" [WIFI] WiFi MAC: %s"), WiFi.macAddress().c_str());
|
||||
|
||||
#ifdef CRASH
|
||||
char output_str[80] = {0};
|
||||
char buffer[16] = {0};
|
||||
myDebug_P(PSTR(" [EEPROM] EEPROM size: %u"), EEPROMr.reserved() * SPI_FLASH_SEC_SIZE);
|
||||
@@ -914,7 +1054,6 @@ void MyESP::showSystemStats() {
|
||||
strlcat(output_str, " ", sizeof(output_str));
|
||||
}
|
||||
myDebug(output_str);
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_BOARD
|
||||
myDebug_P(PSTR(" [SYSTEM] Board: %s"), ARDUINO_BOARD);
|
||||
@@ -929,6 +1068,21 @@ void MyESP::showSystemStats() {
|
||||
myDebug_P(PSTR(" [SYSTEM] Boot version: %d"), ESP.getBootVersion());
|
||||
myDebug_P(PSTR(" [SYSTEM] Boot mode: %d"), ESP.getBootMode());
|
||||
//myDebug_P(PSTR("[SYSTEM] Firmware MD5: %s"), (char *)ESP.getSketchMD5().c_str());
|
||||
unsigned char reason = _getCustomResetReason();
|
||||
if (reason > 0) {
|
||||
char buffer[32];
|
||||
strcpy_P(buffer, custom_reset_string[reason - 1]);
|
||||
myDebug_P(PSTR(" [SYSTEM] Last reset reason: %s"), buffer);
|
||||
} else {
|
||||
myDebug_P(PSTR(" [SYSTEM] Last reset reason: %s"), (char *)ESP.getResetReason().c_str());
|
||||
myDebug_P(PSTR(" [SYSTEM] Last reset info: %s"), (char *)ESP.getResetInfo().c_str());
|
||||
}
|
||||
myDebug_P(PSTR(" [SYSTEM] Restart count: %d"), _getSystemStabilityCounter());
|
||||
|
||||
myDebug_P(PSTR(" [SYSTEM] rtcmem status:%u blocks:%u addr:0x%p"), _rtcmemStatus(), RtcmemSize, Rtcmem);
|
||||
for (uint8_t block = 0; block < RtcmemSize; ++block) {
|
||||
myDebug_P(PSTR(" [SYSTEM] rtcmem %02u: %u"), block, reinterpret_cast<volatile uint32_t *>(RTCMEM_ADDR)[block]);
|
||||
}
|
||||
#endif
|
||||
|
||||
FlashMode_t mode = ESP.getFlashChipMode();
|
||||
@@ -942,10 +1096,10 @@ void MyESP::showSystemStats() {
|
||||
#endif
|
||||
myDebug_P(PSTR(" [FLASH] Flash size (SDK): %d"), ESP.getFlashChipSize());
|
||||
myDebug_P(PSTR(" [FLASH] Flash Reserved: %d"), 1 * SPI_FLASH_SEC_SIZE);
|
||||
myDebug_P(PSTR(" [MEM] Firmware size: %d"), ESP.getSketchSize());
|
||||
//myDebug_P(PSTR(" [MEM] Firmware size: %d"), ESP.getSketchSize()); // TODO: commented out because it causes a crash with 2.5.2
|
||||
myDebug_P(PSTR(" [MEM] Max OTA size: %d"), (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
||||
myDebug_P(PSTR(" [MEM] OTA Reserved: %d"), 4 * SPI_FLASH_SEC_SIZE);
|
||||
//myDebug_P(PSTR(" [MEM] Free Heap: %d"), ESP.getFreeHeap());
|
||||
myDebug_P(PSTR(" [MEM] Free Heap: %d"), ESP.getFreeHeap());
|
||||
myDebug_P(PSTR(""));
|
||||
}
|
||||
|
||||
@@ -1385,7 +1539,6 @@ int MyESP::getWifiQuality() {
|
||||
return 2 * (dBm + 100);
|
||||
}
|
||||
|
||||
#ifdef CRASH
|
||||
/**
|
||||
* Save crash information in EEPROM
|
||||
* This function is called automatically if ESP8266 suffers an exception
|
||||
@@ -1534,14 +1687,6 @@ void MyESP::crashDump() {
|
||||
myDebug_P(PSTR("<<<stack<<<"));
|
||||
myDebug_P(PSTR("\nTo clean this dump use the command: %scrash clear%s\n"), COLOR_BOLD_ON, COLOR_BOLD_OFF);
|
||||
}
|
||||
#else
|
||||
void MyESP::crashClear() {
|
||||
}
|
||||
void MyESP::crashDump() {
|
||||
}
|
||||
void MyESP::crashInfo() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// setup MyESP
|
||||
void MyESP::begin(const char * app_hostname, const char * app_name, const char * app_version) {
|
||||
@@ -1549,6 +1694,7 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char *
|
||||
_app_name = strdup(app_name);
|
||||
_app_version = strdup(app_version);
|
||||
|
||||
_rtcmemSetup();
|
||||
_telnet_setup(); // Telnet setup, called first to set Serial
|
||||
_eeprom_setup(); // set up eeprom for storing crash data, if compiled with -DCRASH
|
||||
_fs_setup(); // SPIFFS setup, do this first to get values
|
||||
@@ -1558,6 +1704,8 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char *
|
||||
// print a welcome message
|
||||
myDebug_P(PSTR("\n* %s version %s"), _app_name, _app_version);
|
||||
SerialAndTelnet.flush();
|
||||
|
||||
_setSystemCheck(false); // reset system check
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1565,17 +1713,12 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char *
|
||||
*/
|
||||
void MyESP::loop() {
|
||||
_calculateLoad();
|
||||
_systemCheckLoop();
|
||||
|
||||
_telnetHandle();
|
||||
|
||||
jw.loop(); // WiFi
|
||||
|
||||
/*
|
||||
// do nothing else until we've got a wifi connection
|
||||
if (WiFi.getMode() & WIFI_AP) {
|
||||
return;
|
||||
}
|
||||
*/
|
||||
|
||||
ArduinoOTA.handle(); // OTA
|
||||
_mqttConnect(); // MQTT
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef MyEMS_h
|
||||
#define MyEMS_h
|
||||
|
||||
#define MYESP_VERSION "1.1.13"
|
||||
#define MYESP_VERSION "1.1.14"
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <ArduinoOTA.h>
|
||||
@@ -18,13 +18,14 @@
|
||||
#include <FS.h>
|
||||
#include <JustWifi.h> // https://github.com/xoseperez/justwifi
|
||||
#include <TelnetSpy.h> // modified from https://github.com/yasheena/telnetspy
|
||||
#include <Ticker.h>
|
||||
|
||||
#ifdef CRASH
|
||||
#include <EEPROM_Rotate.h>
|
||||
extern "C" {
|
||||
void custom_crash_callback(struct rst_info *, uint32_t, uint32_t);
|
||||
#include "user_interface.h"
|
||||
void custom_crash_callback(struct rst_info *, uint32_t, uint32_t);
|
||||
extern struct rst_info resetInfo;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
//#include <ESPmDNS.h>
|
||||
@@ -86,6 +87,18 @@ void custom_crash_callback(struct rst_info *, uint32_t, uint32_t);
|
||||
#define COLOR_BRIGHT_CYAN "\x1B[0;96m"
|
||||
#define COLOR_BRIGHT_WHITE "\x1B[0;97m"
|
||||
|
||||
// reset reason codes
|
||||
PROGMEM const char custom_reset_hardware[] = "Hardware button";
|
||||
PROGMEM const char custom_reset_terminal[] = "Reboot from terminal";
|
||||
PROGMEM const char custom_reset_mqtt[] = "Reboot from MQTT";
|
||||
PROGMEM const char custom_reset_ota[] = "Reboot after successful OTA update";
|
||||
PROGMEM const char * const custom_reset_string[] = {custom_reset_hardware, custom_reset_terminal, custom_reset_mqtt, custom_reset_ota};
|
||||
#define CUSTOM_RESET_HARDWARE 1 // Reset from hardware button
|
||||
#define CUSTOM_RESET_TERMINAL 2 // Reset from terminal
|
||||
#define CUSTOM_RESET_MQTT 3 // Reset via MQTT
|
||||
#define CUSTOM_RESET_OTA 4 // Reset after successful OTA update
|
||||
#define CUSTOM_RESET_MAX 4
|
||||
|
||||
// SPIFFS
|
||||
#define SPIFFS_MAXSIZE 800 // https://arduinojson.org/v6/assistant/
|
||||
|
||||
@@ -119,6 +132,30 @@ void custom_crash_callback(struct rst_info *, uint32_t, uint32_t);
|
||||
#define SAVE_CRASH_STACK_END 0x1E // 4 bytes
|
||||
#define SAVE_CRASH_STACK_TRACE 0x22 // variable
|
||||
|
||||
// Base address of USER RTC memory
|
||||
// https://github.com/esp8266/esp8266-wiki/wiki/Memory-Map#memmory-mapped-io-registers
|
||||
#define RTCMEM_ADDR_BASE (0x60001200)
|
||||
|
||||
// RTC memory is accessed using blocks of 4 bytes.
|
||||
// Blocks 0..63 are reserved by the SDK, 64..192 are available to the user.
|
||||
// Blocks 64..96 are reserved by the eboot 'struct eboot_command' (128 -> (128 / 4) -> 32):
|
||||
// https://github.com/esp8266/Arduino/blob/master/bootloaders/eboot/eboot_command.h
|
||||
#define RTCMEM_OFFSET 32u
|
||||
#define RTCMEM_ADDR (RTCMEM_ADDR_BASE + (RTCMEM_OFFSET * 4u))
|
||||
#define RTCMEM_BLOCKS 96u
|
||||
#define RTCMEM_MAGIC 0x45535075
|
||||
|
||||
struct RtcmemData {
|
||||
uint32_t magic; // RTCMEM_MAGIC
|
||||
uint32_t sys; // system reset reason (1-4)
|
||||
uint32_t energy; // store energy count
|
||||
};
|
||||
|
||||
static_assert(sizeof(RtcmemData) <= (RTCMEM_BLOCKS * 4u), "RTCMEM struct is too big");
|
||||
|
||||
#define SYSTEM_CHECK_TIME 60000 // The system is considered stable after these many millis
|
||||
#define SYSTEM_CHECK_MAX 5 // After this many crashes on boot
|
||||
|
||||
typedef struct {
|
||||
bool set; // is it a set command
|
||||
char key[50];
|
||||
@@ -202,6 +239,10 @@ class MyESP {
|
||||
int getWifiQuality();
|
||||
void showSystemStats();
|
||||
|
||||
// rtcmem and reset reason
|
||||
bool rtcmemStatus();
|
||||
uint32_t getSystemResetReason();
|
||||
|
||||
private:
|
||||
// mqtt
|
||||
AsyncMqttClient mqttClient;
|
||||
@@ -226,6 +267,7 @@ class MyESP {
|
||||
char * _mqtt_topic;
|
||||
unsigned long _mqtt_last_connection;
|
||||
bool _mqtt_connecting;
|
||||
bool _rtcmem_status;
|
||||
|
||||
// wifi
|
||||
DNSServer dnsServer; // For Access Point (AP) support
|
||||
@@ -283,6 +325,29 @@ class MyESP {
|
||||
unsigned long _getUptime();
|
||||
String _buildTime();
|
||||
|
||||
// reset reason and rtcmem
|
||||
bool _rtcmemStatus();
|
||||
void _rtcmemInit();
|
||||
void _rtcmemSetup();
|
||||
|
||||
void _deferredReset(unsigned long delay, uint8_t reason);
|
||||
|
||||
uint8_t _getSystemStabilityCounter();
|
||||
void _setSystemStabilityCounter(uint8_t counter);
|
||||
|
||||
uint8_t _getSystemResetReason();
|
||||
void _setSystemResetReason(uint8_t reason);
|
||||
|
||||
unsigned char _getCustomResetReason();
|
||||
void _setCustomResetReason(unsigned char reason);
|
||||
|
||||
bool _systemStable;
|
||||
|
||||
bool getSystemCheck();
|
||||
void _systemCheckLoop();
|
||||
void _setSystemCheck(bool stable);
|
||||
|
||||
|
||||
// load average (0..100)
|
||||
void _calculateLoad();
|
||||
unsigned short int _load_average;
|
||||
|
||||
@@ -32,7 +32,7 @@ upload_protocol = espota
|
||||
upload_port = ems-esp.local
|
||||
|
||||
[env:debug]
|
||||
build_flags = -g -Wall -Wextra -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -DCRASH -DTESTS ${common.wifi_settings}
|
||||
build_flags = -g -Wall -Wextra -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -DTESTS -DNO_GLOBAL_EEPROM ${common.wifi_settings}
|
||||
|
||||
[env:clean]
|
||||
extra_scripts = pre:scripts/clean_fw.py
|
||||
@@ -42,5 +42,5 @@ build_flags = -g -w
|
||||
extra_scripts = pre:scripts/rename_fw.py
|
||||
|
||||
[env:checkcode]
|
||||
build_flags = -g -Wall -Wextra -Werror -Wno-missing-field-initializers -Wno-unused-parameter -Wno-unused-variable -DCRASH -DTESTS
|
||||
build_flags = -g -w
|
||||
extra_scripts = scripts/checkcode.py
|
||||
|
||||
@@ -1,33 +1,43 @@
|
||||
>>>stack>>>
|
||||
3ffffdd0: 3ffffe30 3fff43c8 3fff89bc 40211340
|
||||
3ffffde0: 3fff89bc 3fff43c8 3fff461c 4022cd7a
|
||||
3ffffdf0: 3ffffe70 402096cb 3fff461c 4022cd68
|
||||
3ffffe00: 3ffffe30 3fff43c8 3fff89bc 402096dc
|
||||
3ffffe10: 454d5b20 4f205d4d 52204154 72657365
|
||||
3ffffe20: 00000000 00642520 4025ce70 40209684
|
||||
3ffffe30: 3ffffe70 3ffffe40 00000008 00000001
|
||||
3ffffe40: 00000002 3fff4770 3fff43c8 40246b28
|
||||
3ffffe50: 3fff89b8 ff000000 00068d0c 4020f650
|
||||
3ffffe60: 0000001b 00003340 400205e9 4024f545
|
||||
3ffffe70: 4020cd64 3fff4770 3fff43c8 00000001
|
||||
3ffffe80: 00000002 3fff4770 3fff43c8 4020a640
|
||||
3ffffe90: 45455b20 4d4f5250 4545205d 4d4f5250
|
||||
3ffffea0: 63655320 20726f74 6c6f6f70 7a697320
|
||||
3ffffeb0: 73692065 202c3420 20646e61 75206e69
|
||||
3ffffec0: 61206573 203a6572 39313031 31303120
|
||||
3ffffed0: 30312038 31203731 20363130 00000000
|
||||
3ffffee0: 36313031 00000000 00000000 00000000
|
||||
3ffffef0: 00000000 00000000 ff000007 4020f5ae
|
||||
3fffff00: 00000000 00000007 3ffe8304 402274e7
|
||||
3fffff10: 0000000d 00000001 3fff43c8 3fff46a0
|
||||
3fffff20: 3fff8c4c 00000001 3fff43c8 4020c5b9
|
||||
3fffff30: 3fffdad0 3fff4630 0000000d 40217c8e
|
||||
3fffff40: 3fffdad0 3fff4630 3fff461c 3fff46a0
|
||||
3fffff50: 0000000d 3fff461c 3fff43c8 4020cb89
|
||||
3fffff60: 0000000d 3fff4908 3ffe97ac 3fff48ac
|
||||
3fffff70: 3fff43c8 3fff29cc 3fff43b8 3fff48ac
|
||||
3fffff80: 3fffdad0 3fff29cc 3fff43c8 4020cc58
|
||||
3fffff90: 3fffdad0 00000000 3fff29cc 40205ccc
|
||||
3fffffa0: 3fffdad0 00000000 3fff487c 4020ebd4
|
||||
3fffffb0: feefeffe feefeffe 3ffe97ac 401006f1
|
||||
3ffffd30: 40105346 00000030 0000001e ffffffff
|
||||
3ffffd40: 40105928 00000000 60000200 04000002
|
||||
3ffffd50: 3feffe00 fffffeff 00000000 00000000
|
||||
3ffffd60: 00000003 00000000 0000002d 3ffffe50
|
||||
3ffffd70: 00000008 00001008 00000000 00000030
|
||||
3ffffd80: 34303936 34343139 3ffe3131 40223f98
|
||||
3ffffd90: 3fff46dc 00000001 3ffec7b9 40223f98
|
||||
3ffffda0: 3fff46dc 0000001c 3fff8b18 3ffffe20
|
||||
3ffffdb0: 3fff4a0c 0000073d 0000073d 40211340
|
||||
3ffffdc0: 3ffffe20 3fff4488 3fff8afc 40211768
|
||||
3ffffdd0: 3fff8afc 3fff4488 3fff46dc 4022d182
|
||||
3ffffde0: 3ffffe60 402097ff 3fff46dc 4022d170
|
||||
3ffffdf0: 3ffffe20 3fff4488 3fff8afc 40209810
|
||||
3ffffe00: 00000000 400042db 616c4620 52206873
|
||||
3ffffe10: 40004b31 3ffffe58 00000008 00001000
|
||||
3ffffe20: 40105934 3ffffe30 00000008 00000000
|
||||
3ffffe30: 40100289 3ffffe50 00000000 3fff482c
|
||||
3ffffe40: 3fff8c18 ff000000 00001008 4020d3cc
|
||||
3ffffe50: 00000000 00000000 400205e9 40100250
|
||||
3ffffe60: 400201e9 001640ef 3fff4488 00000003
|
||||
3ffffe70: 00000002 3fff4834 3fff4488 4020a9b9
|
||||
3ffffe80: 45455b20 4d4f5250 4545205d 4d4f5250
|
||||
3ffffe90: 63655320 20726f74 6c6f6f70 7a697320
|
||||
3ffffea0: 73692065 202c3420 20646e61 75206e69
|
||||
3ffffeb0: 61206573 203a6572 39313031 31303120
|
||||
3ffffec0: 30312038 31203731 20363130 00000000
|
||||
3ffffed0: 6f626552 6620746f 206d6f72 6d726574
|
||||
3ffffee0: 6c616e69 4020f900 00000007 40211584
|
||||
3ffffef0: 36313031 00000000 00000000 00000000
|
||||
3fffff00: 00000000 00000007 3ffe8304 402278ef
|
||||
3fffff10: 0000000d 00000001 3fff4488 3fff4760
|
||||
3fffff20: 3fff800c 00000001 3fff4488 4020c95d
|
||||
3fffff30: 0000006d 3fff46f0 0000000d 402180b6
|
||||
3fffff40: 0000006d 3fff46f0 3fff46dc 3fff4760
|
||||
3fffff50: 0000000d 3fff46dc 3fff4488 4020cf39
|
||||
3fffff60: 0000000d 3fff49cc 3ffe97b8 3fff4970
|
||||
3fffff70: 3fff4488 3fff2a8c 3fff4478 3fff4970
|
||||
3fffff80: 3fffdad0 3fff2a8c 3fff4488 4020d008
|
||||
3fffff90: 3fffdad0 00000000 3fff2a8c 40205cd4
|
||||
3fffffa0: 3fffdad0 00000000 3fff4940 4020f000
|
||||
3fffffb0: feefeffe feefeffe 3ffe97b8 401006f1
|
||||
<<<stack<<<
|
||||
@@ -183,7 +183,7 @@ void ICACHE_FLASH_ATTR emsuart_tx_brk() {
|
||||
tmp = (1 << UCBRK);
|
||||
USC0(EMSUART_UART) |= (tmp); // set bit
|
||||
|
||||
if (EMS_Sys_Status.emsTxMode <= 2) { // classic mode
|
||||
if (EMS_Sys_Status.emsTxMode <= 1) { // classic mode and ems+ (0, 1)
|
||||
delayMicroseconds(EMSUART_TX_BRK_WAIT);
|
||||
} else if (EMS_Sys_Status.emsTxMode == 3) { // junkers mode
|
||||
delayMicroseconds(EMSUART_TX_WAIT_BRK - EMSUART_TX_LAG); // 1144 (11 Bits)
|
||||
@@ -238,10 +238,9 @@ void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||
* - <BRK> is detected
|
||||
* At end of receive we re-enable Rx-INT and send a Tx-BRK in loopback mode.
|
||||
*/
|
||||
|
||||
ETS_UART_INTR_DISABLE(); // disable rx interrupt
|
||||
|
||||
// clear Rx status register - https://github.com/proddy/EMS-ESP/issues/103#issuecomment-495605798
|
||||
// clear Rx status register
|
||||
USC0(EMSUART_UART) |= (1 << UCRXRST); // reset uart rx fifo
|
||||
emsuart_flush_fifos();
|
||||
|
||||
@@ -254,9 +253,9 @@ void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
// we got the whole telegram in Rx buffer
|
||||
// on Rx-BRK (bus collision), we simply enable Rx and leave
|
||||
// otherwise, we send the final Tx-BRK in loopback and enable Rx-INT.
|
||||
// we got the whole telegram in the Rx buffer
|
||||
// on Rx-BRK (bus collision), we simply enable Rx and leave it
|
||||
// otherwise we send the final Tx-BRK in the loopback and re=enable Rx-INT.
|
||||
// worst case, we'll see an additional Rx-BRK...
|
||||
if (!(USIS(EMSUART_UART) & (1 << UIBD))) {
|
||||
phantomBrk = 1; // tell Rx to expect a phantom BRK
|
||||
@@ -276,7 +275,6 @@ void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||
}
|
||||
|
||||
// w/o flushing the Rx FIFO we will get a trailing \0 from our loopback BRK
|
||||
// emsuart_flush_fifos(); // flush Rx buffer to be sure
|
||||
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
#pragma once
|
||||
|
||||
#define APP_NAME "EMS-ESP"
|
||||
#define APP_VERSION "1.8.0b11"
|
||||
#define APP_VERSION "1.8.0b12"
|
||||
#define APP_HOSTNAME "ems-esp"
|
||||
|
||||
Reference in New Issue
Block a user