From f5084a59bd6e2ff288fec0ae3b0adf6c63e2c893 Mon Sep 17 00:00:00 2001 From: jflyper Date: Sun, 19 May 2019 18:42:39 +0900 Subject: [PATCH] Partitions are now accessed by types rather than indices --- src/main/cli/cli.c | 14 +++- src/main/cms/cms_menu_blackbox.c | 2 +- src/main/drivers/flash.c | 125 ++++++++++++++++++++----------- src/main/drivers/flash.h | 25 ++++--- src/main/drivers/flash_w25n01g.c | 10 +-- src/main/io/flashfs.c | 4 +- src/main/msp/msp.c | 2 +- src/main/osd/osd.c | 2 +- 8 files changed, 117 insertions(+), 67 deletions(-) diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index 4d8fe20704..ddc832602e 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -2219,8 +2219,20 @@ static void cliFlashInfo(char *cmdline) cliPrintLinef("Flash sectors=%u, sectorSize=%u, pagesPerSector=%u, pageSize=%u, totalSize=%u", layout->sectors, layout->sectorSize, layout->pagesPerSector, layout->pageSize, layout->totalSize); + + for (uint8_t index = 0; index < FLASH_MAX_PARTITIONS; index++) { + const flashPartition_t *partition; + if (index == 0) { + cliPrintLine("Paritions:"); + } + partition = flashPartitionFindByIndex(index); + if (!partition) { + break; + } + cliPrintLinef(" %d: %s %u %u", index, flashPartitionGetTypeName(partition->type), partition->startSector, partition->endSector); + } #ifdef USE_FLASHFS - const flashPartition_t *flashPartition = flashFindPartitionByUsage(FLASH_PARTITION_FLASHFS); + const flashPartition_t *flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS); cliPrintLinef("FlashFS size=%u, usedSize=%u", FLASH_PARTITION_SECTOR_COUNT(flashPartition) * layout->sectorSize, diff --git a/src/main/cms/cms_menu_blackbox.c b/src/main/cms/cms_menu_blackbox.c index 39f4a2de3d..18b4a72a73 100644 --- a/src/main/cms/cms_menu_blackbox.c +++ b/src/main/cms/cms_menu_blackbox.c @@ -126,7 +126,7 @@ static void cmsx_Blackbox_GetDeviceStatus(void) if (storageDeviceIsWorking) { tfp_sprintf(cmsx_BlackboxStatus, "READY"); - const flashPartition_t *flashPartition = flashFindPartitionByUsage(FLASH_PARTITION_FLASHFS); + const flashPartition_t *flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS); const flashGeometry_t *flashGeometry = flashGetGeometry(); storageUsed = flashfsGetOffset() / 1024; diff --git a/src/main/drivers/flash.c b/src/main/drivers/flash.c index 232d1189d8..1e16a370e1 100644 --- a/src/main/drivers/flash.c +++ b/src/main/drivers/flash.c @@ -43,8 +43,7 @@ static busDevice_t *busdev; static flashDevice_t flashDevice; static flashPartitionTable_t flashPartitionTable; - -static void flashConfigurePartitions(void); +static int flashPartitions = 0; #define FLASH_INSTRUCTION_RDID 0x9F @@ -201,17 +200,6 @@ bool flashDeviceInit(const flashConfig_t *flashConfig) return false; } -bool flashInit(const flashConfig_t *flashConfig) -{ - memset(&flashPartitionTable, 0x00, sizeof(flashPartitionTable)); - - bool haveFlash = flashDeviceInit(flashConfig); - - flashConfigurePartitions(); - - return haveFlash; -} - bool flashIsReady(void) { return flashDevice.vTable->isReady(&flashDevice); @@ -282,18 +270,12 @@ const flashGeometry_t *flashGetGeometry(void) * * Partitions are required so that Badblock management (inc spare blocks), FlashFS (Blackbox Logging), Configuration and Firmware can be kept separate and tracked. * - * Currently, to keep things simple (and working), the following rules apply: - * - * 1) order of partitions in the paritions table strictly defined as follows - * - * BAD BLOCK MANAGEMENT - * FIRMWARE - * FLASH FS - * - * 2) If firmware or bootloader doesn't use or care about a particular type partition the corresponding entry should be empty, i.e. partition table entry memset to 0x00. - * - * 3) flash FS must start at sector 0. IMPORTANT: There is existing blackbox/flash FS code the relies on this!!! + * XXX FIXME + * XXX Note that Flash FS must start at sector 0. + * XXX There is existing blackbox/flash FS code the relies on this!!! + * XXX This restriction can and will be fixed by creating a set of flash operation functions that take partition as an additional parameter. */ + static void flashConfigurePartitions(void) { @@ -305,7 +287,7 @@ static void flashConfigurePartitions(void) flashSector_t startSector = 0; flashSector_t endSector = flashGeometry->sectors - 1; // 0 based index - const flashPartition_t *badBlockPartition = flashFindPartitionByUsage(FLASH_PARTITION_BADBLOCK_MANAGEMENT); + const flashPartition_t *badBlockPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_BADBLOCK_MANAGEMENT); if (badBlockPartition) { endSector = badBlockPartition->startSector - 1; } @@ -320,39 +302,38 @@ static void flashConfigurePartitions(void) startSector = (endSector + 1) - firmwareSectors; // + 1 for inclusive - const flashPartition_t firmwarePartition = { - .usage = FLASH_PARTITION_FIRMWARE, - .startSector = startSector, - .endSector = endSector - }; + flashPartitionSet(FLASH_PARTITION_TYPE_FIRMWARE, startSector, endSector); endSector = startSector - 1; startSector = 0; +#endif - flashSetPartition(1, &firmwarePartition); +#if defined(EEPROM_IN_EXTERNAL_FLASH) + const uint32_t configSize = EEPROM_SIZE; + flashSector_t configSectors = (configSize / flashGeometry->sectorSize); + + if (configSize % flashGeometry->sectorSize > 0) { + configSectors++; // needs a portion of a sector. + } + + startSector = (endSector + 1) - configSectors; // + 1 for inclusive + + flashPartitionSet(FLASH_PARTITION_TYPE_CONFIG, startSector, endSector); + + endSector = startSector - 1; + startSector = 0; #endif #ifdef USE_FLASHFS - const flashPartition_t flashFsPartition = { - .usage = FLASH_PARTITION_FLASHFS, - .startSector = startSector, - .endSector = endSector - }; - - flashSetPartition(2, &flashFsPartition); + flashPartitionSet(FLASH_PARTITION_TYPE_FLASHFS, startSector, endSector); #endif } -void flashSetPartition(uint8_t index, const flashPartition_t *partition) -{ - memcpy(&flashPartitionTable.partitions[index], partition, sizeof(*partition)); -} - -const flashPartition_t *flashFindPartitionByUsage(uint8_t usage) +flashPartition_t *flashPartitionFindByType(uint8_t type) { for (int index = 0; index < FLASH_MAX_PARTITIONS; index++) { flashPartition_t *candidate = &flashPartitionTable.partitions[index]; - if (candidate->usage == usage) { + if (candidate->type == type) { return candidate; } } @@ -360,4 +341,58 @@ const flashPartition_t *flashFindPartitionByUsage(uint8_t usage) return NULL; } +const flashPartition_t *flashPartitionFindByIndex(uint8_t index) +{ + if (index >= flashPartitions) { + return NULL; + } + + return &flashPartitionTable.partitions[index]; +} + +void flashPartitionSet(uint8_t type, uint32_t startSector, uint32_t endSector) +{ + flashPartition_t *entry = flashPartitionFindByType(type); + + if (!entry) { + if (flashPartitions == FLASH_MAX_PARTITIONS - 1) { + return; + } + entry = &flashPartitionTable.partitions[flashPartitions++]; + } + + entry->type = type; + entry->startSector = startSector; + entry->endSector = endSector; +} + +// Must be in sync with FLASH_PARTITION_TYPE +static const char *flashPartitionNames[] = { + "UNKNOWN ", + "PARTITION", + "FLASHFS ", + "BBMGMT ", + "FIRMWARE ", + "CONFIG ", +}; + +const char *flashPartitionGetTypeName(flashPartitionType_e type) +{ + if (type < ARRAYLEN(flashPartitionNames)) { + return flashPartitionNames[type]; + } + + return NULL; +} + +bool flashInit(const flashConfig_t *flashConfig) +{ + memset(&flashPartitionTable, 0x00, sizeof(flashPartitionTable)); + + bool haveFlash = flashDeviceInit(flashConfig); + + flashConfigurePartitions(); + + return haveFlash; +} #endif // USE_FLASH_CHIP diff --git a/src/main/drivers/flash.h b/src/main/drivers/flash.h index 1ccd869cc4..330674372e 100644 --- a/src/main/drivers/flash.h +++ b/src/main/drivers/flash.h @@ -67,23 +67,30 @@ const flashGeometry_t *flashGetGeometry(void); // typedef struct flashPartition_s { - uint8_t usage; + uint8_t type; flashSector_t startSector; flashSector_t endSector; } flashPartition_t; #define FLASH_PARTITION_SECTOR_COUNT(partition) (partition->endSector + 1 - partition->startSector) // + 1 for inclusive, start and end sector can be the same sector. -#define FLASH_PARTITION_UNKNOWN 0 -#define FLASH_PARTITION_FLASHFS 1 -#define FLASH_PARTITION_BADBLOCK_MANAGEMENT 2 -#define FLASH_PARTITION_FIRMWARE 3 - -#define FLASH_MAX_PARTITIONS 3 +// Must be in sync with flashPartitionTypeNames[] +// Should not be deleted or reordered once the code is writing a table to a flash. +typedef enum { + FLASH_PARTITION_TYPE_UNKNOWN = 0, + FLASH_PARTITION_TYPE_PARTITION_TABLE, + FLASH_PARTITION_TYPE_FLASHFS, + FLASH_PARTITION_TYPE_BADBLOCK_MANAGEMENT, + FLASH_PARTITION_TYPE_FIRMWARE, + FLASH_PARTITION_TYPE_CONFIG, + FLASH_MAX_PARTITIONS +} flashPartitionType_e; typedef struct flashPartitionTable_s { flashPartition_t partitions[FLASH_MAX_PARTITIONS]; } flashPartitionTable_t; -void flashSetPartition(uint8_t index, const flashPartition_t *partition); -const flashPartition_t *flashFindPartitionByUsage(uint8_t usage); +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); diff --git a/src/main/drivers/flash_w25n01g.c b/src/main/drivers/flash_w25n01g.c index f65c6965b4..0cb3f287af 100644 --- a/src/main/drivers/flash_w25n01g.c +++ b/src/main/drivers/flash_w25n01g.c @@ -325,12 +325,6 @@ static void w25n01g_writeEnable(flashDevice_t *fdevice) */ const flashVTable_t w25n01g_vTable; -static const flashPartition_t badBlockPartition = { - .usage = FLASH_PARTITION_BADBLOCK_MANAGEMENT, - .startSector = W25N01G_BB_MANAGEMENT_START_BLOCK, - .endSector = W25N01G_BB_MANAGEMENT_START_BLOCK + W25N01G_BB_MANAGEMENT_BLOCKS - 1 // -1 for inclusive, 0 based. -}; - static void w25n01g_deviceInit(flashDevice_t *flashdev); bool w25n01g_detect(flashDevice_t *fdevice, uint32_t chipID) @@ -366,7 +360,9 @@ bool w25n01g_detect(flashDevice_t *fdevice, uint32_t chipID) fdevice->geometry.sectorSize = fdevice->geometry.pagesPerSector * fdevice->geometry.pageSize; fdevice->geometry.totalSize = fdevice->geometry.sectorSize * fdevice->geometry.sectors; - flashSetPartition(0, &badBlockPartition); + flashPartitionSet(FLASH_PARTITION_TYPE_BADBLOCK_MANAGEMENT, + W25N01G_BB_MANAGEMENT_START_BLOCK, + W25N01G_BB_MANAGEMENT_START_BLOCK + W25N01G_BB_MANAGEMENT_BLOCKS - 1); fdevice->couldBeBusy = true; // Just for luck we'll assume the chip could be busy even though it isn't specced to be diff --git a/src/main/io/flashfs.c b/src/main/io/flashfs.c index 11d58b0917..6c0e1a6f72 100644 --- a/src/main/io/flashfs.c +++ b/src/main/io/flashfs.c @@ -595,11 +595,11 @@ void flashfsClose(void) /** * Call after initializing the flash chip in order to set up the filesystem. */ -void flashfsInit() +void flashfsInit(void) { flashfsSize = 0; - flashPartition = flashFindPartitionByUsage(FLASH_PARTITION_FLASHFS); + flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS); flashGeometry = flashGetGeometry(); if (!flashPartition) { diff --git a/src/main/msp/msp.c b/src/main/msp/msp.c index 35b4c1464c..0bc9c2b247 100644 --- a/src/main/msp/msp.c +++ b/src/main/msp/msp.c @@ -338,7 +338,7 @@ static void serializeDataflashSummaryReply(sbuf_t *dst) uint8_t flags = MSP_FLASHFS_FLAG_SUPPORTED; flags |= (flashfsIsReady() ? MSP_FLASHFS_FLAG_READY : 0); - const flashPartition_t *flashPartition = flashFindPartitionByUsage(FLASH_PARTITION_FLASHFS); + const flashPartition_t *flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS); sbufWriteU8(dst, flags); sbufWriteU32(dst, FLASH_PARTITION_SECTOR_COUNT(flashPartition)); diff --git a/src/main/osd/osd.c b/src/main/osd/osd.c index 0d28f7d2b8..ee881f42c5 100644 --- a/src/main/osd/osd.c +++ b/src/main/osd/osd.c @@ -433,7 +433,7 @@ static void osdGetBlackboxStatusString(char * buff) case BLACKBOX_DEVICE_FLASH: if (storageDeviceIsWorking) { - const flashPartition_t *flashPartition = flashFindPartitionByUsage(FLASH_PARTITION_FLASHFS); + const flashPartition_t *flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS); const flashGeometry_t *flashGeometry = flashGetGeometry(); storageTotal = ((FLASH_PARTITION_SECTOR_COUNT(flashPartition) * flashGeometry->sectorSize) / 1024);