You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/03/13 16:11:46 UTC
(nuttx) branch master updated (ea7dbdc8ac -> 3b79363041)
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
from ea7dbdc8ac risc-v/k230: fix k230_hart_is_big issue
new cd80900646 mtd_config_fs : support algin size
new 3b79363041 mtd_config_fs : optimize nvs
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
drivers/mtd/Kconfig | 7 +++
drivers/mtd/mtd_config_fs.c | 139 ++++++++++++++++++++++++++++++++++++--------
2 files changed, 122 insertions(+), 24 deletions(-)
(nuttx) 02/02: mtd_config_fs : optimize nvs
Posted by xi...@apache.org.
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 3b7936304183d505f15a3a270fc39277f9da8e60
Author: xucheng5 <xu...@xiaomi.com>
AuthorDate: Wed Dec 20 11:45:27 2023 +0800
mtd_config_fs : optimize nvs
Signed-off-by: xucheng5 <xu...@xiaomi.com>
---
drivers/mtd/mtd_config_fs.c | 156 +++++++++++++++++++++++++++++---------------
1 file changed, 104 insertions(+), 52 deletions(-)
diff --git a/drivers/mtd/mtd_config_fs.c b/drivers/mtd/mtd_config_fs.c
index ad2d3ca2b0..f1f8079f5f 100644
--- a/drivers/mtd/mtd_config_fs.c
+++ b/drivers/mtd/mtd_config_fs.c
@@ -81,11 +81,8 @@
#define NVS_SPECIAL_ATE_ID 0xffffffff
-#ifdef CONFIG_MTD_WRITE_ALIGN_SIZE
#define NVS_ALIGN_SIZE CONFIG_MTD_WRITE_ALIGN_SIZE
-#else
-#define NVS_ALIGN_SIZE 4
-#endif
+#define NVS_ALIGN_UP(x) (((x) + NVS_ALIGN_SIZE - 1) & ~(NVS_ALIGN_SIZE - 1))
/****************************************************************************
* Private Types
@@ -116,11 +113,15 @@ begin_packed_struct struct nvs_ate
uint16_t key_len; /* Key string len */
uint8_t part; /* Part of a multipart data - future extension */
uint8_t crc8; /* Crc8 check of the ate entry */
-#if CONFIG_MTD_WRITE_ALIGN_SIZE > 4
- uint8_t padding[NVS_ALIGN_SIZE - 4]; /* padding for align */
+#if CONFIG_MTD_WRITE_ALIGN_SIZE <= 4
+ /* stay compatible with situation which align byte be 1 */
+
+ uint8_t expired[NVS_ALIGN_SIZE];
+ uint8_t reserved[4 - NVS_ALIGN_SIZE];
+#else
+ uint8_t padding[NVS_ALIGN_UP(12) - 12];
+ uint8_t expired[NVS_ALIGN_SIZE];
#endif
- uint8_t expired; /* 0xFF-newest entry, others-old entry */
- uint8_t reserved[NVS_ALIGN_SIZE - 1];
} end_packed_struct;
/****************************************************************************
@@ -163,19 +164,6 @@ static const struct file_operations g_mtdnvs_fops =
* Private Functions
****************************************************************************/
-/****************************************************************************
- * Name: nvs_al_size
- ****************************************************************************/
-
-static inline size_t nvs_al_size(size_t len)
-{
-#ifdef CONFIG_MTD_WRITE_ALIGN_SIZE
- return (len + (NVS_ALIGN_SIZE - 1U)) & ~(NVS_ALIGN_SIZE - 1U);
-#else
- return len;
-#endif
-}
-
/****************************************************************************
* Name: nvs_fnv_hash
****************************************************************************/
@@ -599,6 +587,40 @@ static int nvs_close_ate_valid(FAR struct nvs_fs *fs,
return 1;
}
+/****************************************************************************
+ * Name: nvs_flash_write_multi_blk
+ *
+ * Description:
+ * Store multi align block in flash
+ *
+ * Returned Value:
+ * number of bytes at the end of addr which is left to write next time.
+ * zero indicates all bytes were written . On error returns -ERRNO code.
+ ****************************************************************************/
+
+int nvs_flash_write_multi_blk(FAR struct nvs_fs *fs, const uint8_t *addr,
+ size_t size)
+{
+ size_t blk_cnt;
+ int left;
+ int rc;
+
+ blk_cnt = size / NVS_ALIGN_SIZE;
+ left = size % NVS_ALIGN_SIZE;
+
+ if (blk_cnt)
+ {
+ rc = nvs_flash_data_wrt(fs, addr, size - left);
+ if (rc)
+ {
+ ferr("Write multi data value failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ return left;
+}
+
/****************************************************************************
* Name: nvs_flash_wrt_entry
*
@@ -613,8 +635,9 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id,
{
int rc;
struct nvs_ate entry;
- uint16_t total;
- uint8_t *tmp;
+ uint16_t left;
+ uint16_t copy_len = 0;
+ uint8_t buf[NVS_ALIGN_SIZE];
memset(&entry, fs->erasestate, sizeof(entry));
entry.id = id;
@@ -624,37 +647,65 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id,
nvs_ate_crc8_update(&entry);
- /* Let's sew key and data into one, key comes first, then data */
+ /* Let's save key and data into one, key comes first, then data */
- total = nvs_al_size(key_size + len);
- tmp = kmm_malloc(total);
- if (tmp == NULL)
+ rc = nvs_flash_write_multi_blk(fs, key, key_size);
+ if (rc < 0)
{
- ferr("malloc size %u failed\n", total);
- return -ENOMEM;
+ return rc;
}
- memcpy(tmp, key, key_size);
- memcpy(tmp + key_size, data, len);
- memset(tmp + key_size + len, fs->erasestate, total - key_size - len);
-
- rc = nvs_flash_data_wrt(fs, tmp, total);
if (rc)
{
- ferr("Write value failed, rc=%d\n", rc);
- kmm_free(tmp);
+ /* Write align block which inlcude part key + part data */
+
+ left = rc;
+ memset(buf, fs->erasestate, NVS_ALIGN_SIZE);
+
+ copy_len = (left + len) <= NVS_ALIGN_SIZE ?
+ len : (NVS_ALIGN_SIZE - left);
+
+ memcpy(buf, key + key_size - left, left);
+ memcpy(buf + left, data, copy_len);
+ rc = nvs_flash_data_wrt(fs, buf, NVS_ALIGN_SIZE);
+ if (rc)
+ {
+ ferr("Write value failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ rc = nvs_flash_write_multi_blk(fs, data + copy_len, len - copy_len);
+ if (rc < 0)
+ {
return rc;
}
+ if (rc)
+ {
+ /* Add padding at the end of data */
+
+ left = rc;
+ memset(buf, fs->erasestate, NVS_ALIGN_SIZE);
+ memcpy(buf, data + len - left, left);
+
+ rc = nvs_flash_data_wrt(fs, buf, NVS_ALIGN_SIZE);
+ if (rc)
+ {
+ ferr("Write value failed, rc=%d\n", rc);
+ return rc;
+ }
+ }
+
+ /* Last, let's save entry to flash */
+
rc = nvs_flash_ate_wrt(fs, &entry);
if (rc)
{
ferr("Write ate failed, rc=%d\n", rc);
- kmm_free(tmp);
return rc;
}
- kmm_free(tmp);
return 0;
}
@@ -699,7 +750,7 @@ static int nvs_recover_last_ate(FAR struct nvs_fs *fs,
data_end_addr &= ADDR_BLOCK_MASK;
data_end_addr += end_ate.offset +
- nvs_al_size(end_ate.key_len + end_ate.len);
+ NVS_ALIGN_UP(end_ate.key_len + end_ate.len);
*addr = ate_end_addr;
}
@@ -945,7 +996,7 @@ static int nvs_gc(FAR struct nvs_fs *fs)
return rc;
}
- if (gc_ate.expired != fs->erasestate)
+ if (gc_ate.expired[0] != fs->erasestate)
{
/* Deleted or old ate, ignore it */
@@ -971,7 +1022,7 @@ static int nvs_gc(FAR struct nvs_fs *fs)
nvs_ate_crc8_update(&gc_ate);
rc = nvs_flash_block_move(fs, data_addr,
- nvs_al_size(gc_ate.key_len + gc_ate.len));
+ NVS_ALIGN_UP(gc_ate.key_len + gc_ate.len));
if (rc)
{
return rc;
@@ -1156,8 +1207,8 @@ static int nvs_startup(FAR struct nvs_fs *fs)
/* Complete write of ate was performed */
fs->data_wra = addr & ADDR_BLOCK_MASK;
- fs->data_wra += last_ate.offset + nvs_al_size(last_ate.key_len +
- last_ate.len);
+ fs->data_wra += last_ate.offset +
+ NVS_ALIGN_UP(last_ate.key_len + last_ate.len);
finfo("recovered data_wra=0x%" PRIx32 "\n", fs->data_wra);
}
@@ -1316,7 +1367,7 @@ static int nvs_startup(FAR struct nvs_fs *fs)
if (nvs_ate_valid(fs, &second_ate)
&& second_ate.id == last_ate.id
- && second_ate.expired == fs->erasestate)
+ && second_ate.expired[0] == fs->erasestate)
{
finfo("same id at 0x%" PRIx32 ", key_len %" PRIu16 ", "
"offset %" PRIu16 "\n",
@@ -1432,7 +1483,7 @@ static ssize_t nvs_read_entry(FAR struct nvs_fs *fs, FAR const uint8_t *key,
{
/* It is old or deleted, return -ENOENT */
- if (wlk_ate.expired != fs->erasestate)
+ if (wlk_ate.expired[0] != fs->erasestate)
{
return -ENOENT;
}
@@ -1521,13 +1572,14 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs,
/* Data now contains input data and input key, input key first. */
- data_size = nvs_al_size(key_size + pdata->len);
+ data_size = NVS_ALIGN_UP(key_size + pdata->len);
/* The maximum data size is block size - 3 ate
* where: 1 ate for data, 1 ate for block close, 1 ate for gc done.
*/
- finfo("key_size=%zu, len=%zu\n", key_size, pdata->len);
+ finfo("key_size=%zu, len=%zu, data_size = %zu\n", key_size,
+ pdata->len, data_size);
if ((data_size > (fs->geo.erasesize - 3 * sizeof(struct nvs_ate))) ||
((pdata->len > 0) && (pdata->configdata == NULL)))
@@ -1587,7 +1639,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs,
{
/* If prev ate is expired, it is deleted. */
- if (wlk_ate.expired != fs->erasestate)
+ if (wlk_ate.expired[0] != fs->erasestate)
{
/* Skip delete entry as it is already the
* last one.
@@ -1611,7 +1663,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs,
}
}
else if (pdata->len == wlk_ate.len &&
- wlk_ate.expired == fs->erasestate)
+ wlk_ate.expired[0] == fs->erasestate)
{
/* Do not try to compare if lengths are not equal
* or prev one is deleted.
@@ -1658,7 +1710,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs,
/* Nvs is changed after gc, we will look for the old ate.
*/
- if (prev_found && wlk_ate.expired == fs->erasestate)
+ if (prev_found && wlk_ate.expired[0] == fs->erasestate)
{
finfo("prev entry exists, search for it\n");
@@ -1701,7 +1753,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs,
* already expired)
*/
- if (prev_found && wlk_ate.expired == fs->erasestate)
+ if (prev_found && wlk_ate.expired[0] == fs->erasestate)
{
rc = nvs_expire_ate(fs, hist_addr);
finfo("expir prev entry, %" PRIx32 ", rc %d\n",
@@ -1871,7 +1923,7 @@ static int nvs_next(FAR struct nvs_fs *fs,
if (nvs_ate_valid(fs, &step_ate)
&& step_ate.id != NVS_SPECIAL_ATE_ID
- && step_ate.expired == fs->erasestate)
+ && step_ate.expired[0] == fs->erasestate)
{
break;
}
(nuttx) 01/02: mtd_config_fs : support algin size
Posted by xi...@apache.org.
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 cd80900646dbade1874973e757618d0ea07ca94b
Author: xucheng5 <xu...@xiaomi.com>
AuthorDate: Fri Dec 15 17:59:39 2023 +0800
mtd_config_fs : support algin size
Signed-off-by: xucheng5 <xu...@xiaomi.com>
---
drivers/mtd/Kconfig | 7 +++++
drivers/mtd/mtd_config_fs.c | 65 ++++++++++++++++++++++++++++++++++++---------
2 files changed, 59 insertions(+), 13 deletions(-)
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 5d75e84972..5b16be665a 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -195,6 +195,13 @@ config MTD_CONFIG_FAIL_SAFE
This replaces the drivers/mtd/mtd_config, which
is resilient to power loss.
+config MTD_WRITE_ALIGN_SIZE
+ int "align size [1,2,4,8,16] for per write operation"
+ default 1
+ depends on MTD_CONFIG_FAIL_SAFE
+ ---help---
+ align size will be one of 1,2,4,8,16
+
endif # MTD_CONFIG
comment "MTD Device Drivers"
diff --git a/drivers/mtd/mtd_config_fs.c b/drivers/mtd/mtd_config_fs.c
index aac530ae15..ad2d3ca2b0 100644
--- a/drivers/mtd/mtd_config_fs.c
+++ b/drivers/mtd/mtd_config_fs.c
@@ -81,6 +81,12 @@
#define NVS_SPECIAL_ATE_ID 0xffffffff
+#ifdef CONFIG_MTD_WRITE_ALIGN_SIZE
+#define NVS_ALIGN_SIZE CONFIG_MTD_WRITE_ALIGN_SIZE
+#else
+#define NVS_ALIGN_SIZE 4
+#endif
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -110,8 +116,11 @@ begin_packed_struct struct nvs_ate
uint16_t key_len; /* Key string len */
uint8_t part; /* Part of a multipart data - future extension */
uint8_t crc8; /* Crc8 check of the ate entry */
+#if CONFIG_MTD_WRITE_ALIGN_SIZE > 4
+ uint8_t padding[NVS_ALIGN_SIZE - 4]; /* padding for align */
+#endif
uint8_t expired; /* 0xFF-newest entry, others-old entry */
- uint8_t reserved[3]; /* For future extension */
+ uint8_t reserved[NVS_ALIGN_SIZE - 1];
} end_packed_struct;
/****************************************************************************
@@ -154,6 +163,19 @@ static const struct file_operations g_mtdnvs_fops =
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: nvs_al_size
+ ****************************************************************************/
+
+static inline size_t nvs_al_size(size_t len)
+{
+#ifdef CONFIG_MTD_WRITE_ALIGN_SIZE
+ return (len + (NVS_ALIGN_SIZE - 1U)) & ~(NVS_ALIGN_SIZE - 1U);
+#else
+ return len;
+#endif
+}
+
/****************************************************************************
* Name: nvs_fnv_hash
****************************************************************************/
@@ -591,6 +613,8 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id,
{
int rc;
struct nvs_ate entry;
+ uint16_t total;
+ uint8_t *tmp;
memset(&entry, fs->erasestate, sizeof(entry));
entry.id = id;
@@ -602,17 +626,23 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id,
/* Let's sew key and data into one, key comes first, then data */
- rc = nvs_flash_data_wrt(fs, key, key_size);
- if (rc)
+ total = nvs_al_size(key_size + len);
+ tmp = kmm_malloc(total);
+ if (tmp == NULL)
{
- ferr("Write key failed, rc=%d\n", rc);
- return rc;
+ ferr("malloc size %u failed\n", total);
+ return -ENOMEM;
}
- rc = nvs_flash_data_wrt(fs, data, len);
+ memcpy(tmp, key, key_size);
+ memcpy(tmp + key_size, data, len);
+ memset(tmp + key_size + len, fs->erasestate, total - key_size - len);
+
+ rc = nvs_flash_data_wrt(fs, tmp, total);
if (rc)
{
ferr("Write value failed, rc=%d\n", rc);
+ kmm_free(tmp);
return rc;
}
@@ -620,9 +650,11 @@ static int nvs_flash_wrt_entry(FAR struct nvs_fs *fs, uint32_t id,
if (rc)
{
ferr("Write ate failed, rc=%d\n", rc);
+ kmm_free(tmp);
return rc;
}
+ kmm_free(tmp);
return 0;
}
@@ -666,10 +698,16 @@ static int nvs_recover_last_ate(FAR struct nvs_fs *fs,
/* Found a valid ate, update data_end_addr and *addr */
data_end_addr &= ADDR_BLOCK_MASK;
- data_end_addr += end_ate.offset + end_ate.key_len + end_ate.len;
+ data_end_addr += end_ate.offset +
+ nvs_al_size(end_ate.key_len + end_ate.len);
*addr = ate_end_addr;
}
+ if (ate_end_addr < sizeof(struct nvs_ate))
+ {
+ break;
+ }
+
ate_end_addr -= sizeof(struct nvs_ate);
}
@@ -829,10 +867,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 = 0;
+ uint8_t expired[NVS_ALIGN_SIZE];
+ memset(expired, ~fs->erasestate, sizeof(expired));
return nvs_flash_wrt(fs, addr + offsetof(struct nvs_ate, expired),
- &expired, sizeof(expired));
+ expired, sizeof(expired));
}
/****************************************************************************
@@ -932,7 +971,7 @@ static int nvs_gc(FAR struct nvs_fs *fs)
nvs_ate_crc8_update(&gc_ate);
rc = nvs_flash_block_move(fs, data_addr,
- gc_ate.key_len + gc_ate.len);
+ nvs_al_size(gc_ate.key_len + gc_ate.len));
if (rc)
{
return rc;
@@ -1117,8 +1156,8 @@ static int nvs_startup(FAR struct nvs_fs *fs)
/* Complete write of ate was performed */
fs->data_wra = addr & ADDR_BLOCK_MASK;
- fs->data_wra += last_ate.offset + last_ate.key_len +
- last_ate.len;
+ fs->data_wra += last_ate.offset + nvs_al_size(last_ate.key_len +
+ last_ate.len);
finfo("recovered data_wra=0x%" PRIx32 "\n", fs->data_wra);
}
@@ -1482,7 +1521,7 @@ static ssize_t nvs_write(FAR struct nvs_fs *fs,
/* Data now contains input data and input key, input key first. */
- data_size = key_size + pdata->len;
+ data_size = nvs_al_size(key_size + pdata->len);
/* The maximum data size is block size - 3 ate
* where: 1 ate for data, 1 ate for block close, 1 ate for gc done.