Compare commits

..

No commits in common. "c4fcbad3723d75a98a28501c3354cae5a424e20b" and "c1beb446789ef560a106d79c99f19f548621df26" have entirely different histories.

5 changed files with 39 additions and 68 deletions

View File

@ -49,6 +49,24 @@ void OSFS::writeNBytes(uint16_t address, unsigned int num, const byte *input)
} }
#endif #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. * @brief Copies a file from one location to another.
* *
@ -330,16 +348,10 @@ void rmDir(const char *dirname)
#endif #endif
} }
/**
* Some platforms (nrf52) might need to do an extra step before FSBegin().
*/
__attribute__((weak, noinline)) void preFSBegin() {}
void fsInit() void fsInit()
{ {
#ifdef FSCom #ifdef FSCom
concurrency::LockGuard g(spiLock); spiLock->lock();
preFSBegin();
if (!FSBegin()) { if (!FSBegin()) {
LOG_ERROR("Filesystem mount failed"); LOG_ERROR("Filesystem mount failed");
// assert(0); This auto-formats the partition, so no need to fail here. // assert(0); This auto-formats the partition, so no need to fail here.
@ -350,6 +362,7 @@ void fsInit()
LOG_DEBUG("Filesystem files:"); LOG_DEBUG("Filesystem files:");
#endif #endif
listDir("/", 10); listDir("/", 10);
spiLock->unlock();
#endif #endif
} }

View File

@ -58,3 +58,6 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels);
void listDir(const char *dirname, uint8_t levels, bool del = false); void listDir(const char *dirname, uint8_t levels, bool del = false);
void rmDir(const char *dirname); void rmDir(const char *dirname);
void setupSDCard(); 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)

View File

@ -8,6 +8,7 @@ static File openFile(const char *filename, bool fullAtomic)
concurrency::LockGuard g(spiLock); concurrency::LockGuard g(spiLock);
LOG_DEBUG("Opening %s, fullAtomic=%d", filename, fullAtomic); LOG_DEBUG("Opening %s, fullAtomic=%d", filename, fullAtomic);
#ifdef ARCH_NRF52 #ifdef ARCH_NRF52
lfs_assert_failed = false;
File file = FSCom.open(filename, FILE_O_WRITE); File file = FSCom.open(filename, FILE_O_WRITE);
file.seek(0); file.seek(0);
return file; return file;
@ -19,6 +20,7 @@ static File openFile(const char *filename, bool fullAtomic)
filenameTmp += ".tmp"; filenameTmp += ".tmp";
// clear any previous LFS errors // clear any previous LFS errors
lfs_assert_failed = false;
return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE); return FSCom.open(filenameTmp.c_str(), FILE_O_WRITE);
} }
@ -94,6 +96,8 @@ bool SafeFile::close()
bool SafeFile::testReadback() bool SafeFile::testReadback()
{ {
concurrency::LockGuard g(spiLock); concurrency::LockGuard g(spiLock);
bool lfs_failed = lfs_assert_failed;
lfs_assert_failed = false;
String filenameTmp = filename; String filenameTmp = filename;
filenameTmp += ".tmp"; filenameTmp += ".tmp";
@ -115,7 +119,7 @@ bool SafeFile::testReadback()
return false; return false;
} }
return true; return !lfs_failed;
} }
#endif #endif

View File

@ -2662,13 +2662,14 @@ int Screen::handleStatusUpdate(const meshtastic::Status *arg)
int Screen::handleTextMessage(const meshtastic_MeshPacket *packet) int Screen::handleTextMessage(const meshtastic_MeshPacket *packet)
{ {
// If auto carousel is disabled -> return 0 and skip new messages handling
if (config.display.auto_screen_carousel_secs == 0)
return 0;
// Handle focus change based on message type
if (showingNormalScreen) { if (showingNormalScreen) {
setFrames(packet->from == 0 ? FOCUS_PRESERVE : FOCUS_TEXTMESSAGE); // Outgoing message
if (packet->from == 0)
setFrames(FOCUS_PRESERVE); // Return to same frame (quietly hiding the rx text message frame)
// Incoming message
else
setFrames(FOCUS_TEXTMESSAGE); // Focus on the new message
} }
return 0; return 0;

View File

@ -1,7 +1,6 @@
#include "configuration.h" #include "configuration.h"
#include <Adafruit_TinyUSB.h> #include <Adafruit_TinyUSB.h>
#include <Adafruit_nRFCrypto.h> #include <Adafruit_nRFCrypto.h>
#include <InternalFileSystem.h>
#include <SPI.h> #include <SPI.h>
#include <Wire.h> #include <Wire.h>
#include <assert.h> #include <assert.h>
@ -131,54 +130,6 @@ int printf(const char *fmt, ...)
return res; 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() void checkSDEvents()
{ {
if (useSoftDevice) { if (useSoftDevice) {
@ -203,7 +154,6 @@ void checkSDEvents()
void nrf52Loop() void nrf52Loop()
{ {
checkSDEvents(); checkSDEvents();
reportLittleFSCorruptionOnce();
} }
#ifdef USE_SEMIHOSTING #ifdef USE_SEMIHOSTING