From f3464d90cc72add643a3532708b934dcb85c3714 Mon Sep 17 00:00:00 2001 From: Martin Luessi Date: Fri, 8 Jul 2022 06:46:08 -0700 Subject: [PATCH] Flashfs: Add support for asynchronous complete erase --- src/main/fc/tasks.c | 5 +++++ src/main/io/flashfs.c | 48 +++++++++++++++++++++++++++++++------------ src/main/io/flashfs.h | 1 + 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/main/fc/tasks.c b/src/main/fc/tasks.c index 7c0407dfa0..de630702b4 100644 --- a/src/main/fc/tasks.c +++ b/src/main/fc/tasks.c @@ -61,6 +61,7 @@ #include "io/asyncfatfs/asyncfatfs.h" #include "io/beeper.h" #include "io/dashboard.h" +#include "io/flashfs.h" #include "io/gps.h" #include "io/ledstrip.h" #include "io/piniobox.h" @@ -126,6 +127,10 @@ static void taskMain(timeUs_t currentTimeUs) #ifdef USE_SDCARD afatfs_poll(); #endif + +#ifdef USE_FLASHFS + flashfsEraseAsync(); +#endif } static void taskHandleSerial(timeUs_t currentTimeUs) diff --git a/src/main/io/flashfs.c b/src/main/io/flashfs.c index 8e8c16bd57..9cd7e869f9 100644 --- a/src/main/io/flashfs.c +++ b/src/main/io/flashfs.c @@ -41,12 +41,20 @@ #include "build/debug.h" #include "common/printf.h" #include "drivers/flash.h" +#include "drivers/light_led.h" #include "io/flashfs.h" +typedef enum { + FLASHFS_IDLE, + FLASHFS_ERASING, +} flashfsState_e; + static const flashPartition_t *flashPartition = NULL; static const flashGeometry_t *flashGeometry = NULL; static uint32_t flashfsSize = 0; +static flashfsState_e flashfsState = FLASHFS_IDLE; +static flashSector_t eraseSectorCurrent = 0; static DMA_DATA_ZERO_INIT uint8_t flashWriteBuffer[FLASHFS_WRITE_BUFFER_SIZE]; @@ -110,17 +118,9 @@ void flashfsEraseCompletely(void) if (doFullErase) { flashEraseCompletely(); } else { - - // TODO - the partial sector-based erase needs to be completely reworked. - // All calls to flashfsEraseCompletely() currently expect the erase to run - // asynchronously and return immediately. The current implementation performs - // the erase synchronously and doesn't return until complete. This breaks calls - // from MSP and runtime mode-switched erasing. - - for (flashSector_t sectorIndex = flashPartition->startSector; sectorIndex <= flashPartition->endSector; sectorIndex++) { - uint32_t sectorAddress = sectorIndex * flashGeometry->sectorSize; - flashEraseSector(sectorAddress); - } + // start asynchronous erase of all sectors + eraseSectorCurrent = flashPartition->startSector; + flashfsState = FLASHFS_ERASING; } } @@ -160,9 +160,9 @@ void flashfsEraseRange(uint32_t start, uint32_t end) */ bool flashfsIsReady(void) { - // Check for flash chip existence first, then check if ready. + // Check for flash chip existence first, then check if idle and ready. - return (flashfsIsSupported() && flashIsReady()); + return (flashfsIsSupported() && (flashfsState == FLASHFS_IDLE) && flashIsReady()); } bool flashfsIsSupported(void) @@ -407,6 +407,28 @@ void flashfsFlushSync(void) while (!flashIsReady()); } +/** + * Asynchronously erase the flash: Check if ready and then erase sector. + */ +void flashfsEraseAsync(void) +{ + if (flashfsState == FLASHFS_ERASING) { + if ((flashfsIsSupported() && flashIsReady())) { + if (eraseSectorCurrent <= flashPartition->endSector) { + // Erase sector + uint32_t sectorAddress = eraseSectorCurrent * flashGeometry->sectorSize; + flashEraseSector(sectorAddress); + eraseSectorCurrent++; + LED1_TOGGLE; + } else { + // Done erasing + flashfsState = FLASHFS_IDLE; + LED1_OFF; + } + } + } +} + void flashfsSeekAbs(uint32_t offset) { flashfsFlushSync(); diff --git a/src/main/io/flashfs.h b/src/main/io/flashfs.h index 0817d26b05..510efdb560 100644 --- a/src/main/io/flashfs.h +++ b/src/main/io/flashfs.h @@ -46,6 +46,7 @@ int flashfsReadAbs(uint32_t offset, uint8_t *data, unsigned int len); bool flashfsFlushAsync(bool force); void flashfsFlushSync(void); +void flashfsEraseAsync(void); void flashfsClose(void); void flashfsInit(void);