[NXP] Fix key storage issues and add NVS wear stats support (#35511)
* [nxp][platform][common] Simplify factory reset procedure when KeyStorage is used
Instead of resetting the KetStorage which, in turn, removes the key files
one by one, just shut it down to trigger a FileCache flush and then simply
format the file system partition.
Signed-off-by: Marian Chereji <marian.chereji@nxp.com>
(cherry picked from commit 9a2624656feff58849d89272e73559da19078849)
* [nxp][platform][common] Update "NXPConfig.h" to allow building multiple key storage solutions
The "NXPConfig.h" header was developed to support 2 key storage
solutions so far, which were mostly selected using the
CHIP_PLAT_NVM_SUPPORT build symbol. In order to be able to support
additional key storage solutions (such as Zephyr NVS), which are no
longer selected via the above mentioned build symbol, the header
Signed-off-by: Marian Chereji <marian.chereji@nxp.com>
(cherry picked from commit 7bace6914508ac98124836a1be3973818993dd58)
* [nxp][common] Fix KeyStorage use of illegal buffer size when checking the existence of a key
The "NXPConfig::ConfigValueExists" member function is using a
non-zero buffer capacity combined with a NULL buffer pointer when
calling the KeyStorage KS_GetKeyInt() function. This combination is
illegal. When using a NULL buffer pointer, a capacity of zero is
required to be provided.
Signed-off-by: Marian Chereji <marian.chereji@nxp.com>
(cherry picked from commit f8f03ef0041bc8b7729fe7959cf2244b6d65133e)
* [nxp][platform][common] Add check for read_bytes_size
read_bytes_size can be nullptr according to the KVS API.
Add a nullptr check to account for use cases where the
parameter is not used (implicitly set to nullptr).
Signed-off-by: marius-alex-tache <marius.tache@nxp.com>
* [nxp][platform][common] Add support for NVS key storage wear statistics
Added the support to initialize and update key storage wear
statistics.
Signed-off-by: Marian Chereji <marian.chereji@nxp.com>
Reviewed-by: Doru-Cristian Gucea <doru-cristian.gucea@nxp.com>
Reviewed-by: Martin Girardot <martin.girardot@nxp.com>
(cherry picked from commit d05884ddf8baac0da0a4d9d2a693280d2bdae86a)
* [nxp][platform][common] Update platform names for w0/w1
Signed-off-by: marius-alex-tache <marius.tache@nxp.com>
---------
Signed-off-by: marius-alex-tache <marius.tache@nxp.com>
Co-authored-by: Marian Chereji <marian.chereji@nxp.com>
diff --git a/src/platform/nxp/BUILD.gn b/src/platform/nxp/BUILD.gn
index 0865a1d..b2043ca 100644
--- a/src/platform/nxp/BUILD.gn
+++ b/src/platform/nxp/BUILD.gn
@@ -26,7 +26,7 @@
"${chip_root}/src/platform/logging:headers",
]
- if (nxp_platform == "k32w/k32w0" || nxp_platform == "k32w1") {
+ if (nxp_platform == "k32w0" || nxp_platform == "mcxw71_k32w1") {
sources = [ "${chip_root}/src/platform/nxp/${nxp_platform}/Logging.cpp" ]
} else {
sources = [ "${chip_root}/src/platform/nxp/common/Logging.cpp" ]
diff --git a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h
index ba2321c..e8d392f 100644
--- a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h
+++ b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h
@@ -102,6 +102,10 @@
#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 1
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
+#ifndef CHIP_DEVICE_CONFIG_KVS_WEAR_STATS_KEY
+#define CHIP_DEVICE_CONFIG_KVS_WEAR_STATS_KEY "nxp/diag/usr"
+#endif // CHIP_DEVICE_CONFIG_KVS_WEAR_STATS_KEY
+
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD && !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY 1
#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1
diff --git a/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp
index af2598c..737007a 100644
--- a/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp
+++ b/src/platform/nxp/common/KeyValueStoreManagerImpl.cpp
@@ -55,7 +55,10 @@
ChipLogError(DeviceLayer, "KVS, failed to read key!");
}
- *read_bytes_size = read_bytes;
+ if (read_bytes_size)
+ {
+ *read_bytes_size = read_bytes;
+ }
exit:
ConvertError(err);
diff --git a/src/platform/nxp/common/NXPConfig.h b/src/platform/nxp/common/NXPConfig.h
index 03d6174..7de3bea 100644
--- a/src/platform/nxp/common/NXPConfig.h
+++ b/src/platform/nxp/common/NXPConfig.h
@@ -40,14 +40,12 @@
#if (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_NVM_FWK)
#include "NVM_Interface.h"
+#include "ram_storage.h"
#elif (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_LITTLEFS)
#include "fwk_filesystem.h"
-#endif
-
-#if (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_KEY_STORAGE)
-#include "fwk_key_storage.h"
-#else
#include "ram_storage.h"
+#elif (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_KEY_STORAGE)
+#include "fwk_key_storage.h"
#endif
namespace chip {
@@ -188,11 +186,14 @@
private:
#if (CHIP_PLAT_NVM_SUPPORT == CHIP_PLAT_KEY_STORAGE)
static CHIP_ERROR MapKeyStorageStatus(ks_error_t ksStatus);
-#else
+#elif (CHIP_PLAT_NVM_SUPPORT != CHIP_PLAT_NO_NVM)
static CHIP_ERROR MapRamStorageStatus(rsError rsStatus);
#endif
static int SaveIntKeysToFS(void);
static int SaveStringKeysToFS(void);
+#if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS == 1)
+ static CHIP_ERROR InitStorageWearStats(void);
+#endif
};
} // namespace Internal
diff --git a/src/platform/nxp/common/NXPConfigKS.cpp b/src/platform/nxp/common/NXPConfigKS.cpp
index 1940a80..930f07f 100644
--- a/src/platform/nxp/common/NXPConfigKS.cpp
+++ b/src/platform/nxp/common/NXPConfigKS.cpp
@@ -31,6 +31,7 @@
#include <platform/internal/testing/ConfigUnitTest.h>
#include "fwk_file_cache.h"
+#include "fwk_fs_abstraction.h"
#include "fwk_key_storage.h"
#include "fwk_lfs_mflash.h"
@@ -419,26 +420,26 @@
found = false;
readValue_p = NULL;
outLen = 0;
- /* Max number of bytes read when getting a value */
- bufSize = 256;
+ bufSize = 0;
if (ValidConfigKey(key))
{
/* Get the first occurence */
status = KS_GetKeyInt(ks_handle_p, (int) key, (char *) NS_INT, readValue_p, bufSize, &outLen);
- found = (status == KS_ERROR_NONE && outLen != 0);
+ found = (status != KS_ERROR_KEY_NOT_FOUND);
}
return found;
}
CHIP_ERROR NXPConfig::FactoryResetConfig(void)
{
- /*for (Key key = kMinConfigKey_ChipConfig; key <= kMaxConfigKey_ChipConfig; key++)
- {
- ClearConfigValue(key);
- }*/
-
- KS_Reset(ks_handle_p);
+ /*
+ * When a factory reset is required, shut down the KeyStorage (which
+ * also flushes the FileCache) and then execute a simple format of the
+ * the file system partition.
+ */
+ KS_DeInit(ks_handle_p);
+ FSA_Format();
DBG_PRINTF("FactoryResetConfig done\r\n");
diff --git a/src/platform/nxp/common/NXPConfigNVS.cpp b/src/platform/nxp/common/NXPConfigNVS.cpp
index 34d98a3..4cd997b 100644
--- a/src/platform/nxp/common/NXPConfigNVS.cpp
+++ b/src/platform/nxp/common/NXPConfigNVS.cpp
@@ -20,10 +20,14 @@
#include <lib/core/CHIPEncoding.h>
#include <platform/CHIPDeviceError.h>
#include <platform/internal/testing/ConfigUnitTest.h>
+#include <platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h>
#include <settings.h>
/* Only for flash init, to be move to sdk framework */
#include "port/nvs_port.h"
+#if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS == 1)
+#include "fwk_nvs_stats.h"
+#endif /* CHIP_DEVICE_CONFIG_KVS_WEAR_STATS */
// These can be overridden by the application as needed.
#ifndef CHIP_DEVICE_INTEGER_SETTINGS_KEY
@@ -137,6 +141,17 @@
return 0;
}
+
+#if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS == 1)
+void OnFlashSectorWearCountUpdate(uint16_t sector_idx, const nvs_storage_wear_profile_t * flash_wear_profile)
+{
+ char keyUser[] = CHIP_DEVICE_CONFIG_KVS_WEAR_STATS_KEY;
+ const size_t flash_wear_profile_size = NVS_STORAGE_WEAR_PROFILE_SIZE(flash_wear_profile->sector_count);
+
+ /* Update the NVS stats key in storage */
+ NXPConfig::WriteConfigValueBin((const char *) keyUser, (uint8_t *) flash_wear_profile, flash_wear_profile_size);
+}
+#endif /* CHIP_DEVICE_CONFIG_KVS_WEAR_STATS */
} // namespace
CHIP_ERROR NXPConfig::Init()
@@ -151,9 +166,51 @@
ReturnErrorCodeIf(settings_subsys_init(), CHIP_ERROR_PERSISTED_STORAGE_FAILED);
+#if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS == 1)
+ ReturnErrorOnFailure(InitStorageWearStats());
+#endif /* CHIP_DEVICE_CONFIG_KVS_WEAR_STATS */
+
return CHIP_NO_ERROR;
}
+#if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS == 1)
+CHIP_ERROR NXPConfig::InitStorageWearStats(void)
+{
+ nvs_storage_wear_profile_t * flash_wear_profile = NULL;
+ const size_t flash_wear_profile_size = NVS_STORAGE_WEAR_PROFILE_SIZE((uint32_t) NV_STORAGE_MAX_SECTORS);
+ size_t size;
+ char keyUser[] = CHIP_DEVICE_CONFIG_KVS_WEAR_STATS_KEY;
+
+ /* Create an empty flash wear profile */
+ flash_wear_profile = (nvs_storage_wear_profile_t *) calloc(1, flash_wear_profile_size);
+ ReturnErrorCodeIf(flash_wear_profile == NULL, CHIP_ERROR_NO_MEMORY);
+
+ /* Try to read the flash wear profile from the User Support diagnostic log key */
+ CHIP_ERROR err = ReadConfigValueBin((const char *) keyUser, (uint8_t *) flash_wear_profile, flash_wear_profile_size, size);
+ if ((err != CHIP_NO_ERROR) || (size != flash_wear_profile_size) ||
+ (flash_wear_profile->sector_count != (uint32_t) NV_STORAGE_MAX_SECTORS))
+ {
+ /* Either the flash wear stats are not available in the persistent
+ * storage or the flash wear statistics that we have read are not
+ * compatible with the current persistent storage configuration. In
+ * this case - just reset and save the flash wear statistics. */
+ flash_wear_profile->sector_count = (uint32_t) NV_STORAGE_MAX_SECTORS;
+ memset(flash_wear_profile->erase_count, 0, (uint32_t) NV_STORAGE_MAX_SECTORS * sizeof(uint16_t));
+ WriteConfigValueBin((const char *) keyUser, (uint8_t *) flash_wear_profile, flash_wear_profile_size);
+ }
+ else
+ {
+ /* Load the flash wear profile into the NVS statistics */
+ nvs_stats_load_profile(flash_wear_profile);
+ }
+ free(flash_wear_profile);
+
+ nvs_stats_config_event_handler(OnFlashSectorWearCountUpdate);
+
+ return CHIP_NO_ERROR;
+}
+#endif /* CHIP_DEVICE_CONFIG_KVS_WEAR_STATS */
+
CHIP_ERROR NXPConfig::ReadConfigValue(Key key, bool & val)
{
ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.