mirror of
https://github.com/meshtastic/firmware.git
synced 2025-02-01 02:09:57 +00:00
Reboot before formatting LittleFS (#5900)
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / package-raspbian (push) Waiting to run
CI / package-raspbian-armv7l (push) Waiting to run
CI / package-native (push) Waiting to run
CI / build-debian-src (push) Waiting to run
CI / test-native (push) Waiting to run
CI / build-docker (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
Flawfinder Scan / Flawfinder (push) Waiting to run
Some checks are pending
CI / setup (check) (push) Waiting to run
CI / setup (esp32) (push) Waiting to run
CI / setup (esp32c3) (push) Waiting to run
CI / setup (esp32c6) (push) Waiting to run
CI / setup (esp32s3) (push) Waiting to run
CI / setup (nrf52840) (push) Waiting to run
CI / setup (rp2040) (push) Waiting to run
CI / setup (stm32) (push) Waiting to run
CI / check (push) Blocked by required conditions
CI / build-esp32 (push) Blocked by required conditions
CI / build-esp32-s3 (push) Blocked by required conditions
CI / build-esp32-c3 (push) Blocked by required conditions
CI / build-esp32-c6 (push) Blocked by required conditions
CI / build-nrf52 (push) Blocked by required conditions
CI / build-rpi2040 (push) Blocked by required conditions
CI / build-stm32 (push) Blocked by required conditions
CI / package-raspbian (push) Waiting to run
CI / package-raspbian-armv7l (push) Waiting to run
CI / package-native (push) Waiting to run
CI / build-debian-src (push) Waiting to run
CI / test-native (push) Waiting to run
CI / build-docker (push) Waiting to run
CI / after-checks (push) Blocked by required conditions
CI / gather-artifacts (esp32) (push) Blocked by required conditions
CI / gather-artifacts (esp32c3) (push) Blocked by required conditions
CI / gather-artifacts (esp32c6) (push) Blocked by required conditions
CI / gather-artifacts (esp32s3) (push) Blocked by required conditions
CI / gather-artifacts (nrf52840) (push) Blocked by required conditions
CI / gather-artifacts (rp2040) (push) Blocked by required conditions
CI / gather-artifacts (stm32) (push) Blocked by required conditions
CI / release-artifacts (push) Blocked by required conditions
CI / release-firmware (esp32) (push) Blocked by required conditions
CI / release-firmware (esp32c3) (push) Blocked by required conditions
CI / release-firmware (esp32c6) (push) Blocked by required conditions
CI / release-firmware (esp32s3) (push) Blocked by required conditions
CI / release-firmware (nrf52840) (push) Blocked by required conditions
CI / release-firmware (rp2040) (push) Blocked by required conditions
CI / release-firmware (stm32) (push) Blocked by required conditions
Flawfinder Scan / Flawfinder (push) Waiting to run
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
parent
0f981153eb
commit
c4fcbad372
@ -49,24 +49,6 @@ void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input)
|
||||
}
|
||||
#endif
|
||||
|
||||
bool lfs_assert_failed =
|
||||
false; // Note: we use this global on all platforms, though it can only be set true on nrf52 (in our modified lfs_util.h)
|
||||
|
||||
extern "C" void lfs_assert(const char *reason)
|
||||
{
|
||||
LOG_ERROR("LFS assert: %s", reason);
|
||||
lfs_assert_failed = true;
|
||||
|
||||
#ifndef ARCH_PORTDUINO
|
||||
#ifdef FSCom
|
||||
// CORRUPTED FILESYSTEM. This causes bootloop so
|
||||
// might as well try formatting now.
|
||||
LOG_ERROR("Trying FSCom.format()");
|
||||
FSCom.format();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Copies a file from one location to another.
|
||||
*
|
||||
@ -348,10 +330,16 @@ void rmDir(const char *dirname)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Some platforms (nrf52) might need to do an extra step before FSBegin().
|
||||
*/
|
||||
__attribute__((weak, noinline)) void preFSBegin() {}
|
||||
|
||||
void fsInit()
|
||||
{
|
||||
#ifdef FSCom
|
||||
spiLock->lock();
|
||||
concurrency::LockGuard g(spiLock);
|
||||
preFSBegin();
|
||||
if (!FSBegin()) {
|
||||
LOG_ERROR("Filesystem mount failed");
|
||||
// assert(0); This auto-formats the partition, so no need to fail here.
|
||||
@ -362,7 +350,6 @@ void fsInit()
|
||||
LOG_DEBUG("Filesystem files:");
|
||||
#endif
|
||||
listDir("/", 10);
|
||||
spiLock->unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,3 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels);
|
||||
void listDir(const char *dirname, uint8_t levels, bool del = false);
|
||||
void rmDir(const char *dirname);
|
||||
void setupSDCard();
|
||||
|
||||
extern bool lfs_assert_failed; // Note: we use this global on all platforms, though it can only be set true on nrf52 (in our
|
||||
// modified lfs_util.h)
|
||||
|
@ -8,7 +8,6 @@ static File openFile(const char *filename, bool fullAtomic)
|
||||
concurrency::LockGuard g(spiLock);
|
||||
LOG_DEBUG("Opening %s, fullAtomic=%d", filename, fullAtomic);
|
||||
#ifdef ARCH_NRF52
|
||||
lfs_assert_failed = false;
|
||||
File file = FSCom.open(filename, FILE_O_WRITE);
|
||||
file.seek(0);
|
||||
return file;
|
||||
@ -20,7 +19,6 @@ static File openFile(const char *filename, bool fullAtomic)
|
||||
filenameTmp += ".tmp";
|
||||
|
||||
// clear any previous LFS errors
|
||||
lfs_assert_failed = false;
|
||||
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
|
||||
}
|
||||
|
||||
@ -96,8 +94,6 @@ bool SafeFile::close()
|
||||
bool SafeFile::testReadback()
|
||||
{
|
||||
concurrency::LockGuard g(spiLock);
|
||||
bool lfs_failed = lfs_assert_failed;
|
||||
lfs_assert_failed = false;
|
||||
|
||||
String filenameTmp = filename;
|
||||
filenameTmp += ".tmp";
|
||||
@ -119,7 +115,7 @@ bool SafeFile::testReadback()
|
||||
return false;
|
||||
}
|
||||
|
||||
return !lfs_failed;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,6 +1,7 @@
|
||||
#include "configuration.h"
|
||||
#include <Adafruit_TinyUSB.h>
|
||||
#include <Adafruit_nRFCrypto.h>
|
||||
#include <InternalFileSystem.h>
|
||||
#include <SPI.h>
|
||||
#include <Wire.h>
|
||||
#include <assert.h>
|
||||
@ -130,6 +131,54 @@ int printf(const char *fmt, ...)
|
||||
return res;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
constexpr uint8_t NRF52_MAGIC_LFS_IS_CORRUPT = 0xF5;
|
||||
constexpr uint32_t MULTIPLE_CORRUPTION_DELAY_MILLIS = 20 * 60 * 1000;
|
||||
static unsigned long millis_until_formatting_again = 0;
|
||||
|
||||
// Report the critical error from loop(), giving a chance for the screen to be initialized first.
|
||||
inline void reportLittleFSCorruptionOnce()
|
||||
{
|
||||
static bool report_corruption = !!millis_until_formatting_again;
|
||||
if (report_corruption) {
|
||||
report_corruption = false;
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_FLASH_CORRUPTION_UNRECOVERABLE);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void preFSBegin()
|
||||
{
|
||||
// The GPREGRET register keeps its value across warm boots. Check that this is a warm boot and, if GPREGRET
|
||||
// is set to NRF52_MAGIC_LFS_IS_CORRUPT, format LittleFS.
|
||||
if (!(NRF_POWER->RESETREAS == 0 && NRF_POWER->GPREGRET == NRF52_MAGIC_LFS_IS_CORRUPT))
|
||||
return;
|
||||
NRF_POWER->GPREGRET = 0;
|
||||
millis_until_formatting_again = millis() + MULTIPLE_CORRUPTION_DELAY_MILLIS;
|
||||
InternalFS.format();
|
||||
LOG_INFO("LittleFS format complete; restoring default settings");
|
||||
}
|
||||
|
||||
extern "C" void lfs_assert(const char *reason)
|
||||
{
|
||||
LOG_ERROR("LittleFS corruption detected: %s", reason);
|
||||
if (millis_until_formatting_again > millis()) {
|
||||
RECORD_CRITICALERROR(meshtastic_CriticalErrorCode_FLASH_CORRUPTION_UNRECOVERABLE);
|
||||
const long millis_remain = millis_until_formatting_again - millis();
|
||||
LOG_WARN("Pausing %d seconds to avoid wear on flash storage", millis_remain / 1000);
|
||||
delay(millis_remain);
|
||||
}
|
||||
LOG_INFO("Rebooting to format LittleFS");
|
||||
delay(500); // Give the serial port a bit of time to output that last message.
|
||||
// Try setting GPREGRET with the SoftDevice first. If that fails (perhaps because the SD hasn't been initialize yet) then set
|
||||
// NRF_POWER->GPREGRET directly.
|
||||
if (!(sd_power_gpregret_clr(0, 0xFF) == NRF_SUCCESS && sd_power_gpregret_set(0, NRF52_MAGIC_LFS_IS_CORRUPT) == NRF_SUCCESS)) {
|
||||
NRF_POWER->GPREGRET = NRF52_MAGIC_LFS_IS_CORRUPT;
|
||||
}
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
void checkSDEvents()
|
||||
{
|
||||
if (useSoftDevice) {
|
||||
@ -154,6 +203,7 @@ void checkSDEvents()
|
||||
void nrf52Loop()
|
||||
{
|
||||
checkSDEvents();
|
||||
reportLittleFSCorruptionOnce();
|
||||
}
|
||||
|
||||
#ifdef USE_SEMIHOSTING
|
||||
|
Loading…
Reference in New Issue
Block a user