From b09972b445ef4e85755917ded941e5b1ec4a27d9 Mon Sep 17 00:00:00 2001 From: Adrien Ricciardi Date: Wed, 26 Jun 2024 14:15:17 +0200 Subject: [PATCH] fs: nvs: Allow application to switch sector to get free space Add an API function allowing the application to determine the amount of free bytes in the current sector. Add a second API function allowing the application to switch to the next NVS sector, calling the garbage collector on such sector. The goal is togive more granularity to the application to control when the garbage collector is triggered. Signed-off-by: Adrien Ricciardi --- include/zephyr/fs/nvs.h | 24 ++++++++++++++++++++++++ subsys/fs/nvs/nvs.c | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/include/zephyr/fs/nvs.h b/include/zephyr/fs/nvs.h index 313e9016095c4f..df70b64f58bced 100644 --- a/include/zephyr/fs/nvs.h +++ b/include/zephyr/fs/nvs.h @@ -164,6 +164,30 @@ ssize_t nvs_read_hist(struct nvs_fs *fs, uint16_t id, void *data, size_t len, ui */ ssize_t nvs_calc_free_space(struct nvs_fs *fs); +/** + * @brief Tell how many contiguous free space remains in the currently active NVS sector. + * + * @param fs Pointer to the file system. + * + * @return Number of free bytes. + */ +size_t nvs_sector_max_data_size(struct nvs_fs *fs); + +/** + * @brief Close the currently active sector and switch to the next one. + * + * @note The garbage collector is called on the new sector. + * + * @warning This routine is made available for specific use cases. + * It breaks the aim of the NVS to avoid any unnecessary flash erases. + * Using this routine extensively can result in premature failure of the flash device. + * + * @param fs Pointer to the file system. + * + * @return 0 on success. On error, returns negative value of errno.h defined error codes. + */ +int nvs_sector_use_next(struct nvs_fs *fs); + /** * @} */ diff --git a/subsys/fs/nvs/nvs.c b/subsys/fs/nvs/nvs.c index c9af07f4f1f56d..5d0a5f5b724c6c 100644 --- a/subsys/fs/nvs/nvs.c +++ b/subsys/fs/nvs/nvs.c @@ -1358,3 +1358,40 @@ ssize_t nvs_calc_free_space(struct nvs_fs *fs) } return free_space; } + +size_t nvs_sector_max_data_size(struct nvs_fs *fs) +{ + size_t ate_size; + + if (!fs->ready) { + LOG_ERR("NVS not initialized"); + return -EACCES; + } + + ate_size = nvs_al_size(fs, sizeof(struct nvs_ate)); + + return fs->ate_wra - fs->data_wra - ate_size - NVS_DATA_CRC_SIZE; +} + +int nvs_sector_use_next(struct nvs_fs *fs) +{ + int ret; + + if (!fs->ready) { + LOG_ERR("NVS not initialized"); + return -EACCES; + } + + k_mutex_lock(&fs->nvs_lock, K_FOREVER); + + ret = nvs_sector_close(fs); + if (ret != 0) { + goto end; + } + + ret = nvs_gc(fs); + +end: + k_mutex_unlock(&fs->nvs_lock); + return ret; +}