Fix reset 5 and 6 when filesystem in use

This commit is contained in:
Theo Arends 2021-01-12 14:54:12 +01:00
parent 675ca5f98e
commit 15598d71a9
4 changed files with 56 additions and 60 deletions

View File

@ -154,19 +154,20 @@ bool RtcRebootValid(void)
* 0x000xxxxx - Unzipped binary code end
* 0x000x1000 - First page used by Core OTA
* ::::
* 0x000F2FFF
* 0x000F2FFF 0x000F5FFF 0x000F5FFF
******************************************************************************
* Next 32k is overwritten by OTA
* 0x000F3000 - 4k Tasmota Quick Power Cycle counter (SETTINGS_LOCATION - CFG_ROTATES) - First four bytes only
* 0x000F3FFF
* 0x000F4000 - 4k First Tasmota rotating settings page
* 0x000F3000 0x000F6000 0x000F6000 - 4k Tasmota Quick Power Cycle counter (SETTINGS_LOCATION - CFG_ROTATES) - First four bytes only
* 0x000F3FFF 0x000F6FFF 0x000F6FFF
* 0x000F4000 0x000F7000 0x000F7000 - 4k First Tasmota rotating settings page
* ::::
* 0x000FA000 - 4k Last Tasmota rotating settings page = Last page used by Core OTA (SETTINGS_LOCATION)
* 0x000FAFFF
* 0x000FA000 0x000FD000 0x000FD000 - 4k Last Tasmota rotating settings page = Last page used by Core OTA (SETTINGS_LOCATION)
* 0x000FAFFF 0x000FDFFF 0x000FDFFF
******************************************************************************
* 0x000FB000 0x000FB000 - 15k9 Not used
* 0x000FE000 0x000FE000 - 3k9 Not used
* 0x000FEFF0 0x000FEFF0 - 4k1 Empty
* 0x000FFFFF 0x000FFFFF
*
* 0x000FB000 0x00100000 0x00100000 - 0k, 980k or 2980k Core FS start (LittleFS)
* 0x000FB000 0x001FA000 0x003FA000 - 0k, 980k or 2980k Core FS end (LittleFS)
* 0x001FAFFF 0x003FAFFF
@ -189,7 +190,8 @@ extern "C" {
#ifdef ESP8266
extern "C" uint32_t _FS_start; // 1M = 0x402fb000, 2M = 0x40300000, 4M = 0x40300000
uint32_t SETTINGS_LOCATION = (((uint32_t)&_FS_start - 0x40200000) / SPI_FLASH_SEC_SIZE) -1; // 0xFA, 0xFF or 0xFF
const uint32_t FLASH_FS_START = (((uint32_t)&_FS_start - 0x40200000) / SPI_FLASH_SEC_SIZE);
uint32_t SETTINGS_LOCATION = FLASH_FS_START -1; // 0xFA, 0x0FF or 0x0FF
// From libraries/EEPROM/EEPROM.cpp EEPROMClass
extern "C" uint32_t _EEPROM_start; // 1M = 0x402FB000, 2M = 0x403FB000, 4M = 0x405FB000
@ -213,7 +215,7 @@ uint8_t *settings_buffer = nullptr;
void SettingsInit(void) {
if (SETTINGS_LOCATION > 0xFA) {
SETTINGS_LOCATION = 0xFD; // Skip empty partition part
SETTINGS_LOCATION = 0xFD; // Skip empty partition part and keep in first 1M
}
}
@ -536,6 +538,9 @@ void SettingsSave(uint8_t rotate)
Settings.cfg_crc32 = GetSettingsCrc32();
#ifdef ESP8266
#ifdef USE_UFILESYS
TfsSaveFile(TASM_FILE_SETTINGS, (const uint8_t*)&Settings, sizeof(Settings));
#endif
if (ESP.flashEraseSector(settings_location)) {
ESP.flashWrite(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
}
@ -561,12 +566,18 @@ void SettingsSave(uint8_t rotate)
void SettingsLoad(void) {
#ifdef ESP8266
#ifdef USE_UFILESYS
if (TfsLoadFile(TASM_FILE_SETTINGS, (uint8_t*)&Settings, sizeof(Settings))) {
settings_location = 1;
AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from File, " D_COUNT " %lu"), Settings.save_flag);
} else {
#endif
// Load configuration from eeprom or one of 7 slots below if first valid load does not stop_flash_rotate
// Activated with version 8.4.0.2 - Fails to read any config before version 6.6.0.11
settings_location = 0;
uint32_t save_flag = 0;
uint32_t flash_location = FLASH_EEPROM_START;
for (uint32_t i = 0; i < CFG_ROTATES; i++) { // Read all config pages in search of valid and latest
for (uint32_t i = 0; i <= CFG_ROTATES; i++) { // Read all config pages in search of valid and latest
if (1 == i) { flash_location = SETTINGS_LOCATION; }
ESP.flashRead(flash_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
if ((Settings.cfg_crc32 != 0xFFFFFFFF) && (Settings.cfg_crc32 != 0x00000000) && (Settings.cfg_crc32 == GetSettingsCrc32())) {
@ -585,9 +596,13 @@ void SettingsLoad(void) {
ESP.flashRead(settings_location * SPI_FLASH_SEC_SIZE, (uint32*)&Settings, sizeof(Settings));
AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %lu"), settings_location, Settings.save_flag);
}
#ifdef USE_UFILESYS
}
#endif
#endif // ESP8266
#ifdef ESP32
uint32_t source = SettingsRead(&Settings, sizeof(Settings));
if (source) { settings_location = 1; }
AddLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG "Loaded from %s, " D_COUNT " %lu"), (source)?"File":"Nvm", Settings.save_flag);
#endif // ESP32
@ -606,25 +621,6 @@ uint32_t CfgTime(void) {
return Settings.cfg_timestamp;
}
void EspErase(uint32_t start_sector, uint32_t end_sector)
{
bool serial_output = (LOG_LEVEL_DEBUG_MORE <= TasmotaGlobal.seriallog_level);
for (uint32_t sector = start_sector; sector < end_sector; sector++) {
bool result = ESP.flashEraseSector(sector); // Arduino core - erases flash as seen by SDK
// bool result = !SPIEraseSector(sector); // SDK - erases flash as seen by SDK
// bool result = EsptoolEraseSector(sector); // Esptool - erases flash completely (slow)
if (serial_output) {
Serial.printf_P(PSTR(D_LOG_APPLICATION D_ERASED_SECTOR " %d %s\n"), sector, (result) ? D_OK : D_ERROR);
delay(10);
} else {
yield();
}
OsWatchLoop();
}
}
#ifdef ESP8266
void SettingsErase(uint8_t type)
{
@ -637,54 +633,52 @@ void SettingsErase(uint8_t type)
The default erase function is EspTool (EsptoolErase)
0 = Erase from program end until end of flash as seen by SDK
1 = Erase 16k SDK parameter area near end of flash as seen by SDK (0x0xFCxxx - 0x0xFFFFF) solving possible wifi errors
2 = Erase Tasmota parameter area (0x0xF3xxx - 0x0xFBFFF)
0 = Erase from program end until end of flash as seen by SDK including optional filesystem
1 = Erase 16k SDK parameter area near end of flash as seen by SDK (0x0XFCxxx - 0x0XFFFFF) solving possible wifi errors
2 = Erase from program end until end of flash as seen by SDK excluding optional filesystem
3 = Erase Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
4 = Erase SDK parameter area used for wifi calibration (0x0FCxxx - 0x0FCFFF)
*/
#ifndef FIRMWARE_MINIMAL
// Reset 2 = Erase all flash from program end to end of physical flash
uint32_t _sectorStart = (ESP.getSketchSize() / SPI_FLASH_SEC_SIZE) + 1;
uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE; // Flash size as reported by hardware
if (1 == type) {
if (1 == type) { // Reset 3 = SDK parameter area
// source Esp.cpp and core_esp8266_phy.cpp
_sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4; // SDK parameter area
}
else if (2 == type) {
_sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota parameter area (0x0F3xxx - 0x0FAFFF)
_sectorEnd = SETTINGS_LOCATION;
}
else if (3 == type) {
_sectorStart = SETTINGS_LOCATION - CFG_ROTATES; // Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
_sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE; // Flash size as seen by SDK
}
else if (4 == type) {
// _sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4; // SDK phy area and Core calibration sector (0x0FC000)
_sectorStart = FLASH_EEPROM_START +1; // SDK phy area and Core calibration sector (0x0FC000)
_sectorEnd = _sectorStart +1; // SDK end of phy area and Core calibration sector (0x0FCFFF)
_sectorStart = (ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE) - 4;
}
else if (2 == type) { // Reset 5, 6 = Erase all flash from program end to end of physical flash but skip filesystem
/*
else if (5 == type) {
_sectorStart = (ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE) -4; // SDK phy area and Core calibration sector (0xxFC000)
_sectorEnd = _sectorStart +1; // SDK end of phy area and Core calibration sector (0xxFCFFF)
}
#ifdef USE_UFILESYS
TfsDeleteFile(TASM_FILE_SETTINGS); // Not needed as it is recreated by set defaults before restart
#endif
*/
else {
return;
EsptoolErase(_sectorStart, FLASH_FS_START);
_sectorStart = FLASH_EEPROM_START;
_sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE; // Flash size as seen by SDK
}
else if (3 == type) { // QPC Reached = QPC and Tasmota and SDK parameter area (0x0F3xxx - 0x0FFFFF)
#ifdef USE_UFILESYS
TfsDeleteFile(TASM_FILE_SETTINGS);
#endif
EsptoolErase(SETTINGS_LOCATION - CFG_ROTATES, SETTINGS_LOCATION +1);
_sectorStart = FLASH_EEPROM_START;
_sectorEnd = ESP.getFlashChipSize() / SPI_FLASH_SEC_SIZE; // Flash size as seen by SDK
}
else if (4 == type) { // WIFI_FORCE_RF_CAL_ERASE = SDK wifi calibration
_sectorStart = FLASH_EEPROM_START +1; // SDK phy area and Core calibration sector (0x0XFC000)
_sectorEnd = _sectorStart +1; // SDK end of phy area and Core calibration sector (0x0XFCFFF)
}
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " from 0x%08X to 0x%08X"), _sectorStart * SPI_FLASH_SEC_SIZE, (_sectorEnd * SPI_FLASH_SEC_SIZE) -1);
// EspErase(_sectorStart, _sectorEnd); // Arduino core and SDK - erases flash as seen by SDK
EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
EsptoolErase(_sectorStart, _sectorEnd); // Esptool - erases flash completely
#endif // FIRMWARE_MINIMAL
}
#endif // ESP8266
void SettingsSdkErase(void)
{
WiFi.disconnect(false); // Delete SDK wifi config
WiFi.disconnect(false); // Delete SDK wifi config
SettingsErase(1);
delay(1000);
}

View File

@ -138,7 +138,7 @@ int32_t NvmErase(const char *sNvsName) {
void SettingsErase(uint8_t type) {
// SDK and Tasmota data is held in default NVS partition
// Tasmota data is held also in file /settings on default filesystem
// Tasmota data is held also in file /.settings on default filesystem
// cal_data - SDK PHY calibration data as documented in esp_phy_init.h
// qpc - Tasmota Quick Power Cycle state
// main - Tasmota Settings data

View File

@ -95,6 +95,8 @@ bool EsptoolEraseSector(uint32_t sector)
void EsptoolErase(uint32_t start_sector, uint32_t end_sector)
{
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_APPLICATION D_ERASE " from 0x%06X to 0x%06X"), start_sector * SPI_FLASH_SEC_SIZE, (end_sector * SPI_FLASH_SEC_SIZE) -1);
int next_erase_sector = start_sector;
int remaining_erase_sector = end_sector - start_sector;

View File

@ -1134,7 +1134,7 @@ void Every250mSeconds(void)
// Backup mqtt host, port, client, username and password
// }
if ((215 == TasmotaGlobal.restart_flag) || (216 == TasmotaGlobal.restart_flag)) {
SettingsErase(0); // Erase all flash from program end to end of physical flash
SettingsErase(2); // Erase all flash from program end to end of physical excluding optional filesystem
}
SettingsDefault();
// Restore current SSIDs and Passwords