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)

Reply via email to