This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 1b587db6675bbbc7f9de85793ad732d1e33e124f Author: zhaoxingyu1 <[email protected]> AuthorDate: Tue Jul 15 20:47:25 2025 +0800 mtdconfig/nvs: use a fixed size buffer instead of vla use a fixed size buffer on stack instead of vla, When it needs to pass misra-c check Signed-off-by: zhaoxingyu1 <[email protected]> --- drivers/mtd/Kconfig | 13 +++++-- drivers/mtd/mtd_config_nvs.c | 80 ++++++++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 6c0a9066118..b661bc44212 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -212,9 +212,16 @@ config MTD_CONFIG_CACHE_SIZE int "Non-volatile Storage lookup cache size" default 0 depends on MTD_CONFIG_NVS - help - Number of entries in Non-volatile Storage lookup cache. - It is recommended that it be a power of 2. + ---help--- + Number of entries in Non-volatile Storage lookup cache. + It is recommended that it be a power of 2. + +config MTD_CONFIG_BUFFER_SIZE + int "Buffer size on the stack" + default 0 + ---help--- + Define a fixed size buffer on the stack instead of using a + variable length array. endif diff --git a/drivers/mtd/mtd_config_nvs.c b/drivers/mtd/mtd_config_nvs.c index fe4d4a8a1da..f09997950db 100644 --- a/drivers/mtd/mtd_config_nvs.c +++ b/drivers/mtd/mtd_config_nvs.c @@ -57,9 +57,17 @@ #define NVS_CACHE_NO_ADDR 0xffffffff -#define NVS_ATE(name, size) \ - char name##_buf[size]; \ - FAR struct nvs_ate *name = (FAR struct nvs_ate *)name##_buf +#if CONFIG_MTD_CONFIG_BUFFER_SIZE > 0 +# define NVS_BUFFER_SIZE(fs) CONFIG_MTD_CONFIG_BUFFER_SIZE +# define NVS_ATE(name, size) \ + char name##_buf[CONFIG_MTD_CONFIG_BUFFER_SIZE]; \ + FAR struct nvs_ate *name = (FAR struct nvs_ate *)name##_buf +#else +# define NVS_BUFFER_SIZE(fs) nvs_align_up(fs, 32) +# define NVS_ATE(name, size) \ + char name##_buf[size]; \ + FAR struct nvs_ate *name = (FAR struct nvs_ate *)name##_buf +#endif /**************************************************************************** * Private Types @@ -204,6 +212,15 @@ static inline size_t nvs_align_up(FAR struct nvs_fs *fs, size_t len) return (len + (fs->progsize - 1)) & ~(fs->progsize - 1); } +/**************************************************************************** + * Name: nvs_align_down + ****************************************************************************/ + +static inline size_t nvs_align_down(FAR struct nvs_fs *fs, size_t len) +{ + return len & ~(fs->progsize - 1); +} + /**************************************************************************** * Name: nvs_ate_size ****************************************************************************/ @@ -220,15 +237,6 @@ static inline size_t nvs_ate_size(FAR struct nvs_fs *fs) return nvs_align_up(fs, sizeof(struct nvs_ate)) + fs->progsize; } -/**************************************************************************** - * Name: nvs_buffer_size - ****************************************************************************/ - -static inline size_t nvs_buffer_size(FAR struct nvs_fs *fs) -{ - return nvs_align_up(fs, 32); -} - /**************************************************************************** * Name: nvs_ate_expired ****************************************************************************/ @@ -340,7 +348,7 @@ static int nvs_flash_rd(FAR struct nvs_fs *fs, uint32_t addr, return nvs_flash_brd(fs, offset, data, len); #else - uint8_t buf[fs->progsize]; + uint8_t buf[NVS_BUFFER_SIZE(fs)]; size_t bytes_to_rd; off_t begin_padding; off_t offset; @@ -466,13 +474,14 @@ static int nvs_flash_block_cmp(FAR struct nvs_fs *fs, uint32_t addr, FAR const void *data, size_t len) { FAR const uint8_t *data8 = (FAR const uint8_t *)data; - uint8_t buf[nvs_buffer_size(fs)]; + uint8_t buf[NVS_BUFFER_SIZE(fs)]; + size_t buf_size = nvs_align_down(fs, sizeof(buf)); size_t bytes_to_cmp; int rc; while (len > 0) { - bytes_to_cmp = MIN(sizeof(buf), len); + bytes_to_cmp = MIN(buf_size, len); rc = nvs_flash_rd(fs, addr, buf, bytes_to_cmp); if (rc) { @@ -506,14 +515,15 @@ static int nvs_flash_block_cmp(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_direct_cmp(FAR struct nvs_fs *fs, uint32_t addr1, uint32_t addr2, size_t len) { - uint8_t buf1[nvs_buffer_size(fs)]; - uint8_t buf2[nvs_buffer_size(fs)]; + uint8_t buf1[NVS_BUFFER_SIZE(fs)]; + uint8_t buf2[NVS_BUFFER_SIZE(fs)]; + size_t buf_size = nvs_align_down(fs, sizeof(buf1)); size_t bytes_to_cmp; int rc; while (len > 0) { - bytes_to_cmp = MIN(sizeof(buf1), len); + bytes_to_cmp = MIN(buf_size, len); rc = nvs_flash_rd(fs, addr1, buf1, bytes_to_cmp); if (rc) { @@ -553,14 +563,15 @@ static int nvs_flash_direct_cmp(FAR struct nvs_fs *fs, uint32_t addr1, static int nvs_flash_cmp_const(FAR struct nvs_fs *fs, uint32_t addr, uint8_t value, size_t len) { - uint8_t cmp[nvs_buffer_size(fs)]; + uint8_t cmp[NVS_BUFFER_SIZE(fs)]; + size_t buf_size = nvs_align_down(fs, sizeof(cmp)); size_t bytes_to_cmp; int rc; memset(cmp, value, sizeof(cmp)); while (len > 0) { - bytes_to_cmp = MIN(sizeof(cmp), len); + bytes_to_cmp = MIN(buf_size, len); rc = nvs_flash_block_cmp(fs, addr, cmp, bytes_to_cmp); if (rc) { @@ -586,13 +597,14 @@ static int nvs_flash_cmp_const(FAR struct nvs_fs *fs, uint32_t addr, static int nvs_flash_block_move(FAR struct nvs_fs *fs, uint32_t addr, size_t len) { - uint8_t buf[nvs_buffer_size(fs)]; + uint8_t buf[NVS_BUFFER_SIZE(fs)]; + size_t buf_size = nvs_align_down(fs, sizeof(buf)); size_t bytes_to_copy; int rc; while (len) { - bytes_to_copy = MIN(sizeof(buf), len); + bytes_to_copy = MIN(buf_size, len); rc = nvs_flash_rd(fs, addr, buf, bytes_to_copy); if (rc) { @@ -799,7 +811,7 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, { size_t ate_size = nvs_ate_size(fs); NVS_ATE(entry, ate_size); - uint8_t buf[fs->progsize]; + uint8_t buf[NVS_BUFFER_SIZE(fs)]; uint16_t copy_len = 0; uint16_t left; int rc; @@ -826,14 +838,14 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Write align block which include part key + part data */ left = rc; - memset(buf, fs->erasestate, sizeof(buf)); + memset(buf, fs->erasestate, fs->progsize); - copy_len = (left + len) <= sizeof(buf) ? - len : (sizeof(buf) - left); + copy_len = (left + len) <= fs->progsize ? + len : (fs->progsize - left); memcpy(buf, key + key_size - left, left); memcpy(buf + left, data, copy_len); - rc = nvs_flash_data_wrt(fs, buf, sizeof(buf)); + rc = nvs_flash_data_wrt(fs, buf, fs->progsize); if (rc) { ferr("Write value failed, rc=%d\n", rc); @@ -852,10 +864,10 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, /* Add padding at the end of data */ left = rc; - memset(buf, fs->erasestate, sizeof(buf)); + memset(buf, fs->erasestate, fs->progsize); memcpy(buf, data + len - left, left); - rc = nvs_flash_data_wrt(fs, buf, sizeof(buf)); + rc = nvs_flash_data_wrt(fs, buf, fs->progsize); if (rc) { ferr("Write value failed, rc=%d\n", rc); @@ -1088,11 +1100,11 @@ static int nvs_add_gc_done_ate(FAR struct nvs_fs *fs) static int nvs_expire_ate(FAR struct nvs_fs *fs, uint32_t addr) { - uint8_t expired[fs->progsize]; - memset(expired, ~fs->erasestate, sizeof(expired)); + uint8_t expired[NVS_BUFFER_SIZE(fs)]; + memset(expired, ~fs->erasestate, fs->progsize); return nvs_flash_wrt(fs, addr + nvs_align_up(fs, sizeof(struct nvs_ate)), - expired, sizeof(expired)); + expired, fs->progsize); } /**************************************************************************** @@ -1274,6 +1286,10 @@ static int nvs_startup(FAR struct nvs_fs *fs) NVS_ATE(second_ate, ate_size); NVS_ATE(last_ate, ate_size); +#if CONFIG_MTD_CONFIG_BUFFER_SIZE > 0 + DEBUGASSERT(ate_size <= CONFIG_MTD_CONFIG_BUFFER_SIZE); +#endif + rc = MTD_IOCTL(fs->mtd, MTDIOC_ERASESTATE, (unsigned long)((uintptr_t)&fs->erasestate)); if (rc < 0)
