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 2e4ce227744980f98b542574a74d69d174f82c2f Author: zhaoxingyu1 <[email protected]> AuthorDate: Sun Jul 13 17:44:14 2025 +0800 mtd_config/nvs: add data crc8 The purpose is to reduce the conflict rate of ate CRC and verify the data Signed-off-by: zhaoxingyu1 <[email protected]> --- drivers/mtd/mtd_config_nvs.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/mtd/mtd_config_nvs.c b/drivers/mtd/mtd_config_nvs.c index 5baa87ce858..fe4d4a8a1da 100644 --- a/drivers/mtd/mtd_config_nvs.c +++ b/drivers/mtd/mtd_config_nvs.c @@ -95,7 +95,7 @@ begin_packed_struct struct nvs_ate uint16_t offset; /* Data offset within block */ uint16_t len; /* Data len within block */ uint16_t key_len; /* Key string len */ - uint8_t part; /* Part of a multipart data - future extension */ + uint8_t data_crc8; /* Crc8 check of the data */ uint8_t crc8; /* Crc8 check of the ate entry */ uint8_t expired[0]; } end_packed_struct; @@ -670,13 +670,15 @@ static void nvs_ate_crc8_update(FAR struct nvs_ate *entry) * ****************************************************************************/ -static bool nvs_ate_crc8_check(FAR const struct nvs_ate *entry) +static bool nvs_ate_crc8_check(FAR struct nvs_fs *fs, + FAR const struct nvs_ate *entry) { uint8_t ate_crc; ate_crc = crc8part((FAR const uint8_t *)entry, offsetof(struct nvs_ate, crc8), 0xff); - return ate_crc == entry->crc8; + return ate_crc == entry->crc8 && (entry->len > 0 || + entry->data_crc8 == 0 || entry->data_crc8 == fs->erasestate); } /**************************************************************************** @@ -716,7 +718,7 @@ static int nvs_ate_cmp_const(FAR const struct nvs_ate *entry, static bool nvs_ate_valid(FAR struct nvs_fs *fs, FAR const struct nvs_ate *entry) { - return nvs_ate_crc8_check(entry) && + return nvs_ate_crc8_check(fs, entry) && entry->offset < (fs->blocksize - nvs_ate_size(fs)) && (entry->key_len > 0 || entry->id == nvs_special_ate_id(fs)); } @@ -807,6 +809,7 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id, entry->offset = fs->data_wra & NVS_ADDR_OFFS_MASK; entry->len = len; entry->key_len = key_size; + entry->data_crc8 = crc8(data, len); nvs_ate_crc8_update(entry); @@ -1654,6 +1657,7 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, uint32_t rd_addr; uint32_t hist_addr; uint32_t hash_id; + uint8_t data_crc8; bool hit = true; int rc; @@ -1732,6 +1736,19 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key, ferr("Data read failed, rc=%d\n", rc); return rc; } + + if (len >= wlk_ate->len && wlk_ate->data_crc8 != fs->erasestate) + { + /* Do not compute CRC for partial reads as CRC won't match */ + + data_crc8 = crc8(data, wlk_ate->len); + if (wlk_ate->data_crc8 != data_crc8) + { + ferr("Invalid data crc: %" PRIx8 ", wlk_ate->data_crc8: " + "%" PRIx8 "\n", data_crc8, wlk_ate->data_crc8); + return -EIO; + } + } } if (ate_addr)
