From 517d55a2ce8ae37779d2383780ed87c8430a11d2 Mon Sep 17 00:00:00 2001 From: zhaoxingyu1 Date: Wed, 7 Aug 2024 18:48:20 +0800 Subject: [PATCH] nvs: modify nvs block size and block numbers mtd_config_fs/Kconfig: update nvs block size and block number to configurable Signed-off-by: zhaoxingyu1 --- drivers/mtd/Kconfig | 7 ++++ drivers/mtd/mtd_config_fs.c | 67 ++++++++++++++++++++----------------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 7ed1aae7d5..0dc2f38c6f 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -202,6 +202,13 @@ config MTD_WRITE_ALIGN_SIZE ---help--- align size will be one of 1,2,4,8,16 +config MTD_BLOCKSIZE_MULTIPLE + int "Set NVS blocksize multiple" + default 1 + depends on MTD_CONFIG_FAIL_SAFE + ---help--- + The size of a multiple of blocksize compared to erasize + endif # MTD_CONFIG comment "MTD Device Drivers" diff --git a/drivers/mtd/mtd_config_fs.c b/drivers/mtd/mtd_config_fs.c index da361790b0..411ca204e0 100644 --- a/drivers/mtd/mtd_config_fs.c +++ b/drivers/mtd/mtd_config_fs.c @@ -93,7 +93,8 @@ struct nvs_fs { FAR struct mtd_dev_s *mtd; /* MTD device */ - struct mtd_geometry_s geo; + uint32_t blocksize; /* Size of one nvs block */ + uint32_t nblocks; /* Number of nvs blocks */ uint8_t erasestate; /* Erased value */ uint32_t ate_wra; /* Next alloc table entry * Write address @@ -203,7 +204,7 @@ static int nvs_flash_wrt(FAR struct nvs_fs *fs, uint32_t addr, off_t offset; int ret; - offset = fs->geo.erasesize * (addr >> ADDR_BLOCK_SHIFT); + offset = fs->blocksize * (addr >> ADDR_BLOCK_SHIFT); offset += addr & ADDR_OFFS_MASK; ret = MTD_WRITE(fs->mtd, offset, len, data); @@ -229,7 +230,7 @@ static int nvs_flash_rd(FAR struct nvs_fs *fs, uint32_t addr, off_t offset; int ret; - offset = fs->geo.erasesize * (addr >> ADDR_BLOCK_SHIFT); + offset = fs->blocksize * (addr >> ADDR_BLOCK_SHIFT); offset += addr & ADDR_OFFS_MASK; ret = MTD_READ(fs->mtd, offset, len, data); @@ -461,7 +462,9 @@ static int nvs_flash_erase_block(FAR struct nvs_fs *fs, uint32_t addr) int rc; finfo("Erasing addr %" PRIx32 "\n", addr); - rc = MTD_ERASE(fs->mtd, addr >> ADDR_BLOCK_SHIFT, 1); + rc = MTD_ERASE(fs->mtd, + CONFIG_MTD_BLOCKSIZE_MULTIPLE * (addr >> ADDR_BLOCK_SHIFT), + CONFIG_MTD_BLOCKSIZE_MULTIPLE); if (rc < 0) { ferr("Erasing failed %d\n", rc); @@ -549,7 +552,7 @@ static int nvs_ate_valid(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { if (nvs_ate_crc8_check(entry) || - entry->offset >= (fs->geo.erasesize - sizeof(struct nvs_ate))) + entry->offset >= (fs->blocksize - sizeof(struct nvs_ate))) { return 0; } @@ -579,7 +582,7 @@ static int nvs_close_ate_valid(FAR struct nvs_fs *fs, return 0; } - if ((fs->geo.erasesize - entry->offset) % sizeof(struct nvs_ate)) + if ((fs->blocksize - entry->offset) % sizeof(struct nvs_ate)) { return 0; } @@ -788,7 +791,7 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, *addr += sizeof(struct nvs_ate); if (((*addr) & ADDR_OFFS_MASK) != - (fs->geo.erasesize - sizeof(struct nvs_ate))) + (fs->blocksize - sizeof(struct nvs_ate))) { return 0; } @@ -797,7 +800,7 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, if (((*addr) >> ADDR_BLOCK_SHIFT) == 0) { - *addr += ((fs->geo.neraseblocks - 1) << ADDR_BLOCK_SHIFT); + *addr += ((fs->nblocks - 1) << ADDR_BLOCK_SHIFT); } else { @@ -847,9 +850,9 @@ static int nvs_prev_ate(FAR struct nvs_fs *fs, FAR uint32_t *addr, static void nvs_block_advance(FAR struct nvs_fs *fs, FAR uint32_t *addr) { *addr += (1 << ADDR_BLOCK_SHIFT); - if ((*addr >> ADDR_BLOCK_SHIFT) == fs->geo.neraseblocks) + if ((*addr >> ADDR_BLOCK_SHIFT) == fs->nblocks) { - *addr -= (fs->geo.neraseblocks << ADDR_BLOCK_SHIFT); + *addr -= (fs->nblocks << ADDR_BLOCK_SHIFT); } } @@ -875,7 +878,7 @@ static int nvs_block_close(FAR struct nvs_fs *fs) (fs->ate_wra + sizeof(struct nvs_ate)) & ADDR_OFFS_MASK; fs->ate_wra &= ADDR_BLOCK_MASK; - fs->ate_wra += fs->geo.erasesize - sizeof(struct nvs_ate); + fs->ate_wra += fs->blocksize - sizeof(struct nvs_ate); nvs_ate_crc8_update(&close_ate); @@ -950,7 +953,7 @@ static int nvs_gc(FAR struct nvs_fs *fs) sec_addr = (fs->ate_wra & ADDR_BLOCK_MASK); nvs_block_advance(fs, &sec_addr); - gc_addr = sec_addr + fs->geo.erasesize - sizeof(struct nvs_ate); + gc_addr = sec_addr + fs->blocksize - sizeof(struct nvs_ate); finfo("gc: set, sec_addr %" PRIx32 ", gc_addr %" PRIx32 "\n", sec_addr, gc_addr); @@ -1068,8 +1071,9 @@ static int nvs_startup(FAR struct nvs_fs *fs) uint32_t second_addr; uint32_t last_addr; struct nvs_ate second_ate; + struct mtd_geometry_s geo; - /* Initialize addr to 0 for the case fs->geo.neraseblocks == 0. This + /* Initialize addr to 0 for the case fs->nblocks == 0. This * should never happen but both * Coverity and GCC believe the contrary. */ @@ -1087,7 +1091,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) */ rc = MTD_IOCTL(fs->mtd, MTDIOC_GEOMETRY, - (unsigned long)((uintptr_t)&(fs->geo))); + (unsigned long)((uintptr_t)&(geo))); if (rc < 0) { ferr("ERROR: MTD ioctl(MTDIOC_GEOMETRY) failed: %d\n", rc); @@ -1102,9 +1106,12 @@ static int nvs_startup(FAR struct nvs_fs *fs) return rc; } + fs->blocksize = CONFIG_MTD_BLOCKSIZE_MULTIPLE * geo.erasesize; + fs->nblocks = geo.neraseblocks / CONFIG_MTD_BLOCKSIZE_MULTIPLE; + /* Check the number of blocks, it should be at least 2. */ - if (fs->geo.neraseblocks < 2) + if (fs->nblocks < 2) { ferr("Configuration error - block count\n"); return -EINVAL; @@ -1114,10 +1121,10 @@ static int nvs_startup(FAR struct nvs_fs *fs) * a closed block, this is where NVS can write. */ - for (i = 0; i < fs->geo.neraseblocks; i++) + for (i = 0; i < fs->nblocks; i++) { addr = (i << ADDR_BLOCK_SHIFT) + - (uint16_t)(fs->geo.erasesize - sizeof(struct nvs_ate)); + (uint16_t)(fs->blocksize - sizeof(struct nvs_ate)); rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, sizeof(struct nvs_ate)); fwarn("rc=%d\n", rc); @@ -1143,12 +1150,12 @@ static int nvs_startup(FAR struct nvs_fs *fs) /* All blocks are closed, this is not a nvs fs */ - if (closed_blocks == fs->geo.neraseblocks) + if (closed_blocks == fs->nblocks) { return -EDEADLK; } - if (i == fs->geo.neraseblocks) + if (i == fs->nblocks) { /* None of the blocks where closed, in most cases we can set * the address to the first block, except when there are only @@ -1224,7 +1231,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) addr = fs->ate_wra & ADDR_BLOCK_MASK; nvs_block_advance(fs, &addr); - rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, fs->geo.erasesize); + rc = nvs_flash_cmp_const(fs, addr, fs->erasestate, fs->blocksize); if (rc < 0) { return rc; @@ -1241,7 +1248,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) addr = fs->ate_wra + sizeof(struct nvs_ate); while ((addr & ADDR_OFFS_MASK) < - (fs->geo.erasesize - sizeof(struct nvs_ate))) + (fs->blocksize - sizeof(struct nvs_ate))) { rc = nvs_flash_ate_rd(fs, addr, &gc_done_ate); if (rc) @@ -1279,7 +1286,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) } fs->ate_wra &= ADDR_BLOCK_MASK; - fs->ate_wra += (fs->geo.erasesize - 2 * sizeof(struct nvs_ate)); + fs->ate_wra += (fs->blocksize - 2 * sizeof(struct nvs_ate)); fs->data_wra = (fs->ate_wra & ADDR_BLOCK_MASK); finfo("GC when data_wra=0x%" PRIx32 "\n", fs->data_wra); rc = nvs_gc(fs); @@ -1313,7 +1320,7 @@ static int nvs_startup(FAR struct nvs_fs *fs) * valid data (this also avoids closing a block without any data). */ - if (((fs->ate_wra + 2 * sizeof(struct nvs_ate)) == fs->geo.erasesize) && + if (((fs->ate_wra + 2 * sizeof(struct nvs_ate)) == fs->blocksize) && (fs->data_wra != (fs->ate_wra & ADDR_BLOCK_MASK))) { rc = nvs_flash_erase_block(fs, fs->ate_wra); @@ -1411,13 +1418,13 @@ end: */ if ((!rc) && ((fs->ate_wra & ADDR_OFFS_MASK) == - (fs->geo.erasesize - 2 * sizeof(struct nvs_ate)))) + (fs->blocksize - 2 * sizeof(struct nvs_ate)))) { rc = nvs_add_gc_done_ate(fs); } finfo("%" PRIu32 " Eraseblocks of %" PRIu32 " bytes\n", - fs->geo.neraseblocks, fs->geo.erasesize); + fs->nblocks, fs->blocksize); finfo("alloc wra: %" PRIu32 ", 0x%" PRIx32 "\n", (fs->ate_wra >> ADDR_BLOCK_SHIFT), (fs->ate_wra & ADDR_OFFS_MASK)); finfo("data wra: %" PRIu32 ", 0x%" PRIx32 "\n", @@ -1581,7 +1588,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, finfo("key_size=%zu, len=%zu, data_size = %zu\n", key_size, pdata->len, data_size); - if ((data_size > (fs->geo.erasesize - 3 * sizeof(struct nvs_ate))) || + if ((data_size > (fs->blocksize - 3 * sizeof(struct nvs_ate))) || ((pdata->len > 0) && (pdata->configdata == NULL))) { return -EINVAL; @@ -1696,7 +1703,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, block_to_write_befor_gc = fs->ate_wra >> ADDR_BLOCK_SHIFT; while (1) { - if (gc_count == fs->geo.neraseblocks) + if (gc_count == fs->nblocks) { /* Gc'ed all blocks, no extra space will be created * by extra gc. @@ -1716,10 +1723,10 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs, /* If gc touched second latest ate, search for it again */ - if (gc_count >= fs->geo.neraseblocks - 1 - - (block_to_write_befor_gc + fs->geo.neraseblocks - + if (gc_count >= fs->nblocks - 1 - + (block_to_write_befor_gc + fs->nblocks - (hist_addr >> ADDR_BLOCK_SHIFT)) - % fs->geo.neraseblocks) + % fs->nblocks) { rc = nvs_read_entry(fs, key, key_size, NULL, 0, &hist_addr);