mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-15 04:15:44 +03:00
Partitions are now accessed by types rather than indices
This commit is contained in:
parent
92999681e3
commit
f5084a59bd
8 changed files with 117 additions and 67 deletions
|
@ -2219,8 +2219,20 @@ static void cliFlashInfo(char *cmdline)
|
||||||
|
|
||||||
cliPrintLinef("Flash sectors=%u, sectorSize=%u, pagesPerSector=%u, pageSize=%u, totalSize=%u",
|
cliPrintLinef("Flash sectors=%u, sectorSize=%u, pagesPerSector=%u, pageSize=%u, totalSize=%u",
|
||||||
layout->sectors, layout->sectorSize, layout->pagesPerSector, layout->pageSize, layout->totalSize);
|
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
|
#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",
|
cliPrintLinef("FlashFS size=%u, usedSize=%u",
|
||||||
FLASH_PARTITION_SECTOR_COUNT(flashPartition) * layout->sectorSize,
|
FLASH_PARTITION_SECTOR_COUNT(flashPartition) * layout->sectorSize,
|
||||||
|
|
|
@ -126,7 +126,7 @@ static void cmsx_Blackbox_GetDeviceStatus(void)
|
||||||
if (storageDeviceIsWorking) {
|
if (storageDeviceIsWorking) {
|
||||||
tfp_sprintf(cmsx_BlackboxStatus, "READY");
|
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();
|
const flashGeometry_t *flashGeometry = flashGetGeometry();
|
||||||
|
|
||||||
storageUsed = flashfsGetOffset() / 1024;
|
storageUsed = flashfsGetOffset() / 1024;
|
||||||
|
|
|
@ -43,8 +43,7 @@ static busDevice_t *busdev;
|
||||||
|
|
||||||
static flashDevice_t flashDevice;
|
static flashDevice_t flashDevice;
|
||||||
static flashPartitionTable_t flashPartitionTable;
|
static flashPartitionTable_t flashPartitionTable;
|
||||||
|
static int flashPartitions = 0;
|
||||||
static void flashConfigurePartitions(void);
|
|
||||||
|
|
||||||
#define FLASH_INSTRUCTION_RDID 0x9F
|
#define FLASH_INSTRUCTION_RDID 0x9F
|
||||||
|
|
||||||
|
@ -201,17 +200,6 @@ bool flashDeviceInit(const flashConfig_t *flashConfig)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool flashInit(const flashConfig_t *flashConfig)
|
|
||||||
{
|
|
||||||
memset(&flashPartitionTable, 0x00, sizeof(flashPartitionTable));
|
|
||||||
|
|
||||||
bool haveFlash = flashDeviceInit(flashConfig);
|
|
||||||
|
|
||||||
flashConfigurePartitions();
|
|
||||||
|
|
||||||
return haveFlash;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool flashIsReady(void)
|
bool flashIsReady(void)
|
||||||
{
|
{
|
||||||
return flashDevice.vTable->isReady(&flashDevice);
|
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.
|
* 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:
|
* XXX FIXME
|
||||||
*
|
* XXX Note that Flash FS must start at sector 0.
|
||||||
* 1) order of partitions in the paritions table strictly defined as follows
|
* 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.
|
||||||
* 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!!!
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void flashConfigurePartitions(void)
|
static void flashConfigurePartitions(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -305,7 +287,7 @@ static void flashConfigurePartitions(void)
|
||||||
flashSector_t startSector = 0;
|
flashSector_t startSector = 0;
|
||||||
flashSector_t endSector = flashGeometry->sectors - 1; // 0 based index
|
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) {
|
if (badBlockPartition) {
|
||||||
endSector = badBlockPartition->startSector - 1;
|
endSector = badBlockPartition->startSector - 1;
|
||||||
}
|
}
|
||||||
|
@ -320,39 +302,38 @@ static void flashConfigurePartitions(void)
|
||||||
|
|
||||||
startSector = (endSector + 1) - firmwareSectors; // + 1 for inclusive
|
startSector = (endSector + 1) - firmwareSectors; // + 1 for inclusive
|
||||||
|
|
||||||
const flashPartition_t firmwarePartition = {
|
flashPartitionSet(FLASH_PARTITION_TYPE_FIRMWARE, startSector, endSector);
|
||||||
.usage = FLASH_PARTITION_FIRMWARE,
|
|
||||||
.startSector = startSector,
|
|
||||||
.endSector = endSector
|
|
||||||
};
|
|
||||||
|
|
||||||
endSector = startSector - 1;
|
endSector = startSector - 1;
|
||||||
startSector = 0;
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef USE_FLASHFS
|
#ifdef USE_FLASHFS
|
||||||
const flashPartition_t flashFsPartition = {
|
flashPartitionSet(FLASH_PARTITION_TYPE_FLASHFS, startSector, endSector);
|
||||||
.usage = FLASH_PARTITION_FLASHFS,
|
|
||||||
.startSector = startSector,
|
|
||||||
.endSector = endSector
|
|
||||||
};
|
|
||||||
|
|
||||||
flashSetPartition(2, &flashFsPartition);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashSetPartition(uint8_t index, const flashPartition_t *partition)
|
flashPartition_t *flashPartitionFindByType(uint8_t type)
|
||||||
{
|
|
||||||
memcpy(&flashPartitionTable.partitions[index], partition, sizeof(*partition));
|
|
||||||
}
|
|
||||||
|
|
||||||
const flashPartition_t *flashFindPartitionByUsage(uint8_t usage)
|
|
||||||
{
|
{
|
||||||
for (int index = 0; index < FLASH_MAX_PARTITIONS; index++) {
|
for (int index = 0; index < FLASH_MAX_PARTITIONS; index++) {
|
||||||
flashPartition_t *candidate = &flashPartitionTable.partitions[index];
|
flashPartition_t *candidate = &flashPartitionTable.partitions[index];
|
||||||
if (candidate->usage == usage) {
|
if (candidate->type == type) {
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,4 +341,58 @@ const flashPartition_t *flashFindPartitionByUsage(uint8_t usage)
|
||||||
return NULL;
|
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
|
#endif // USE_FLASH_CHIP
|
||||||
|
|
|
@ -67,23 +67,30 @@ const flashGeometry_t *flashGetGeometry(void);
|
||||||
//
|
//
|
||||||
|
|
||||||
typedef struct flashPartition_s {
|
typedef struct flashPartition_s {
|
||||||
uint8_t usage;
|
uint8_t type;
|
||||||
flashSector_t startSector;
|
flashSector_t startSector;
|
||||||
flashSector_t endSector;
|
flashSector_t endSector;
|
||||||
} flashPartition_t;
|
} 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_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
|
// Must be in sync with flashPartitionTypeNames[]
|
||||||
#define FLASH_PARTITION_FLASHFS 1
|
// Should not be deleted or reordered once the code is writing a table to a flash.
|
||||||
#define FLASH_PARTITION_BADBLOCK_MANAGEMENT 2
|
typedef enum {
|
||||||
#define FLASH_PARTITION_FIRMWARE 3
|
FLASH_PARTITION_TYPE_UNKNOWN = 0,
|
||||||
|
FLASH_PARTITION_TYPE_PARTITION_TABLE,
|
||||||
#define FLASH_MAX_PARTITIONS 3
|
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 {
|
typedef struct flashPartitionTable_s {
|
||||||
flashPartition_t partitions[FLASH_MAX_PARTITIONS];
|
flashPartition_t partitions[FLASH_MAX_PARTITIONS];
|
||||||
} flashPartitionTable_t;
|
} flashPartitionTable_t;
|
||||||
|
|
||||||
void flashSetPartition(uint8_t index, const flashPartition_t *partition);
|
void flashPartitionSet(uint8_t index, uint32_t startSector, uint32_t endSector);
|
||||||
const flashPartition_t *flashFindPartitionByUsage(uint8_t usage);
|
flashPartition_t *flashPartitionFindByType(flashPartitionType_e type);
|
||||||
|
const flashPartition_t *flashPartitionFindByIndex(uint8_t index);
|
||||||
|
const char *flashPartitionGetTypeName(flashPartitionType_e type);
|
||||||
|
|
|
@ -325,12 +325,6 @@ static void w25n01g_writeEnable(flashDevice_t *fdevice)
|
||||||
*/
|
*/
|
||||||
const flashVTable_t w25n01g_vTable;
|
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);
|
static void w25n01g_deviceInit(flashDevice_t *flashdev);
|
||||||
|
|
||||||
bool w25n01g_detect(flashDevice_t *fdevice, uint32_t chipID)
|
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.sectorSize = fdevice->geometry.pagesPerSector * fdevice->geometry.pageSize;
|
||||||
fdevice->geometry.totalSize = fdevice->geometry.sectorSize * fdevice->geometry.sectors;
|
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
|
fdevice->couldBeBusy = true; // Just for luck we'll assume the chip could be busy even though it isn't specced to be
|
||||||
|
|
||||||
|
|
|
@ -595,11 +595,11 @@ void flashfsClose(void)
|
||||||
/**
|
/**
|
||||||
* Call after initializing the flash chip in order to set up the filesystem.
|
* Call after initializing the flash chip in order to set up the filesystem.
|
||||||
*/
|
*/
|
||||||
void flashfsInit()
|
void flashfsInit(void)
|
||||||
{
|
{
|
||||||
flashfsSize = 0;
|
flashfsSize = 0;
|
||||||
|
|
||||||
flashPartition = flashFindPartitionByUsage(FLASH_PARTITION_FLASHFS);
|
flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS);
|
||||||
flashGeometry = flashGetGeometry();
|
flashGeometry = flashGetGeometry();
|
||||||
|
|
||||||
if (!flashPartition) {
|
if (!flashPartition) {
|
||||||
|
|
|
@ -338,7 +338,7 @@ static void serializeDataflashSummaryReply(sbuf_t *dst)
|
||||||
uint8_t flags = MSP_FLASHFS_FLAG_SUPPORTED;
|
uint8_t flags = MSP_FLASHFS_FLAG_SUPPORTED;
|
||||||
flags |= (flashfsIsReady() ? MSP_FLASHFS_FLAG_READY : 0);
|
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);
|
sbufWriteU8(dst, flags);
|
||||||
sbufWriteU32(dst, FLASH_PARTITION_SECTOR_COUNT(flashPartition));
|
sbufWriteU32(dst, FLASH_PARTITION_SECTOR_COUNT(flashPartition));
|
||||||
|
|
|
@ -433,7 +433,7 @@ static void osdGetBlackboxStatusString(char * buff)
|
||||||
case BLACKBOX_DEVICE_FLASH:
|
case BLACKBOX_DEVICE_FLASH:
|
||||||
if (storageDeviceIsWorking) {
|
if (storageDeviceIsWorking) {
|
||||||
|
|
||||||
const flashPartition_t *flashPartition = flashFindPartitionByUsage(FLASH_PARTITION_FLASHFS);
|
const flashPartition_t *flashPartition = flashPartitionFindByType(FLASH_PARTITION_TYPE_FLASHFS);
|
||||||
const flashGeometry_t *flashGeometry = flashGetGeometry();
|
const flashGeometry_t *flashGeometry = flashGetGeometry();
|
||||||
|
|
||||||
storageTotal = ((FLASH_PARTITION_SECTOR_COUNT(flashPartition) * flashGeometry->sectorSize) / 1024);
|
storageTotal = ((FLASH_PARTITION_SECTOR_COUNT(flashPartition) * flashGeometry->sectorSize) / 1024);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue