Skip to content

nvs: also support sector_size of 64KB #91389

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/zephyr/fs/nvs.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct nvs_fs {
/** Data write address */
uint32_t data_wra;
/** File system is split into sectors, each sector must be multiple of erase-block-size */
uint16_t sector_size;
uint32_t sector_size;
/** Number of sectors in the file system */
uint16_t sector_count;
/** Flag indicating if the file system is initialized */
Expand Down
7 changes: 7 additions & 0 deletions subsys/fs/nvs/nvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1025,6 +1025,13 @@ int nvs_mount(struct nvs_fs *fs)
return -EINVAL;
}

/* check that sector size is not greater than max */
if (fs->sector_size > NVS_MAX_SECTOR_SIZE) {
LOG_ERR("Sector size %u too large, maximum is %zu",
fs->sector_size, NVS_MAX_SECTOR_SIZE);
return -EINVAL;
}

/* check that sector size is a multiple of pagesize */
rc = flash_get_page_info_by_offs(fs->flash_device, fs->offset, &info);
if (rc) {
Expand Down
2 changes: 2 additions & 0 deletions subsys/fs/nvs/nvs_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ extern "C" {
#define ADDR_SECT_SHIFT 16
#define ADDR_OFFS_MASK 0x0000FFFF

#define NVS_MAX_SECTOR_SIZE KB(64)

/*
* Status return values
*/
Expand Down
41 changes: 41 additions & 0 deletions tests/subsys/fs/nvs/boards/native_sim_64kb_erase_block.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) 2025 Google LLC
*
* SPDX-License-Identifier: Apache-2.0
*/

&flash0 {
erase-block-size = <0x10000>;

/*
* Delete old partitions that were not aligned on 64kb addresses and
* create new ones that are aligned.
*/
/delete-node/ partitions;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0x00010000>;
};
slot0_partition: partition@10000 {
label = "image-0";
reg = <0x00010000 0x00070000>;
};
slot1_partition: partition@80000 {
label = "image-1";
reg = <0x00080000 0x00070000>;
};
scratch_partition: partition@f0000 {
label = "image-scratch";
reg = <0x000f0000 0x00020000>;
};
storage_partition: partition@110000 {
label = "storage";
reg = <0x00110000 0x00050000>;
};
};
};
37 changes: 28 additions & 9 deletions tests/subsys/fs/nvs/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,14 @@ ZTEST_SUITE(nvs, NULL, setup, before, after, NULL);
ZTEST_F(nvs, test_nvs_mount)
{
int err;
size_t orig_sector_size = fixture->fs.sector_size;

fixture->fs.sector_size = KB(128);
err = nvs_mount(&fixture->fs);
zassert_true(err == -EINVAL,
"nvs_mount did not return expected err for invalid sector_size");

fixture->fs.sector_size = orig_sector_size;
err = nvs_mount(&fixture->fs);
zassert_true(err == 0, "nvs_mount call failure: %d", err);
}
Expand Down Expand Up @@ -307,7 +314,7 @@ static void write_content(uint16_t max_id, uint16_t begin, uint16_t end,

for (uint16_t i = begin; i < end; i++) {
uint8_t id = (i % max_id);
uint8_t id_data = id + max_id * (i / max_id);
uint8_t id_data = id + max_id * ((i % 256) / max_id);

memset(buf, id_data, sizeof(buf));

Expand Down Expand Up @@ -346,13 +353,25 @@ ZTEST_F(nvs, test_nvs_gc_3sectors)

const uint16_t max_id = 10;
/* 50th write will trigger 1st GC. */
const uint16_t max_writes = 51;
uint16_t max_writes = 51;
/* 75th write will trigger 2st GC. */
const uint16_t max_writes_2 = 51 + 25;
uint16_t max_writes_2 = 51 + 25;
/* 100th write will trigger 3st GC. */
const uint16_t max_writes_3 = 51 + 25 + 25;
uint16_t max_writes_3 = 51 + 25 + 25;
/* 125th write will trigger 4st GC. */
const uint16_t max_writes_4 = 51 + 25 + 25 + 25;
uint16_t max_writes_4 = 51 + 25 + 25 + 25;

if (fixture->fs.sector_size == KB(64)) {
/* write 1637 will trigger 1st GC. */
/* write 3274 will trigger 2nd GC. */
max_writes = 3275;
/* write 4911 will trigger 3rd GC. */
max_writes_2 = 3275 + 1637;
/* write 6548 will trigger 4th GC. */
max_writes_3 = 3275 + 1637 + 1637;
/* write 8185 will trigger 5th GC. */
max_writes_4 = 3275 + 1637 + 1637 + 1637;
}

fixture->fs.sector_count = 3;

Expand All @@ -361,7 +380,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors)
zassert_equal(fixture->fs.ate_wra >> ADDR_SECT_SHIFT, 0,
"unexpected write sector");

/* Trigger 1st GC */
/* Trigger 1st and 2nd GC */
write_content(max_id, 0, max_writes, &fixture->fs);

/* sector sequence: empty,closed, write */
Expand All @@ -376,7 +395,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors)
"unexpected write sector");
check_content(max_id, &fixture->fs);

/* Trigger 2nd GC */
/* Trigger 3rd GC */
write_content(max_id, max_writes, max_writes_2, &fixture->fs);

/* sector sequence: write, empty, closed */
Expand All @@ -391,7 +410,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors)
"unexpected write sector");
check_content(max_id, &fixture->fs);

/* Trigger 3rd GC */
/* Trigger 4th GC */
write_content(max_id, max_writes_2, max_writes_3, &fixture->fs);

/* sector sequence: closed, write, empty */
Expand All @@ -406,7 +425,7 @@ ZTEST_F(nvs, test_nvs_gc_3sectors)
"unexpected write sector");
check_content(max_id, &fixture->fs);

/* Trigger 4th GC */
/* Trigger 5th GC */
write_content(max_id, max_writes_3, max_writes_4, &fixture->fs);

/* sector sequence: empty,closed, write */
Expand Down
3 changes: 3 additions & 0 deletions tests/subsys/fs/nvs/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ tests:
- CONFIG_NVS_LOOKUP_CACHE=y
- CONFIG_NVS_LOOKUP_CACHE_SIZE=64
platform_allow: native_sim
filesystem.nvs.64kb_erase_block:
extra_args: DTC_OVERLAY_FILE=boards/native_sim_64kb_erase_block.overlay
platform_allow: native_sim