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; +}