From aaa2f9682df21ec2559e728fd3e31ae903307e74 Mon Sep 17 00:00:00 2001 From: Bruce Luckcuck Date: Sat, 25 May 2019 12:18:52 -0400 Subject: [PATCH] Use full erase when possible for FLASHFS erase If there is only a single partition, its type is FLASHFS, and it uses the entire geometry, then perform a full rather than a sector-based erase. The full erase is significantly faster than erasing by individual sectors. --- src/main/drivers/flash.c | 5 +++++ src/main/drivers/flash.h | 1 + src/main/io/flashfs.c | 21 ++++++++++++++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/main/drivers/flash.c b/src/main/drivers/flash.c index 1e16a370e..97aa946f1 100644 --- a/src/main/drivers/flash.c +++ b/src/main/drivers/flash.c @@ -395,4 +395,9 @@ bool flashInit(const flashConfig_t *flashConfig) return haveFlash; } + +int flashPartitionCount(void) +{ + return flashPartitions; +} #endif // USE_FLASH_CHIP diff --git a/src/main/drivers/flash.h b/src/main/drivers/flash.h index 330674372..dac4df70b 100644 --- a/src/main/drivers/flash.h +++ b/src/main/drivers/flash.h @@ -94,3 +94,4 @@ void flashPartitionSet(uint8_t index, uint32_t startSector, uint32_t endSector); flashPartition_t *flashPartitionFindByType(flashPartitionType_e type); const flashPartition_t *flashPartitionFindByIndex(uint8_t index); const char *flashPartitionGetTypeName(flashPartitionType_e type); +int flashPartitionCount(void); diff --git a/src/main/io/flashfs.c b/src/main/io/flashfs.c index 6c0e1a6f7..6599d6051 100644 --- a/src/main/io/flashfs.c +++ b/src/main/io/flashfs.c @@ -78,9 +78,24 @@ static void flashfsSetTailAddress(uint32_t address) void flashfsEraseCompletely(void) { - for (flashSector_t sectorIndex = flashPartition->startSector; sectorIndex <= flashPartition->endSector; sectorIndex++) { - uint32_t sectorAddress = sectorIndex * flashGeometry->sectorSize; - flashEraseSector(sectorAddress); + if (flashGeometry->sectors > 0 && flashPartitionCount() > 0) { + // if there's a single FLASHFS partition and it uses the entire flash then do a full erase + const bool doFullErase = (flashPartitionCount() == 1) && (FLASH_PARTITION_SECTOR_COUNT(flashPartition) == flashGeometry->sectors); + 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); + } + } } flashfsClearBuffer();