From 076282a117fea40fdfbe7da040e6c2f430881990 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 3 Jun 2020 18:33:09 +0000 Subject: [PATCH] subsys/fs/nvs: Use flash_get_parameters() to get erase value Use new flash API call to obtain erase value instead of relaying on hardcoded literals. Signed-off-by: Dominik Ermel --- include/fs/nvs.h | 1 + subsys/fs/nvs/nvs.c | 40 ++++++++++++------- .../fs/nvs/boards/qemu_x86_ev_0x00.overlay | 9 +++++ tests/subsys/fs/nvs/testcase.yaml | 3 ++ 4 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay diff --git a/include/fs/nvs.h b/include/fs/nvs.h index ae200ea82b3..d58798b147e 100644 --- a/include/fs/nvs.h +++ b/include/fs/nvs.h @@ -57,6 +57,7 @@ struct nvs_fs { struct k_mutex nvs_lock; struct device *flash_device; + const struct flash_parameters *flash_parameters; }; /** diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index 6cef3e42a09..dd85b082715 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -66,7 +66,9 @@ static int nvs_flash_al_wrt(struct nvs_fs *fs, uint32_t addr, const void *data, } if (len) { memcpy(buf, data8, len); - (void)memset(buf + len, 0xff, fs->write_block_size - len); + (void)memset(buf + len, fs->flash_parameters->erase_value, + fs->write_block_size - len); + rc = flash_write(fs->flash_device, offset, buf, fs->write_block_size); if (rc) { @@ -221,7 +223,8 @@ static int nvs_flash_erase_sector(struct nvs_fs *fs, uint32_t addr) off_t offset; addr &= ADDR_SECT_MASK; - rc = nvs_flash_cmp_const(fs, addr, 0xff, fs->sector_size); + rc = nvs_flash_cmp_const(fs, addr, fs->flash_parameters->erase_value, + fs->sector_size); if (rc <= 0) { /* flash error or empty sector */ return rc; @@ -351,7 +354,7 @@ static int nvs_prev_ate(struct nvs_fs *fs, uint32_t *addr, struct nvs_ate *ate) return rc; } - rc = nvs_ate_cmp_const(&close_ate, 0xff); + rc = nvs_ate_cmp_const(&close_ate, fs->flash_parameters->erase_value); /* at the end of filesystem */ if (!rc) { *addr = fs->ate_wra; @@ -460,7 +463,7 @@ static int nvs_gc(struct nvs_fs *fs) return rc; } - rc = nvs_ate_cmp_const(&close_ate, 0xff); + rc = nvs_ate_cmp_const(&close_ate, fs->flash_parameters->erase_value); if (!rc) { rc = nvs_flash_erase_sector(fs, sec_addr); if (rc) { @@ -545,6 +548,7 @@ static int nvs_startup(struct nvs_fs *fs) */ uint32_t addr = 0U; uint16_t i, closed_sectors = 0; + uint8_t erase_value = fs->flash_parameters->erase_value; k_mutex_lock(&fs->nvs_lock, K_FOREVER); @@ -555,14 +559,14 @@ static int nvs_startup(struct nvs_fs *fs) for (i = 0; i < fs->sector_count; i++) { addr = (i << ADDR_SECT_SHIFT) + (uint16_t)(fs->sector_size - ate_size); - rc = nvs_flash_cmp_const(fs, addr, 0xff, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr, erase_value, + sizeof(struct nvs_ate)); if (rc) { /* closed sector */ closed_sectors++; nvs_sector_advance(fs, &addr); - rc = nvs_flash_cmp_const(fs, addr, 0xff, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr, erase_value, + sizeof(struct nvs_ate)); if (!rc) { /* open sector */ break; @@ -581,8 +585,8 @@ static int nvs_startup(struct nvs_fs *fs) * two sectors. Then we can only set it to the first sector if * the last sector contains no ate's. So we check this first */ - rc = nvs_flash_cmp_const(fs, addr - ate_size, 0xff, - sizeof(struct nvs_ate)); + rc = nvs_flash_cmp_const(fs, addr - ate_size, erase_value, + sizeof(struct nvs_ate)); if (!rc) { /* empty ate */ nvs_sector_advance(fs, &addr); @@ -590,7 +594,7 @@ static int nvs_startup(struct nvs_fs *fs) } /* addr contains address of the last ate in the most recent sector - * search for the first ate containing all 0xff + * search for the first ate containing all cells erased. */ fs->ate_wra = addr - ate_size; fs->data_wra = addr & ADDR_SECT_MASK; @@ -601,7 +605,8 @@ static int nvs_startup(struct nvs_fs *fs) goto end; } - rc = nvs_ate_cmp_const(&last_ate, 0xff); + rc = nvs_ate_cmp_const(&last_ate, erase_value); + if (!rc) { /* found ff empty location */ break; @@ -630,7 +635,8 @@ static int nvs_startup(struct nvs_fs *fs) while (fs->ate_wra > fs->data_wra) { empty_len = fs->ate_wra - fs->data_wra; - rc = nvs_flash_cmp_const(fs, fs->data_wra, 0xff, empty_len); + rc = nvs_flash_cmp_const(fs, fs->data_wra, erase_value, + empty_len); if (rc < 0) { goto end; } @@ -647,7 +653,7 @@ static int nvs_startup(struct nvs_fs *fs) */ addr = fs->ate_wra & ADDR_SECT_MASK; nvs_sector_advance(fs, &addr); - rc = nvs_flash_cmp_const(fs, addr, 0xff, fs->sector_size); + rc = nvs_flash_cmp_const(fs, addr, erase_value, fs->sector_size); if (rc < 0) { goto end; } @@ -706,6 +712,12 @@ int nvs_init(struct nvs_fs *fs, const char *dev_name) return -ENXIO; } + fs->flash_parameters = flash_get_parameters(fs->flash_device); + if (fs->flash_parameters == NULL) { + LOG_ERR("Could not obtain flash parameters"); + return -EINVAL; + } + write_block_size = flash_get_write_block_size(fs->flash_device); /* check that the write block size is supported */ diff --git a/tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay b/tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay new file mode 100644 index 00000000000..0f122e34007 --- /dev/null +++ b/tests/subsys/fs/nvs/boards/qemu_x86_ev_0x00.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2020 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&sim_flash { + erase-value = < 0x00 >; +}; diff --git a/tests/subsys/fs/nvs/testcase.yaml b/tests/subsys/fs/nvs/testcase.yaml index f9e94b4b4fc..91aa32b3a22 100644 --- a/tests/subsys/fs/nvs/testcase.yaml +++ b/tests/subsys/fs/nvs/testcase.yaml @@ -1,3 +1,6 @@ tests: filesystem.nvs: platform_whitelist: qemu_x86 + filesystem.nvs_0x00: + extra_args: DTC_OVERLAY_FILE=boards/qemu_x86_ev_0x00.overlay + platform_whitelist: qemu_x86