From 274964999f31c7cb61aee1141bfccb044ef39368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Kr=C3=B3lik?= <66667989+Damian-Nordic@users.noreply.github.com> Date: Fri, 4 Nov 2022 08:42:18 +0100 Subject: [PATCH] [Zephyr] Allow to erase entire NVS on factory reset (#23434) * [Zephyr] Allow to erase entire NVS on factory reset Currently, the default factory reset implementation simply removes Matter (and OpenThread) settings instead of formatting the non-volatile storage partition. The latter approach may be advisable in the cases where no settings need to survive a factory reset, as it is expected to work properly regardless of the state of the storage partition. Additionally, it will regain the original storage performance if it has been loaded with a lot of stale data. Signed-off-by: Damian Krolik * Update doc Signed-off-by: Damian Krolik --- config/nrfconnect/chip-module/Kconfig | 4 +++ config/zephyr/Kconfig | 11 ++++++++ .../nrfconnect_examples_configuration.md | 9 +++++++ .../Zephyr/ConfigurationManagerImpl.cpp | 27 ++++++++++++++++--- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig index b377c65c2e222f..e4a0a9f3a1abab 100644 --- a/config/nrfconnect/chip-module/Kconfig +++ b/config/nrfconnect/chip-module/Kconfig @@ -284,5 +284,9 @@ config CHIP_CERTIFiCATION_DECLARATION_OTA_IMAGE_ID endif +# See config/zephyr/Kconfig for full definition +config CHIP_FACTORY_RESET_ERASE_NVS + bool + default y if CHIP_FACTORY_DATA || CHIP_FACTORY_DATA_CUSTOM_BACKEND endif diff --git a/config/zephyr/Kconfig b/config/zephyr/Kconfig index efa0f7abc2c476..9928bb35b49258 100644 --- a/config/zephyr/Kconfig +++ b/config/zephyr/Kconfig @@ -202,6 +202,17 @@ config CHIP_CRYPTO_PSA Use the backend for the Matter crypto layer that is based on PSA crypto API instead of the default, based on legacy mbedTLS APIs. +config CHIP_FACTORY_RESET_ERASE_NVS + bool "Erase NVS flash pages on factory reset" + depends on SETTINGS_NVS + help + When factory reset is requested, erase flash pages occupied by non-volatile storage + instead of removing Matter-related settings only. This provides a more robust + factory reset mechanism and allows to regain the original storage performance if any + firmware issue has brought it to an unexpected state. For this reason, it is + advisable to set this option if all configuration, including device-specific + entries, is supposed to be cleared on a factory reset. + config CHIP_MALLOC_SYS_HEAP bool "Memory allocator based on Zephyr sys_heap" imply SYS_HEAP_RUNTIME_STATS diff --git a/docs/guides/nrfconnect_examples_configuration.md b/docs/guides/nrfconnect_examples_configuration.md index 119852b3929a89..0254d8bb390644 100644 --- a/docs/guides/nrfconnect_examples_configuration.md +++ b/docs/guides/nrfconnect_examples_configuration.md @@ -193,6 +193,15 @@ instead of using a QR code, which is the default configuration. To enable NFC for commissioning and share the onboarding payload in an NFC tag, set the `CONFIG_CHIP_NFC_COMMISSIONING` option. +**Factory reset behavior** + +By default, the factory reset procedure implemented in the Matter stack removes +Matter-related settings only. If your application does not depend on any +device-lifelong data stored in the non-volatile storage, set the +`CONFIG_CHIP_FACTORY_RESET_ERASE_NVS` option to fully erase the NVS partition at +the factory reset. This approach is more robust and regains the original NVS +performance in case it has been polluted with unwanted entries. + **Logging** You can enable logging for both the stack and Zephyr’s diff --git a/src/platform/Zephyr/ConfigurationManagerImpl.cpp b/src/platform/Zephyr/ConfigurationManagerImpl.cpp index bd19057e65d3bf..107579afbfbb03 100644 --- a/src/platform/Zephyr/ConfigurationManagerImpl.cpp +++ b/src/platform/Zephyr/ConfigurationManagerImpl.cpp @@ -32,6 +32,11 @@ #include #include +#ifdef CONFIG_CHIP_FACTORY_RESET_ERASE_NVS +#include +#include +#endif + namespace chip { namespace DeviceLayer { @@ -168,14 +173,30 @@ void ConfigurationManagerImpl::RunConfigUnitTest(void) void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) { ChipLogProgress(DeviceLayer, "Performing factory reset"); + +#ifdef CONFIG_CHIP_FACTORY_RESET_ERASE_NVS + void * storage = nullptr; + int status = settings_storage_get(&storage); + + if (status == 0) + { + status = nvs_clear(static_cast(storage)); + } + + if (status) + { + ChipLogError(DeviceLayer, "Factory reset failed: %d", status); + } +#else const CHIP_ERROR err = PersistedStorage::KeyValueStoreMgrImpl().DoFactoryReset(); if (err != CHIP_NO_ERROR) + { ChipLogError(DeviceLayer, "Factory reset failed: %" CHIP_ERROR_FORMAT, err.Format()); + } -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD - ThreadStackMgr().ErasePersistentInfo(); -#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + ConnectivityMgr().ErasePersistentInfo(); +#endif PlatformMgr().Shutdown(); }