From 3da3aa89d21bbe4d08e162ff7c6fc22c48d3cdbb Mon Sep 17 00:00:00 2001
From: jmartinez-silabs <67972863+jmartinez-silabs@users.noreply.github.com>
Date: Thu, 31 Mar 2022 23:54:17 -0400
Subject: [PATCH] [EFR32] Rework NVM3 instances and refactor our KVS
implementation to use nvm3 (#16877)
* Merge chip_nvm3 section into silabs default nvm3 section. Rework the efr32Config nvm3 driver, tweaks to linkerfile for the nvm3 section
* Refactore efr32 kvs implementation to use silabs nvm3 driver
* Fix some return codes for KVS
* Update ldscript for mg24. Add verifications in kvs implementation. Regroup nvm3 and kvs init. Set ble default connection params
* Delay keymap commit to nvm, Build argument for kvs entry count, Clean up
* Add build option in efr32_sdk.gni and detail in build script
* add info in read me
* Fix typo, add NVM to wordlist
* undo unwanted change to zap and pigweed submodule.
* remove mv command
---
.github/.wordlist.txt | 1 +
examples/light-switch-app/efr32/README.md | 9 +
examples/light-switch-app/efr32/src/main.cpp | 1 -
examples/lighting-app/efr32/README.md | 9 +
examples/lighting-app/efr32/src/main.cpp | 1 -
examples/lock-app/efr32/README.md | 9 +
examples/lock-app/efr32/src/main.cpp | 1 -
examples/ota-requestor-app/efr32/src/main.cpp | 1 -
examples/persistent-storage/efr32/BUILD.gn | 9 +-
examples/persistent-storage/efr32/README.md | 10 +-
examples/persistent-storage/efr32/main.cpp | 2 +
.../platform/efr32/ldscripts/efr32mg12.ld | 45 +--
.../platform/efr32/ldscripts/efr32mg24.ld | 48 +--
examples/shell/efr32/src/main.cpp | 1 -
examples/window-app/efr32/README.md | 9 +
examples/window-app/efr32/src/main.cpp | 1 -
scripts/examples/gn_efr32_example.sh | 11 +-
src/platform/EFR32/BLEManagerImpl.cpp | 17 +-
src/platform/EFR32/CHIPDevicePlatformConfig.h | 45 ---
.../EFR32/ConfigurationManagerImpl.cpp | 2 -
src/platform/EFR32/ConfigurationManagerImpl.h | 2 +-
src/platform/EFR32/EFR32Config.cpp | 332 +++++-------------
src/platform/EFR32/EFR32Config.h | 127 ++++---
.../EFR32/KeyValueStoreManagerImpl.cpp | 223 +++++++-----
src/platform/EFR32/KeyValueStoreManagerImpl.h | 154 +-------
src/platform/EFR32/PlatformManagerImpl.cpp | 4 +-
src/test_driver/efr32/src/main.cpp | 1 -
third_party/efr32_sdk/efr32_sdk.gni | 11 +-
28 files changed, 427 insertions(+), 659 deletions(-)
diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt
index 37131914b0f8ce..f8d0a2dc434631 100644
--- a/.github/.wordlist.txt
+++ b/.github/.wordlist.txt
@@ -865,6 +865,7 @@ NTAG
nullable
nullptr
NUM
+NVM
nwk
NXP
objcopy
diff --git a/examples/light-switch-app/efr32/README.md b/examples/light-switch-app/efr32/README.md
index a4c9d154c5a6c8..831b66406cd7d2 100644
--- a/examples/light-switch-app/efr32/README.md
+++ b/examples/light-switch-app/efr32/README.md
@@ -406,3 +406,12 @@ is_debug
show_qr_code
$ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false"
+
+### KVS maximum entry count
+
+kvs_max_entries
+
+ Set the maximum Kvs entries that can be stored in NVM (Default 75)
+ Thresholds: 30 <= kvs_max_entries <= 255
+
+ $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A kvs_max_entries=50
diff --git a/examples/light-switch-app/efr32/src/main.cpp b/examples/light-switch-app/efr32/src/main.cpp
index 7ca14521d301e5..5a587b75371184 100644
--- a/examples/light-switch-app/efr32/src/main.cpp
+++ b/examples/light-switch-app/efr32/src/main.cpp
@@ -132,7 +132,6 @@ int main(void)
EFR32_LOG("Init CHIP Stack");
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
CHIP_ERROR ret = PlatformMgr().InitChipStack();
if (ret != CHIP_NO_ERROR)
diff --git a/examples/lighting-app/efr32/README.md b/examples/lighting-app/efr32/README.md
index a6fc76292a8d4a..a4e45a380c07af 100644
--- a/examples/lighting-app/efr32/README.md
+++ b/examples/lighting-app/efr32/README.md
@@ -356,3 +356,12 @@ is_debug
show_qr_code
$ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false"
+
+### KVS maximum entry count
+
+kvs_max_entries
+
+ Set the maximum Kvs entries that can be stored in NVM (Default 75)
+ Thresholds: 30 <= kvs_max_entries <= 255
+
+ $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A kvs_max_entries=50
diff --git a/examples/lighting-app/efr32/src/main.cpp b/examples/lighting-app/efr32/src/main.cpp
index e0f1a4bc26fc1c..d521646e5f87fe 100644
--- a/examples/lighting-app/efr32/src/main.cpp
+++ b/examples/lighting-app/efr32/src/main.cpp
@@ -136,7 +136,6 @@ int main(void)
EFR32_LOG("Init CHIP Stack");
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
CHIP_ERROR ret = PlatformMgr().InitChipStack();
if (ret != CHIP_NO_ERROR)
diff --git a/examples/lock-app/efr32/README.md b/examples/lock-app/efr32/README.md
index 65442b31d84229..61c53124287916 100644
--- a/examples/lock-app/efr32/README.md
+++ b/examples/lock-app/efr32/README.md
@@ -321,3 +321,12 @@ is_debug
show_qr_code
$ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false"
+
+### KVS maximum entry count
+
+kvs_max_entries
+
+ Set the maximum Kvs entries that can be stored in NVM (Default 75)
+ Thresholds: 30 <= kvs_max_entries <= 255
+
+ $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A kvs_max_entries=50
diff --git a/examples/lock-app/efr32/src/main.cpp b/examples/lock-app/efr32/src/main.cpp
index 2ed647b327aa72..79496aba236330 100644
--- a/examples/lock-app/efr32/src/main.cpp
+++ b/examples/lock-app/efr32/src/main.cpp
@@ -132,7 +132,6 @@ int main(void)
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
CHIP_ERROR ret = PlatformMgr().InitChipStack();
if (ret != CHIP_NO_ERROR)
diff --git a/examples/ota-requestor-app/efr32/src/main.cpp b/examples/ota-requestor-app/efr32/src/main.cpp
index c268cdd94ca56b..b193b31aae3ac1 100644
--- a/examples/ota-requestor-app/efr32/src/main.cpp
+++ b/examples/ota-requestor-app/efr32/src/main.cpp
@@ -169,7 +169,6 @@ int main(void)
EFR32_LOG("Init CHIP Stack");
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
CHIP_ERROR ret = PlatformMgr().InitChipStack();
if (ret != CHIP_NO_ERROR)
diff --git a/examples/persistent-storage/efr32/BUILD.gn b/examples/persistent-storage/efr32/BUILD.gn
index 3508a4a1b8a882..05877c4e879656 100644
--- a/examples/persistent-storage/efr32/BUILD.gn
+++ b/examples/persistent-storage/efr32/BUILD.gn
@@ -37,6 +37,7 @@ efr32_sdk("sdk") {
"${chip_root}/src/platform/EFR32",
"${efr32_project_dir}/include",
"${examples_plat_dir}",
+ "${chip_root}/src/lib",
]
defines = [ "BOARD_ID=${efr32_board}" ]
@@ -46,22 +47,20 @@ efr32_executable("persistent_storage") {
output_name = "chip-efr32-persistent_storage-example.out"
sources = [
- "${efr32_project_dir}/../KeyValueStorageTest.cpp",
"${examples_plat_dir}/heap_4_silabs.c",
"${examples_plat_dir}/init_efrPlatform.cpp",
+ "../KeyValueStorageTest.cpp",
"main.cpp",
]
deps = [
":sdk",
- "$dir_pw_assert",
- "$dir_pw_kvs:crc16",
"${chip_root}/src/lib",
]
include_dirs = [
- "${efr32_project_dir}/..",
- "${efr32_project_dir}/include",
+ "..",
+ "include",
]
ldscript = "${examples_plat_dir}/ldscripts/${efr32_family}.ld"
diff --git a/examples/persistent-storage/efr32/README.md b/examples/persistent-storage/efr32/README.md
index 2f3b5773821006..841a72fe82727b 100644
--- a/examples/persistent-storage/efr32/README.md
+++ b/examples/persistent-storage/efr32/README.md
@@ -28,15 +28,7 @@ platforms.
## EFR32
-The EFR32 platform KVS is fully implemented, the KVS is enabled and configured
-using these defines:
-
-```
-defines = [
- "CHIP_KVS_SECTOR_COUNT=4",
- "CHIP_KVS_BASE_SECTOR_INDEX=((FLASH_SIZE/FLASH_PAGE_SIZE)-(CHIP_KVS_SECTOR_COUNT))",
-]
-```
+The EFR32 platform KVS is fully implemented
diff --git a/examples/persistent-storage/efr32/main.cpp b/examples/persistent-storage/efr32/main.cpp
index 04d8aa428b4fa9..3d9674369fa153 100644
--- a/examples/persistent-storage/efr32/main.cpp
+++ b/examples/persistent-storage/efr32/main.cpp
@@ -31,6 +31,8 @@
#include "KeyValueStorageTest.h"
#include "init_efrPlatform.h"
#include "sl_system_kernel.h"
+#include
+#include
#include
static TaskHandle_t sTestTaskHandle;
diff --git a/examples/platform/efr32/ldscripts/efr32mg12.ld b/examples/platform/efr32/ldscripts/efr32mg12.ld
index f55f03521bc1e4..9dba3e1ded84e2 100644
--- a/examples/platform/efr32/ldscripts/efr32mg12.ld
+++ b/examples/platform/efr32/ldscripts/efr32mg12.ld
@@ -177,36 +177,6 @@ SECTIONS
__etext = .;
- /*******************************************************************/
- /* Define flash block for BLE-simee & chip-nvm3 */
- /* simee: 9000H (36k) bytes for BLE nvm3 */
- /* chipNvm3_section: 4000H (16k) bytes for chip nvm3. */
- /* 8K is reserved for OpenThread's NVM which is mapped directly at */
- /* the top of flash */
- /*******************************************************************/
-
- OPENTHREAD_NVM_SIZE = 8192;
-
- .nvm_dummy (DSECT):
- {
- __nvm3_dummy_begin = .;
- . = ALIGN (8192);
- __nvm3_dummy_simee = .;
- KEEP(*(.simee));
- . = ALIGN (8192);
- __nvm3_dummy_chip = .;
- KEEP(*(chipNvm3_section));
- . = ALIGN (8192);
- . += DEFINED(SILABS_WIFI) ? 0 : OPENTHREAD_NVM_SIZE;
- . = DEFINED(SILABS_WIFI) ? . : ALIGN (8192);
- } > FLASH
-
- /* Set NVM to end of FLASH */
- __nvm3Base = LENGTH(FLASH) - SIZEOF(.nvm_dummy) + (__nvm3_dummy_simee - __nvm3_dummy_begin);
- __chipNvm3Base = LENGTH(FLASH) - SIZEOF(.nvm_dummy) + (__nvm3_dummy_chip - __nvm3_dummy_begin);
-
-
- /*******************************************************************/
.data : AT (__etext)
{
@@ -264,6 +234,8 @@ SECTIONS
KEEP(*(.heap*))
__HeapLimit = .;
} > RAM
+
+ __main_flash_end__ = ORIGIN(FLASH) + LENGTH(FLASH);
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
@@ -279,9 +251,18 @@ SECTIONS
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
- /* Check if data + heap + stack exceeds RAM limit */
- ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+ .nvm (DSECT) : {
+ KEEP(*(.simee*))
+ } > FLASH
+ linker_nvm_end = __main_flash_end__ - 2048;
+ linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm);
+ linker_nvm_size = SIZEOF(.nvm);
+ __nvm3Base = linker_nvm_begin;
+
+ /* Check if data + heap + stack exceeds RAM limit */
+ /*ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")*/
+ ASSERT( (linker_nvm_begin + SIZEOF(.nvm)) <= __main_flash_end__, "NVM3 is excessing the flash size !")
/* Check if FLASH usage exceeds FLASH size */
ASSERT( LENGTH(FLASH) >= (__etext), "FLASH memory overflowed !")
diff --git a/examples/platform/efr32/ldscripts/efr32mg24.ld b/examples/platform/efr32/ldscripts/efr32mg24.ld
index 8a7835f6cf2fd0..06bfc7c1842170 100644
--- a/examples/platform/efr32/ldscripts/efr32mg24.ld
+++ b/examples/platform/efr32/ldscripts/efr32mg24.ld
@@ -177,36 +177,6 @@ SECTIONS
__etext = .;
- /*******************************************************************/
- /* Define flash block for BLE-simee & chip-nvm3 */
- /* simee: 9000H (36k) bytes for BLE nvm3 */
- /* chipNvm3_section: 4000H (16k) bytes for chip nvm3. */
- /* 8K is reserved for OpenThread's NVM which is mapped directly at */
- /* the top of flash */
- /*******************************************************************/
-
- OPENTHREAD_NVM_SIZE = 8192;
-
- .nvm_dummy (DSECT):
- {
- __nvm3_dummy_begin = .;
- . = ALIGN (8192);
- __nvm3_dummy_simee = .;
- KEEP(*(.simee));
- . = ALIGN (8192);
- __nvm3_dummy_chip = .;
- KEEP(*(chipNvm3_section));
- . = ALIGN (8192);
- . += DEFINED(SILABS_WIFI) ? 0 : OPENTHREAD_NVM_SIZE;
- . = DEFINED(SILABS_WIFI) ? . : ALIGN (8192);
- } > FLASH
-
- /* Set NVM to end of FLASH */
- __nvm3Base = (ORIGIN(FLASH) + LENGTH(FLASH)) - SIZEOF(.nvm_dummy) + (__nvm3_dummy_simee - __nvm3_dummy_begin);
- __chipNvm3Base = (ORIGIN(FLASH) + LENGTH(FLASH)) - SIZEOF(.nvm_dummy) + (__nvm3_dummy_chip - __nvm3_dummy_begin);
-
-
- /*******************************************************************/
.data : AT (__etext)
{
@@ -265,6 +235,8 @@ SECTIONS
__HeapLimit = .;
} > RAM
+ __main_flash_end__ = ORIGIN(FLASH) + LENGTH(FLASH);
+
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
@@ -279,11 +251,17 @@ SECTIONS
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
- /* Check if data + heap + stack exceeds RAM limit */
- ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+ .nvm (DSECT) : {
+ KEEP(*(.simee*))
+ } > FLASH
+
+ linker_nvm_end = __main_flash_end__;
+ linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm);
+ linker_nvm_size = SIZEOF(.nvm);
+ __nvm3Base = linker_nvm_begin;
+ /* Check if data + heap + stack exceeds RAM limit */
+ /*ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")*/
+ ASSERT( (linker_nvm_begin + SIZEOF(.nvm)) <= __main_flash_end__, "NVM3 is excessing the flash size !")
- /* Check if FLASH usage exceeds FLASH size */
- ASSERT( (ORIGIN(FLASH) + LENGTH(FLASH)) >= (__etext + SIZEOF(.data)), "FLASH memory overflowed !")
- ASSERT((__etext + SIZEOF(.data)) <= __nvm3Base, "FLASH memory overlapped with NVM section.")
}
diff --git a/examples/shell/efr32/src/main.cpp b/examples/shell/efr32/src/main.cpp
index 7592513a730448..9bb827a3d4ea0c 100644
--- a/examples/shell/efr32/src/main.cpp
+++ b/examples/shell/efr32/src/main.cpp
@@ -110,7 +110,6 @@ int main(void)
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
CHIP_ERROR ret = PlatformMgr().InitChipStack();
if (ret != CHIP_NO_ERROR)
diff --git a/examples/window-app/efr32/README.md b/examples/window-app/efr32/README.md
index 8fac6941c0a8d8..8756365f3a7570 100644
--- a/examples/window-app/efr32/README.md
+++ b/examples/window-app/efr32/README.md
@@ -356,3 +356,12 @@ is_debug
show_qr_code
$ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false"
+
+### KVS maximum entry count
+
+kvs_max_entries
+
+ Set the maximum Kvs entries that can be stored in NVM (Default 75)
+ Thresholds: 30 <= kvs_max_entries <= 255
+
+ $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A kvs_max_entries=50
diff --git a/examples/window-app/efr32/src/main.cpp b/examples/window-app/efr32/src/main.cpp
index cfffc9dc071d87..4e844ccd847e34 100644
--- a/examples/window-app/efr32/src/main.cpp
+++ b/examples/window-app/efr32/src/main.cpp
@@ -108,7 +108,6 @@ int main(void)
// Init Chip memory management before the stack
chip::Platform::MemoryInit();
- chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
err = PlatformMgr().InitChipStack();
if (err != CHIP_NO_ERROR)
diff --git a/scripts/examples/gn_efr32_example.sh b/scripts/examples/gn_efr32_example.sh
index 0ce40ef66d7287..37346facff934d 100755
--- a/scripts/examples/gn_efr32_example.sh
+++ b/scripts/examples/gn_efr32_example.sh
@@ -24,7 +24,7 @@ source "$(dirname "$0")/../../scripts/activate.sh"
set -x
env
USE_WIFI=false
-
+CHIP_ROOT="$(dirname "$0")/../.."
USAGE="./scripts/examples/gn_efr32_example.sh []"
if [ "$#" == "0" ]; then
@@ -63,6 +63,9 @@ if [ "$#" == "0" ]; then
Monitor & log memory usage at runtime. (Default false)
enable_openthread_cli
Enables openthread cli without matter shell. (Default true)
+ kvs_max_entries
+ Set the maxium Kvs entries that can be store in NVM (Default 75)
+ Thresholds: 30 <= kvs_max_entries <= 255
show_qr_code
Enables QR code on LCD for devices with an LCD
setupDiscriminator
@@ -144,14 +147,14 @@ else
BUILD_DIR=$OUTDIR/$EFR32_BOARD
echo BUILD_DIR="$BUILD_DIR"
if [ "$USE_WIFI" == true ]; then
- gn gen --check --fail-on-unused-args --root="$ROOT" --dotfile="$ROOT"/build_for_wifi_gnfile.gn --args="efr32_board=\"$EFR32_BOARD\" $optArgs" "$BUILD_DIR"
+ gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --dotfile="$ROOT"/build_for_wifi_gnfile.gn --args="efr32_board=\"$EFR32_BOARD\" $optArgs" "$BUILD_DIR"
else
# thread build
#
if [ -z "$optArgs" ]; then
- gn gen --check --fail-on-unused-args --root="$ROOT" --args="efr32_board=\"$EFR32_BOARD\"" "$BUILD_DIR"
+ gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --args="efr32_board=\"$EFR32_BOARD\"" "$BUILD_DIR"
else
- gn gen --check --fail-on-unused-args --root="$ROOT" --args="efr32_board=\"$EFR32_BOARD\" $optArgs" "$BUILD_DIR"
+ gn gen --check --fail-on-unused-args --export-compile-commands --root="$ROOT" --args="efr32_board=\"$EFR32_BOARD\" $optArgs" "$BUILD_DIR"
fi
fi
ninja -v -C "$BUILD_DIR"/
diff --git a/src/platform/EFR32/BLEManagerImpl.cpp b/src/platform/EFR32/BLEManagerImpl.cpp
index bbbf59105bdba5..13805feebb1f24 100644
--- a/src/platform/EFR32/BLEManagerImpl.cpp
+++ b/src/platform/EFR32/BLEManagerImpl.cpp
@@ -76,6 +76,14 @@ namespace {
#define BLE_CONFIG_RF_PATH_GAIN_TX (0)
#define BLE_CONFIG_RF_PATH_GAIN_RX (0)
+// Default Connection parameters
+#define BLE_CONFIG_MIN_INTERVAL (16) // Time = Value x 1.25 ms = 30ms
+#define BLE_CONFIG_MAX_INTERVAL (80) // Time = Value x 1.25 ms = 100ms
+#define BLE_CONFIG_LATENCY (0)
+#define BLE_CONFIG_TIMEOUT (100) // Time = Value x 10 ms = 1s
+#define BLE_CONFIG_MIN_CE_LENGTH (0) // Leave to min value
+#define BLE_CONFIG_MAX_CE_LENGTH (0xFFFF) // Leave to max value
+
TimerHandle_t sbleAdvTimeoutTimer; // FreeRTOS sw timer.
/* Bluetooth stack configuration parameters (see "UG136: Silicon Labs Bluetooth C Application Developer's Guide" for
@@ -249,6 +257,8 @@ void BLEManagerImpl::bluetoothStackEventHandler(void * p_arg)
RAIL_GetVersion(&railVer, true);
ChipLogProgress(DeviceLayer, "RAIL version:, v%d.%d.%d-b%d", railVer.major, railVer.minor, railVer.rev,
railVer.build);
+ sl_bt_connection_set_default_parameters(BLE_CONFIG_MIN_INTERVAL, BLE_CONFIG_MAX_INTERVAL, BLE_CONFIG_LATENCY,
+ BLE_CONFIG_TIMEOUT, BLE_CONFIG_MIN_CE_LENGTH, BLE_CONFIG_MAX_CE_LENGTH);
}
break;
@@ -257,7 +267,7 @@ void BLEManagerImpl::bluetoothStackEventHandler(void * p_arg)
}
break;
case sl_bt_evt_connection_parameters_id: {
- // ChipLogProgress(DeviceLayer, "Connection parameter ID received. Nothing to do");
+ // ChipLogProgress(DeviceLayer, "Connection parameter ID received");
}
break;
case sl_bt_evt_connection_phy_status_id: {
@@ -307,6 +317,11 @@ void BLEManagerImpl::bluetoothStackEventHandler(void * p_arg)
}
break;
+ case sl_bt_evt_connection_remote_used_features_id: {
+ // ChipLogProgress(DeviceLayer, "link layer features supported by the remote device");
+ }
+ break;
+
default:
ChipLogProgress(DeviceLayer, "evt_UNKNOWN id = %08" PRIx32, SL_BT_MSG_ID(bluetooth_evt->header));
break;
diff --git a/src/platform/EFR32/CHIPDevicePlatformConfig.h b/src/platform/EFR32/CHIPDevicePlatformConfig.h
index ba22beda6ab6d9..0303a7b90059af 100644
--- a/src/platform/EFR32/CHIPDevicePlatformConfig.h
+++ b/src/platform/EFR32/CHIPDevicePlatformConfig.h
@@ -56,51 +56,6 @@
// These are configuration options that are unique to the EFR32 platform.
// These can be overridden by the application as needed.
-// -------------- EFR32 NVM3 Storage Configuration -------------
-
-/**
- * @def CHIP_DEVICE_CONFIG_NVM3_MAX_NUM_OBJECTS
- *
- * @brief
- * Configures the size of the nvm3 cache and should be set >= the
- * maximum number of Chip Config objects, e.g...
- * Factory configs[5], System configs[23], Counter configs[32] + margin[4] = 64.
- *
- */
-#ifndef CHIP_DEVICE_CONFIG_NVM3_MAX_NUM_OBJECTS
-#define CHIP_DEVICE_CONFIG_NVM3_MAX_NUM_OBJECTS 64
-#endif // CHIP_DEVICE_CONFIG_NVM3_MAX_NUM_OBJECTS
-
-/**
- * @def CHIP_DEVICE_CONFIG_NVM3_MAX_OBJECT_SIZE
- *
- * @brief
- * This determines the max size for any Chip nvm3 object
- * (e.g. for Config 'string' or 'binary' types).
- */
-#ifndef CHIP_DEVICE_CONFIG_NVM3_MAX_OBJECT_SIZE
-#define CHIP_DEVICE_CONFIG_NVM3_MAX_OBJECT_SIZE 1000
-#endif // CHIP_DEVICE_CONFIG_NVM3_MAX_OBJECT_SIZE
-
-/**
- * @def CHIP_DEVICE_CONFIG_NVM3_NUM_FLASH_PAGES_FOR_STORAGE
- *
- * @brief
- * This determines the Flash size used for nvm3 data storage:-
- * (assuming 2k Flash page size) => Total Flash size for nvm3: 8 * 2k = 16k
- * The total size should allow sufficient margin for wear-levelling and
- * repacking.
- *
- * MG21 and MG 24 a 8k per page. 3 * 8k = 24k
- */
-#ifndef CHIP_DEVICE_CONFIG_NVM3_NUM_FLASH_PAGES_FOR_STORAGE
-#if defined(EFR32MG21) || defined(EFR32MG24)
-#define CHIP_DEVICE_CONFIG_NVM3_NUM_FLASH_PAGES_FOR_STORAGE 3
-#else
-#define CHIP_DEVICE_CONFIG_NVM3_NUM_FLASH_PAGES_FOR_STORAGE 8
-#endif
-#endif // CHIP_DEVICE_CONFIG_NVM3_NUM_FLASH_PAGES_FOR_STORAGE
-
// ========== Platform-specific Configuration Overrides =========
#ifndef CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY
diff --git a/src/platform/EFR32/ConfigurationManagerImpl.cpp b/src/platform/EFR32/ConfigurationManagerImpl.cpp
index b5a266454d6961..9c370bf3b52e6d 100644
--- a/src/platform/EFR32/ConfigurationManagerImpl.cpp
+++ b/src/platform/EFR32/ConfigurationManagerImpl.cpp
@@ -284,9 +284,7 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg)
#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD
-#if CHIP_KVS_AVAILABLE
PersistedStorage::KeyValueStoreMgrImpl().ErasePartition();
-#endif // CHIP_KVS_AVAILABLE
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
ChipLogProgress(DeviceLayer, "Clearing WiFi provision");
diff --git a/src/platform/EFR32/ConfigurationManagerImpl.h b/src/platform/EFR32/ConfigurationManagerImpl.h
index 7a157ccc3b7fac..baa3e5849afaec 100644
--- a/src/platform/EFR32/ConfigurationManagerImpl.h
+++ b/src/platform/EFR32/ConfigurationManagerImpl.h
@@ -26,7 +26,7 @@
#include
-#include "EFR32Config.h"
+#include
namespace chip {
namespace DeviceLayer {
diff --git a/src/platform/EFR32/EFR32Config.cpp b/src/platform/EFR32/EFR32Config.cpp
index da1734e34d898f..f78797c504c6e8 100644
--- a/src/platform/EFR32/EFR32Config.cpp
+++ b/src/platform/EFR32/EFR32Config.cpp
@@ -31,55 +31,38 @@
#include "FreeRTOS.h"
#include "nvm3.h"
+#include "nvm3_default.h"
#include "nvm3_hal_flash.h"
-namespace chip {
-namespace DeviceLayer {
-namespace Internal {
-
-// Two macros are provided to support the creation of the Silicon Labs NVM3 area and
-// initialization data- NVM3_DEFINE_SECTION_STATIC_DATA() and NVM3_DEFINE_SECTION_INIT_DATA().
-// A linker section called 'name'_section is defined by NVM3_DEFINE_SECTION_STATIC_DATA().
-// The NVM3 area is placed at the top of the device FLASH section by the linker
-// script file: chip-efr32-bringup-MG12P.ld. An error is returned
-// by nvm3_open() on alignment or size violation.
-
-// Local version of SDK macro (avoids uninitialized var compile error).
-#define CHIP_NVM3_DEFINE_SECTION_STATIC_DATA(name, nvmSize, cacheSize) \
- static nvm3_CacheEntry_t name##_cache[cacheSize]; \
- static uint8_t name##_nvm[nvmSize] SL_ATTRIBUTE_SECTION(STRINGIZE(name##_section))
-
-// Local version of SDK macro (allows CHIP to configure the maximum nvm3 object size and headroom).
-#define CHIP_NVM3_DEFINE_SECTION_INIT_DATA(name, maxObjectSize, repackHeadroom) \
- static nvm3_Init_t name = { \
- (nvm3_HalPtr_t) name##_nvm, \
- sizeof(name##_nvm), \
- name##_cache, \
- sizeof(name##_cache) / sizeof(nvm3_CacheEntry_t), \
- maxObjectSize, \
- repackHeadroom, \
- &nvm3_halFlashHandle, \
- }
-
-#define CHIP_NVM3_REPACK_HEADROOM 64 // Threshold for User non-forced nvm3 flash repacking.
-
+// Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd
+// for an application controlled re-entrance protection
#define EFR32_SEM_TIMEOUT_ms 5
-
-static nvm3_Handle_t handle;
static SemaphoreHandle_t nvm3_Sem;
static StaticSemaphore_t nvm3_SemStruct;
-// Declare NVM3 data area and cache.
+void nvm3_lockBegin(void)
+{
+ VerifyOrDie(nvm3_Sem != NULL);
+ xSemaphoreTake(nvm3_Sem, EFR32_SEM_TIMEOUT_ms);
+}
-CHIP_NVM3_DEFINE_SECTION_STATIC_DATA(chipNvm3, CHIP_DEVICE_CONFIG_NVM3_NUM_FLASH_PAGES_FOR_STORAGE * FLASH_PAGE_SIZE,
- CHIP_DEVICE_CONFIG_NVM3_MAX_NUM_OBJECTS);
+void nvm3_lockEnd(void)
+{
+ VerifyOrDie(nvm3_Sem != NULL);
+ xSemaphoreGive(nvm3_Sem);
+}
-CHIP_NVM3_DEFINE_SECTION_INIT_DATA(chipNvm3, CHIP_DEVICE_CONFIG_NVM3_MAX_OBJECT_SIZE, CHIP_NVM3_REPACK_HEADROOM);
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+// Matter NVM3 space is placed in the silabs default nvm3 section shared with other stack.
+// 'kMatterNvm3KeyDomain' identify the matter nvm3 domain.
+// The NVM3 default section is placed at end of Flash minus 1 page byt the linker file
+// See examples/platform/efr32/ldscripts/efr32mgXX.ld
CHIP_ERROR EFR32Config::Init()
{
- CHIP_ERROR err;
-
nvm3_Sem = xSemaphoreCreateBinaryStatic(&nvm3_SemStruct);
if (nvm3_Sem == NULL)
@@ -87,12 +70,13 @@ CHIP_ERROR EFR32Config::Init()
return CHIP_ERROR_NO_MEMORY;
}
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
+ return MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit));
+}
-exit:
- OnExit();
- return err;
+void EFR32Config::DeInit()
+{
+ vSemaphoreDelete(nvm3_Sem);
+ nvm3_close(nvm3_defaultHandle);
}
CHIP_ERROR EFR32Config::ReadConfigValue(Key key, bool & val)
@@ -102,28 +86,18 @@ CHIP_ERROR EFR32Config::ReadConfigValue(Key key, bool & val)
size_t dataLen;
bool tmpVal;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Get nvm3 object info.
- err = MapNvm3Error(nvm3_getObjectInfo(&handle, key, &objectType, &dataLen));
+ err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
SuccessOrExit(err);
// Read nvm3 bytes into tmp.
- err = MapNvm3Error(nvm3_readData(&handle, key, &tmpVal, dataLen));
+ err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &tmpVal, dataLen));
SuccessOrExit(err);
val = tmpVal;
exit:
- OnExit();
return err;
}
@@ -134,27 +108,18 @@ CHIP_ERROR EFR32Config::ReadConfigValue(Key key, uint32_t & val)
size_t dataLen;
uint32_t tmpVal;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Get nvm3 object info.
- err = MapNvm3Error(nvm3_getObjectInfo(&handle, key, &objectType, &dataLen));
+ err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
SuccessOrExit(err);
// Read nvm3 bytes into tmp.
- err = MapNvm3Error(nvm3_readData(&handle, key, &tmpVal, dataLen));
+ err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &tmpVal, dataLen));
SuccessOrExit(err);
val = tmpVal;
exit:
- OnExit();
return err;
}
@@ -165,28 +130,18 @@ CHIP_ERROR EFR32Config::ReadConfigValue(Key key, uint64_t & val)
size_t dataLen;
uint64_t tmpVal;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Get nvm3 object info.
- err = MapNvm3Error(nvm3_getObjectInfo(&handle, key, &objectType, &dataLen));
+ err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
SuccessOrExit(err);
// Read nvm3 bytes into tmp.
- err = MapNvm3Error(nvm3_readData(&handle, key, &tmpVal, dataLen));
+ err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &tmpVal, dataLen));
SuccessOrExit(err);
val = tmpVal;
exit:
- OnExit();
return err;
}
@@ -198,19 +153,10 @@ CHIP_ERROR EFR32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize,
outLen = 0;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Get nvm3 object info.
- err = MapNvm3Error(nvm3_getObjectInfo(&handle, key, &objectType, &dataLen));
+ err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
SuccessOrExit(err);
VerifyOrExit(dataLen > 0, err = CHIP_ERROR_INVALID_STRING_LENGTH);
@@ -221,7 +167,7 @@ CHIP_ERROR EFR32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize,
// terminator char).
VerifyOrExit((bufSize > dataLen), err = CHIP_ERROR_BUFFER_TOO_SMALL);
- err = MapNvm3Error(nvm3_readData(&handle, key, buf, dataLen));
+ err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, buf, dataLen));
SuccessOrExit(err);
outLen = ((dataLen == 1) && (buf[0] == 0)) ? 0 : dataLen;
@@ -237,7 +183,7 @@ CHIP_ERROR EFR32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize,
{
// Read the first byte of the nvm3 string into a tmp var.
char firstByte;
- err = MapNvm3Error(nvm3_readData(&handle, key, &firstByte, 1));
+ err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, &firstByte, 1));
SuccessOrExit(err);
outLen = (firstByte == 0) ? 0 : dataLen;
@@ -245,7 +191,6 @@ CHIP_ERROR EFR32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize,
}
exit:
- OnExit();
return err;
}
@@ -256,19 +201,10 @@ CHIP_ERROR EFR32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSiz
size_t dataLen;
outLen = 0;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Get nvm3 object info.
- err = MapNvm3Error(nvm3_getObjectInfo(&handle, key, &objectType, &dataLen));
+ err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
SuccessOrExit(err);
VerifyOrExit(dataLen > 0, err = CHIP_ERROR_INVALID_STRING_LENGTH);
@@ -278,41 +214,68 @@ CHIP_ERROR EFR32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSiz
// enough to take the data.
VerifyOrExit((bufSize >= dataLen), err = CHIP_ERROR_BUFFER_TOO_SMALL);
- err = MapNvm3Error(nvm3_readData(&handle, key, buf, dataLen));
+ err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, buf, dataLen));
SuccessOrExit(err);
- }
- outLen = dataLen;
+ outLen = dataLen;
+ }
exit:
- OnExit();
return err;
}
-CHIP_ERROR EFR32Config::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val)
+CHIP_ERROR EFR32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset)
{
CHIP_ERROR err;
- uint32_t tmpVal;
- Key key = kMinConfigKey_ChipCounter + counterIdx;
+ uint32_t objectType;
+ size_t dataLen;
+
+ outLen = 0;
+ VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
+
+ // Get nvm3 object info.
+ err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
+ SuccessOrExit(err);
+ VerifyOrExit(dataLen > 0, err = CHIP_ERROR_INVALID_STRING_LENGTH);
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
+ if (buf != NULL)
{
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
+ // Read nvm3 bytes directly into output buffer- check buffer is long enough to take the data
+ // else read what we can but return CHIP_ERROR_BUFFER_TOO_SMALL.
+ size_t maxReadLength = dataLen - offset;
+ if (bufSize >= maxReadLength)
+ {
+ err = MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, maxReadLength));
+ SuccessOrExit(err);
+ outLen = maxReadLength;
+ }
+ else
+ {
+ err = MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, bufSize));
+ SuccessOrExit(err);
+ // read was successful, but we did not read all the data from the object.
+ err = CHIP_ERROR_BUFFER_TOO_SMALL;
+ outLen = bufSize;
+ }
}
+exit:
+ return err;
+}
- VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
+CHIP_ERROR EFR32Config::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val)
+{
+ CHIP_ERROR err;
+ uint32_t tmpVal;
+ Key key = kMinConfigKey_MatterCounter + counterIdx;
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
+ VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
// Read bytes into tmp.
- err = MapNvm3Error(nvm3_readCounter(&handle, key, &tmpVal));
+ err = MapNvm3Error(nvm3_readCounter(nvm3_defaultHandle, key, &tmpVal));
SuccessOrExit(err);
val = tmpVal;
exit:
- OnExit();
return err;
}
@@ -320,22 +283,12 @@ CHIP_ERROR EFR32Config::WriteConfigValue(Key key, bool val)
{
CHIP_ERROR err;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_ERROR_INVALID_ARGUMENT); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
- err = MapNvm3Error(nvm3_writeData(&handle, key, &val, sizeof(val)));
+ err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val)));
SuccessOrExit(err);
exit:
- OnExit();
return err;
}
@@ -343,22 +296,12 @@ CHIP_ERROR EFR32Config::WriteConfigValue(Key key, uint32_t val)
{
CHIP_ERROR err;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
- err = MapNvm3Error(nvm3_writeData(&handle, key, &val, sizeof(val)));
+ err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val)));
SuccessOrExit(err);
exit:
- OnExit();
return err;
}
@@ -366,22 +309,12 @@ CHIP_ERROR EFR32Config::WriteConfigValue(Key key, uint64_t val)
{
CHIP_ERROR err;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
- err = MapNvm3Error(nvm3_writeData(&handle, key, &val, sizeof(val)));
+ err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val)));
SuccessOrExit(err);
exit:
- OnExit();
return err;
}
@@ -394,31 +327,21 @@ CHIP_ERROR EFR32Config::WriteConfigValueStr(Key key, const char * str, size_t st
{
CHIP_ERROR err;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
if (str != NULL)
{
// Write the string to nvm3 without the terminator char (apart from
// empty strings where only the terminator char is stored in nvm3).
- err = MapNvm3Error(nvm3_writeData(&handle, key, str, (strLen > 0) ? strLen : 1));
+ err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, str, (strLen > 0) ? strLen : 1));
SuccessOrExit(err);
}
else
{
- nvm3_deleteObject(&handle, key); // no error checking here.
+ nvm3_deleteObject(nvm3_defaultHandle, key); // no error checking here.
}
exit:
- OnExit();
return err;
}
@@ -426,57 +349,37 @@ CHIP_ERROR EFR32Config::WriteConfigValueBin(Key key, const uint8_t * data, size_
{
CHIP_ERROR err;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
if (data != NULL)
{
if (dataLen > 0)
{
// Write the binary data to nvm3.
- err = MapNvm3Error(nvm3_writeData(&handle, key, data, dataLen));
+ err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, data, dataLen));
SuccessOrExit(err);
}
}
else
{
- nvm3_deleteObject(&handle, key); // no error checking here.
+ nvm3_deleteObject(nvm3_defaultHandle, key); // no error checking here.
}
exit:
- OnExit();
return err;
}
CHIP_ERROR EFR32Config::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val)
{
CHIP_ERROR err;
- Key key = kMinConfigKey_ChipCounter + counterIdx;
-
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
+ Key key = kMinConfigKey_MatterCounter + counterIdx;
VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
- err = MapNvm3Error(nvm3_writeCounter(&handle, key, val));
+ err = MapNvm3Error(nvm3_writeCounter(nvm3_defaultHandle, key, val));
SuccessOrExit(err);
exit:
- OnExit();
return err;
}
@@ -484,44 +387,21 @@ CHIP_ERROR EFR32Config::ClearConfigValue(Key key)
{
CHIP_ERROR err;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Delete the nvm3 object with the given key id.
- err = MapNvm3Error(nvm3_deleteObject(&handle, key));
+ err = MapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, key));
SuccessOrExit(err);
exit:
- OnExit();
return err;
}
bool EFR32Config::ConfigValueExists(Key key)
{
- CHIP_ERROR err;
uint32_t objectType;
size_t dataLen;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
-
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Find object with key id.
- err = MapNvm3Error(nvm3_getObjectInfo(&handle, key, &objectType, &dataLen));
-
-exit:
- OnExit();
+ CHIP_ERROR err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen));
return (err == CHIP_NO_ERROR);
}
@@ -533,15 +413,14 @@ CHIP_ERROR EFR32Config::FactoryResetConfig(void)
CHIP_ERROR err;
// Iterate over all the CHIP Config nvm3 records and delete each one...
- err = ForEachRecord(kMinConfigKey_ChipConfig, kMaxConfigKey_ChipConfig, false,
+ err = ForEachRecord(kMinConfigKey_MatterConfig, kMaxConfigKey_MatterConfig, false,
[](const Key & nvm3Key, const size_t & length) -> CHIP_ERROR {
CHIP_ERROR err2;
// Delete the nvm3 object with the given key id.
- err2 = MapNvm3Error(nvm3_deleteObject(&handle, nvm3Key));
+ err2 = ClearConfigValue(nvm3Key);
SuccessOrExit(err2);
exit:
- nvm3_close(&handle);
return err2;
});
@@ -580,11 +459,6 @@ CHIP_ERROR EFR32Config::ForEachRecord(Key firstNvm3Key, Key lastNvm3Key, bool ad
// Invokes the callers CB function when appropriate.
CHIP_ERROR err = CHIP_NO_ERROR;
- if (pdFALSE == xSemaphoreTake(nvm3_Sem, pdMS_TO_TICKS(EFR32_SEM_TIMEOUT_ms)))
- {
- err = CHIP_ERROR_TIMEOUT;
- SuccessOrExit(err);
- }
for (Key nvm3Key = firstNvm3Key; nvm3Key <= lastNvm3Key; ++nvm3Key)
{
@@ -592,12 +466,8 @@ CHIP_ERROR EFR32Config::ForEachRecord(Key firstNvm3Key, Key lastNvm3Key, bool ad
uint32_t objectType;
size_t dataLen;
- // Open nvm3 handle for reading on each iteration.
- err = MapNvm3Error(nvm3_open(&handle, &chipNvm3));
- SuccessOrExit(err);
-
// Find nvm3 object with current nvm3 iteration key.
- nvm3Res = nvm3_getObjectInfo(&handle, nvm3Key, &objectType, &dataLen);
+ nvm3Res = nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objectType, &dataLen);
switch (nvm3Res)
{
case ECODE_NVM3_OK:
@@ -624,16 +494,14 @@ CHIP_ERROR EFR32Config::ForEachRecord(Key firstNvm3Key, Key lastNvm3Key, bool ad
SuccessOrExit(err);
}
-exit:
- OnExit();
+exit:;
return err;
}
bool EFR32Config::ValidConfigKey(Key key)
{
- // Returns true if the key is in the valid CHIP Config nvm3 key range.
-
- if ((key >= kMinConfigKey_ChipFactory) && (key <= kMaxConfigKey_ChipCounter))
+ // Returns true if the key is in the valid Matter Config nvm3 key range.
+ if ((key >= kMinConfigKey_MatterFactory) && (key <= kMaxConfigKey_MatterKvs))
{
return true;
}
@@ -652,13 +520,7 @@ void EFR32Config::RepackNvm3Flash(void)
// Repack nvm3 flash if nvm3 space < headroom threshold.
// Note- checking periodically during idle periods should prevent
// forced repack events on any write operation.
- nvm3_repack(&handle);
-}
-
-void EFR32Config::OnExit()
-{
- xSemaphoreGive(nvm3_Sem);
- nvm3_close(&handle);
+ nvm3_repack(nvm3_defaultHandle);
}
} // namespace Internal
diff --git a/src/platform/EFR32/EFR32Config.h b/src/platform/EFR32/EFR32Config.h
index 638dd534e578fe..6b8bf52428a04f 100644
--- a/src/platform/EFR32/EFR32Config.h
+++ b/src/platform/EFR32/EFR32Config.h
@@ -31,6 +31,13 @@
#include "nvm3.h"
#include "nvm3_hal_flash.h"
+#ifndef KVS_MAX_ENTRIES
+#define KVS_MAX_ENTRIES 75 // Available key slot count for Kvs Key mapping.
+#endif
+
+static_assert((KVS_MAX_ENTRIES <= 255), "Implementation supports up to 255 Kvs entries");
+static_assert((KVS_MAX_ENTRIES >= 30), "Mininimal Kvs entries requirement is not met");
+
namespace chip {
namespace DeviceLayer {
namespace Internal {
@@ -46,78 +53,94 @@ namespace Internal {
* the template class (e.g. the ReadConfigValue() method).
*/
-// Silabs NVM3 objects use a 20-bit number, however User key range is
-// restricted to 16 bits i.e. 0x0000 -> 0xFFFF.
-// e.g. key = 0xA201
+// Silabs NVM3 objects use a 20-bit number,
+// NVM3 Key 19:16 Stack region
+// NVM3 Key 15:0 Available NVM3 keys 0x0000 -> 0xFFFF.
+// e.g. key = 0x0AA201
+// '0A' = Matter nvm3 region
// 'A2' = the nv group base offest (Factory, Config or Counter)
// '01' = the id offset inside the group.
+constexpr uint32_t kMatterNvm3KeyDomain = 0x0A0000U;
constexpr inline uint32_t EFR32ConfigKey(uint8_t keyBaseOffset, uint8_t id)
{
- return static_cast(keyBaseOffset) << 8 | id;
+ return kMatterNvm3KeyDomain | static_cast(keyBaseOffset) << 8 | id;
}
class EFR32Config
{
-public:
public:
// Definitions for Silicon Labs EFR32 NVM3 driver:-
using Key = uint32_t;
// NVM3 key base offsets used by the CHIP Device Layer.
- static constexpr uint8_t kChipFactory_KeyBase =
- 0xA2; // Persistent config values set at manufacturing time. Retained during factory reset.
- static constexpr uint8_t kChipConfig_KeyBase = 0xA3; // Persistent config values set at runtime. Cleared during factory reset.
- static constexpr uint8_t kChipCounter_KeyBase =
- 0xA4; // Persistent counter values set at runtime. Retained during factory reset.
+ // Persistent config values set at manufacturing time. Retained during factory reset.
+ static constexpr uint8_t kMatterFactory_KeyBase = 0xA2;
+ // Persistent config values set at runtime. Cleared during factory reset.
+ static constexpr uint8_t kMatterConfig_KeyBase = 0xA3;
+ // Persistent counter values set at runtime. Retained during factory reset.
+ static constexpr uint8_t kMatterCounter_KeyBase = 0xA4;
+ // Persistent config values set at runtime. Cleared during factory reset.
+ static constexpr uint8_t kMatterKvs_KeyBase = 0xA5;
// Key definitions for well-known configuration values.
// Factory config keys
- static constexpr Key kConfigKey_SerialNum = EFR32ConfigKey(kChipFactory_KeyBase, 0x00);
- static constexpr Key kConfigKey_MfrDeviceId = EFR32ConfigKey(kChipFactory_KeyBase, 0x01);
- static constexpr Key kConfigKey_MfrDeviceCert = EFR32ConfigKey(kChipFactory_KeyBase, 0x02);
- static constexpr Key kConfigKey_MfrDevicePrivateKey = EFR32ConfigKey(kChipFactory_KeyBase, 0x03);
- static constexpr Key kConfigKey_ManufacturingDate = EFR32ConfigKey(kChipFactory_KeyBase, 0x04);
- static constexpr Key kConfigKey_SetupPinCode = EFR32ConfigKey(kChipFactory_KeyBase, 0x05);
- static constexpr Key kConfigKey_MfrDeviceICACerts = EFR32ConfigKey(kChipFactory_KeyBase, 0x06);
- static constexpr Key kConfigKey_SetupDiscriminator = EFR32ConfigKey(kChipFactory_KeyBase, 0x07);
- static constexpr Key kConfigKey_Spake2pIterationCount = EFR32ConfigKey(kChipFactory_KeyBase, 0x08);
- static constexpr Key kConfigKey_Spake2pSalt = EFR32ConfigKey(kChipFactory_KeyBase, 0x09);
- static constexpr Key kConfigKey_Spake2pVerifier = EFR32ConfigKey(kChipFactory_KeyBase, 0x0A);
- // CHIP Config Keys
- static constexpr Key kConfigKey_FabricId = EFR32ConfigKey(kChipConfig_KeyBase, 0x00);
- static constexpr Key kConfigKey_ServiceConfig = EFR32ConfigKey(kChipConfig_KeyBase, 0x01);
- static constexpr Key kConfigKey_PairedAccountId = EFR32ConfigKey(kChipConfig_KeyBase, 0x02);
- static constexpr Key kConfigKey_ServiceId = EFR32ConfigKey(kChipConfig_KeyBase, 0x03);
- static constexpr Key kConfigKey_FabricSecret = EFR32ConfigKey(kChipConfig_KeyBase, 0x04);
- static constexpr Key kConfigKey_LastUsedEpochKeyId = EFR32ConfigKey(kChipConfig_KeyBase, 0x05);
- static constexpr Key kConfigKey_FailSafeArmed = EFR32ConfigKey(kChipConfig_KeyBase, 0x06);
- static constexpr Key kConfigKey_GroupKey = EFR32ConfigKey(kChipConfig_KeyBase, 0x07);
- static constexpr Key kConfigKey_HardwareVersion = EFR32ConfigKey(kChipConfig_KeyBase, 0x08);
- static constexpr Key kConfigKey_RegulatoryLocation = EFR32ConfigKey(kChipConfig_KeyBase, 0x09);
- static constexpr Key kConfigKey_CountryCode = EFR32ConfigKey(kChipConfig_KeyBase, 0x0A);
- static constexpr Key kConfigKey_Breadcrumb = EFR32ConfigKey(kChipConfig_KeyBase, 0x0B);
- static constexpr Key kConfigKey_WiFiSSID = EFR32ConfigKey(kChipConfig_KeyBase, 0x0C);
- static constexpr Key kConfigKey_WiFiPSK = EFR32ConfigKey(kChipConfig_KeyBase, 0x0D);
- static constexpr Key kConfigKey_WiFiSEC = EFR32ConfigKey(kChipConfig_KeyBase, 0x0E);
- static constexpr Key kConfigKey_GroupKeyBase = EFR32ConfigKey(kChipConfig_KeyBase, 0x0F);
- static constexpr Key kConfigKey_GroupKeyMax = EFR32ConfigKey(kChipConfig_KeyBase, 0x1E); // Allows 16 Group Keys to be created.
- static constexpr Key kConfigKey_UniqueId = EFR32ConfigKey(kChipFactory_KeyBase, 0x1F);
-
- // CHIP Counter Keys
- static constexpr Key kConfigKey_BootCount = EFR32ConfigKey(kChipCounter_KeyBase, 0x00);
- static constexpr Key kConfigKey_TotalOperationalHours = EFR32ConfigKey(kChipCounter_KeyBase, 0x01);
+ static constexpr Key kConfigKey_SerialNum = EFR32ConfigKey(kMatterFactory_KeyBase, 0x00);
+ static constexpr Key kConfigKey_MfrDeviceId = EFR32ConfigKey(kMatterFactory_KeyBase, 0x01);
+ static constexpr Key kConfigKey_MfrDeviceCert = EFR32ConfigKey(kMatterFactory_KeyBase, 0x02);
+ static constexpr Key kConfigKey_MfrDevicePrivateKey = EFR32ConfigKey(kMatterFactory_KeyBase, 0x03);
+ static constexpr Key kConfigKey_ManufacturingDate = EFR32ConfigKey(kMatterFactory_KeyBase, 0x04);
+ static constexpr Key kConfigKey_SetupPinCode = EFR32ConfigKey(kMatterFactory_KeyBase, 0x05);
+ static constexpr Key kConfigKey_MfrDeviceICACerts = EFR32ConfigKey(kMatterFactory_KeyBase, 0x06);
+ static constexpr Key kConfigKey_SetupDiscriminator = EFR32ConfigKey(kMatterFactory_KeyBase, 0x07);
+ static constexpr Key kConfigKey_Spake2pIterationCount = EFR32ConfigKey(kMatterFactory_KeyBase, 0x08);
+ static constexpr Key kConfigKey_Spake2pSalt = EFR32ConfigKey(kMatterFactory_KeyBase, 0x09);
+ static constexpr Key kConfigKey_Spake2pVerifier = EFR32ConfigKey(kMatterFactory_KeyBase, 0x0A);
+ // Matter Config Keys
+ static constexpr Key kConfigKey_FabricId = EFR32ConfigKey(kMatterConfig_KeyBase, 0x00);
+ static constexpr Key kConfigKey_ServiceConfig = EFR32ConfigKey(kMatterConfig_KeyBase, 0x01);
+ static constexpr Key kConfigKey_PairedAccountId = EFR32ConfigKey(kMatterConfig_KeyBase, 0x02);
+ static constexpr Key kConfigKey_ServiceId = EFR32ConfigKey(kMatterConfig_KeyBase, 0x03);
+ static constexpr Key kConfigKey_FabricSecret = EFR32ConfigKey(kMatterConfig_KeyBase, 0x04);
+ static constexpr Key kConfigKey_LastUsedEpochKeyId = EFR32ConfigKey(kMatterConfig_KeyBase, 0x05);
+ static constexpr Key kConfigKey_FailSafeArmed = EFR32ConfigKey(kMatterConfig_KeyBase, 0x06);
+ static constexpr Key kConfigKey_GroupKey = EFR32ConfigKey(kMatterConfig_KeyBase, 0x07);
+ static constexpr Key kConfigKey_HardwareVersion = EFR32ConfigKey(kMatterConfig_KeyBase, 0x08);
+ static constexpr Key kConfigKey_RegulatoryLocation = EFR32ConfigKey(kMatterConfig_KeyBase, 0x09);
+ static constexpr Key kConfigKey_CountryCode = EFR32ConfigKey(kMatterConfig_KeyBase, 0x0A);
+ static constexpr Key kConfigKey_Breadcrumb = EFR32ConfigKey(kMatterConfig_KeyBase, 0x0B);
+ static constexpr Key kConfigKey_WiFiSSID = EFR32ConfigKey(kMatterConfig_KeyBase, 0x0C);
+ static constexpr Key kConfigKey_WiFiPSK = EFR32ConfigKey(kMatterConfig_KeyBase, 0x0D);
+ static constexpr Key kConfigKey_WiFiSEC = EFR32ConfigKey(kMatterConfig_KeyBase, 0x0E);
+ static constexpr Key kConfigKey_GroupKeyBase = EFR32ConfigKey(kMatterConfig_KeyBase, 0x0F);
+ static constexpr Key kConfigKey_GroupKeyMax =
+ EFR32ConfigKey(kMatterConfig_KeyBase, 0x1E); // Allows 16 Group Keys to be created.
+ static constexpr Key kConfigKey_UniqueId = EFR32ConfigKey(kMatterFactory_KeyBase, 0x1F);
+
+ // Matter Counter Keys
+ static constexpr Key kConfigKey_BootCount = EFR32ConfigKey(kMatterCounter_KeyBase, 0x00);
+ static constexpr Key kConfigKey_TotalOperationalHours = EFR32ConfigKey(kMatterCounter_KeyBase, 0x01);
+
+ // Matter KVS storage Keys
+ static constexpr Key kConfigKey_KvsStringKeyMap = EFR32ConfigKey(kMatterKvs_KeyBase, 0x00);
+ static constexpr Key kConfigKey_KvsFirstKeySlot = EFR32ConfigKey(kMatterKvs_KeyBase, 0x01);
+ static constexpr Key kConfigKey_KvsLastKeySlot = EFR32ConfigKey(kMatterKvs_KeyBase, KVS_MAX_ENTRIES);
// Set key id limits for each group.
- static constexpr Key kMinConfigKey_ChipFactory = EFR32ConfigKey(kChipFactory_KeyBase, 0x00);
- static constexpr Key kMaxConfigKey_ChipFactory = EFR32ConfigKey(kChipFactory_KeyBase, 0x0A);
- static constexpr Key kMinConfigKey_ChipConfig = EFR32ConfigKey(kChipConfig_KeyBase, 0x00);
- static constexpr Key kMaxConfigKey_ChipConfig = EFR32ConfigKey(kChipConfig_KeyBase, 0x1B);
- static constexpr Key kMinConfigKey_ChipCounter = EFR32ConfigKey(kChipCounter_KeyBase, 0x00);
- static constexpr Key kMaxConfigKey_ChipCounter =
- EFR32ConfigKey(kChipCounter_KeyBase, 0x1F); // Allows 32 Counters to be created.
+ static constexpr Key kMinConfigKey_MatterFactory = EFR32ConfigKey(kMatterFactory_KeyBase, 0x00);
+ static constexpr Key kMaxConfigKey_MatterFactory = EFR32ConfigKey(kMatterFactory_KeyBase, 0x0A);
+ static constexpr Key kMinConfigKey_MatterConfig = EFR32ConfigKey(kMatterConfig_KeyBase, 0x00);
+ static constexpr Key kMaxConfigKey_MatterConfig = EFR32ConfigKey(kMatterConfig_KeyBase, 0x1B);
+
+ // Allows 32 Counters to be created.
+ static constexpr Key kMinConfigKey_MatterCounter = EFR32ConfigKey(kMatterCounter_KeyBase, 0x00);
+ static constexpr Key kMaxConfigKey_MatterCounter = EFR32ConfigKey(kMatterCounter_KeyBase, 0x1F);
+
+ static constexpr Key kMinConfigKey_MatterKvs = EFR32ConfigKey(kMatterKvs_KeyBase, 0x00);
+ static constexpr Key kMaxConfigKey_MatterKvs = EFR32ConfigKey(kMatterKvs_KeyBase, 0xFF);
static CHIP_ERROR Init(void);
+ static void DeInit(void);
// Configuration methods used by the GenericConfigurationManagerImpl<> template.
static CHIP_ERROR ReadConfigValue(Key key, bool & val);
@@ -125,6 +148,7 @@ class EFR32Config
static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val);
static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen);
static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen);
+ static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset);
static CHIP_ERROR ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val);
static CHIP_ERROR WriteConfigValue(Key key, bool val);
static CHIP_ERROR WriteConfigValue(Key key, uint32_t val);
@@ -147,7 +171,6 @@ class EFR32Config
private:
static CHIP_ERROR MapNvm3Error(Ecode_t nvm3Res);
- static void OnExit(void);
};
} // namespace Internal
diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp
index 28f6ea44d72430..d46079fcc78163 100644
--- a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp
+++ b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp
@@ -21,122 +21,183 @@
* Platform-specific key value storage implementation for EFR32
*/
+#include
+#include
+#include
#include
+#include
+#include
-/* ignore GCC Wconversion warnings for pigweed */
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-#endif
+using namespace ::chip;
+using namespace ::chip::DeviceLayer::Internal;
-#include
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
+#define CONVERT_KEYMAP_INDEX_TO_NVM3KEY(index) (EFR32Config::kConfigKey_KvsFirstKeySlot + index)
+#define CONVERT_NVM3KEY_TO_KEYMAP_INDEX(nvm3Key) (nvm3Key - EFR32Config::kConfigKey_KvsFirstKeySlot)
namespace chip {
namespace DeviceLayer {
namespace PersistedStorage {
KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance;
+char mKvsStoredKeyString[KeyValueStoreManagerImpl::kMaxEntries][PersistentStorageDelegate::kKeyLengthMax + 1];
+
+CHIP_ERROR KeyValueStoreManagerImpl::Init(void)
+{
+ CHIP_ERROR err;
+ err = EFR32Config::Init();
+ SuccessOrExit(err);
-#if defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE
+ memset(mKvsStoredKeyString, 0, sizeof(mKvsStoredKeyString));
+ size_t outLen;
+ err = EFR32Config::ReadConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsStoredKeyString),
+ sizeof(mKvsStoredKeyString), outLen);
+
+ if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) // Initial boot
+ {
+ err = CHIP_NO_ERROR;
+ }
+
+exit:
+ return err;
+}
+
+bool KeyValueStoreManagerImpl::IsValidKvsNvm3Key(uint32_t nvm3Key) const
+{
+ return ((EFR32Config::kConfigKey_KvsFirstKeySlot <= nvm3Key) && (nvm3Key <= EFR32Config::kConfigKey_KvsLastKeySlot));
+}
+
+CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t & nvm3Key, bool isSlotNeeded) const
+{
+ CHIP_ERROR err;
+ uint8_t firstEmptyKeySlot = kMaxEntries;
+ for (uint8_t keyIndex = 0; keyIndex < kMaxEntries; keyIndex++)
+ {
+ if (strcmp(key, mKvsStoredKeyString[keyIndex]) == 0)
+ {
+ nvm3Key = CONVERT_KEYMAP_INDEX_TO_NVM3KEY(keyIndex);
+ VerifyOrDie(IsValidKvsNvm3Key(nvm3Key) == true);
+ return CHIP_NO_ERROR;
+ }
+
+ if (isSlotNeeded && (firstEmptyKeySlot == kMaxEntries) && (mKvsStoredKeyString[keyIndex][0] == 0))
+ {
+ firstEmptyKeySlot = keyIndex;
+ }
+ }
+
+ if (isSlotNeeded)
+ {
+ if (firstEmptyKeySlot != kMaxEntries)
+ {
+ nvm3Key = CONVERT_KEYMAP_INDEX_TO_NVM3KEY(firstEmptyKeySlot);
+ VerifyOrDie(IsValidKvsNvm3Key(nvm3Key) == true);
+ err = CHIP_NO_ERROR;
+ }
+ else
+ {
+ err = CHIP_ERROR_PERSISTED_STORAGE_FAILED;
+ }
+ }
+ else
+ {
+ err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
+ }
+ return err;
+}
+
+void KeyValueStoreManagerImpl::OnScheduledKeyMapSave(System::Layer * systemLayer, void * appState)
+{
+ EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap,
+ reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString));
+}
+
+void KeyValueStoreManagerImpl::ScheduleKeyMapSave(void)
+{
+ /*
+ During commissioning, the key map will be modified multiples times subsequently.
+ Commit the key map in nvm once it as stabilized.
+ */
+ SystemLayer().StartTimer(std::chrono::duration_cast(System::Clock::Seconds32(5)),
+ KeyValueStoreManagerImpl::OnScheduledKeyMapSave, NULL);
+}
CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size,
size_t offset_bytes) const
{
- assert(CHIP_KVS_AVAILABLE);
- auto status_and_size = mKvs.Get(key, std::span(reinterpret_cast(value), value_size), offset_bytes);
+ VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(value != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(value != 0, CHIP_ERROR_INVALID_ARGUMENT);
+
+ uint32_t nvm3Key;
+ CHIP_ERROR err = MapKvsKeyToNvm3(key, nvm3Key);
+ VerifyOrReturnError(err == CHIP_NO_ERROR, err);
+
+ size_t outLen;
+ err = EFR32Config::ReadConfigValueBin(nvm3Key, reinterpret_cast(value), value_size, outLen, offset_bytes);
if (read_bytes_size)
{
- *read_bytes_size = status_and_size.size();
- }
- switch (status_and_size.status().code())
- {
- case pw::OkStatus().code():
- return CHIP_NO_ERROR;
- case pw::Status::NotFound().code():
- return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
- case pw::Status::DataLoss().code():
- return CHIP_ERROR_INTEGRITY_CHECK_FAILED;
- case pw::Status::ResourceExhausted().code():
- return CHIP_ERROR_BUFFER_TOO_SMALL;
- case pw::Status::FailedPrecondition().code():
- return CHIP_ERROR_WELL_UNINITIALIZED;
- case pw::Status::InvalidArgument().code():
- return CHIP_ERROR_INVALID_ARGUMENT;
- default:
- break;
+ *read_bytes_size = outLen;
}
- return CHIP_ERROR_INTERNAL; // Unexpected KVS status.
+
+ return err;
}
CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size)
{
- assert(CHIP_KVS_AVAILABLE);
- auto status = mKvs.Put(key, std::span(reinterpret_cast(value), value_size));
- switch (status.code())
+ VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+ VerifyOrReturnError(value != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+ uint32_t nvm3Key;
+ CHIP_ERROR err = MapKvsKeyToNvm3(key, nvm3Key, /* isSlotNeeded */ true);
+ VerifyOrReturnError(err == CHIP_NO_ERROR, err);
+
+ err = EFR32Config::WriteConfigValueBin(nvm3Key, reinterpret_cast(value), value_size);
+ if (err == CHIP_NO_ERROR)
{
- case pw::OkStatus().code():
- return CHIP_NO_ERROR;
- case pw::Status::DataLoss().code():
- return CHIP_ERROR_INTEGRITY_CHECK_FAILED;
- case pw::Status::ResourceExhausted().code():
- case pw::Status::AlreadyExists().code():
- return CHIP_ERROR_PERSISTED_STORAGE_FAILED;
- case pw::Status::FailedPrecondition().code():
- return CHIP_ERROR_WELL_UNINITIALIZED;
- case pw::Status::InvalidArgument().code():
- return CHIP_ERROR_INVALID_ARGUMENT;
- default:
- break;
+ uint32_t keyIndex = nvm3Key - EFR32Config::kConfigKey_KvsFirstKeySlot;
+ strncpy(mKvsStoredKeyString[keyIndex], key, sizeof(mKvsStoredKeyString[keyIndex]) - 1);
+ ScheduleKeyMapSave();
}
- return CHIP_ERROR_INTERNAL; // Unexpected KVS status.
+
+ return err;
}
CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key)
{
- assert(CHIP_KVS_AVAILABLE);
- auto status = mKvs.Delete(key);
- switch (status.code())
+ VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
+
+ uint32_t nvm3Key;
+ CHIP_ERROR err = MapKvsKeyToNvm3(key, nvm3Key);
+ VerifyOrReturnError(err == CHIP_NO_ERROR, err);
+
+ err = EFR32Config::ClearConfigValue(nvm3Key);
+ if (err == CHIP_NO_ERROR)
{
- case pw::OkStatus().code():
- return CHIP_NO_ERROR;
- case pw::Status::NotFound().code():
- return CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
- case pw::Status::DataLoss().code():
- return CHIP_ERROR_INTEGRITY_CHECK_FAILED;
- case pw::Status::ResourceExhausted().code():
- return CHIP_ERROR_PERSISTED_STORAGE_FAILED;
- case pw::Status::FailedPrecondition().code():
- return CHIP_ERROR_WELL_UNINITIALIZED;
- case pw::Status::InvalidArgument().code():
- return CHIP_ERROR_INVALID_ARGUMENT;
- default:
- break;
+ uint32_t keyIndex = CONVERT_NVM3KEY_TO_KEYMAP_INDEX(nvm3Key);
+ memset(mKvsStoredKeyString[keyIndex], 0, sizeof(mKvsStoredKeyString[keyIndex]));
+ ScheduleKeyMapSave();
}
- return CHIP_ERROR_INTERNAL; // Unexpected KVS status.
+
+ return err;
}
-CHIP_ERROR KeyValueStoreManagerImpl::ErasePartition()
+CHIP_ERROR KeyValueStoreManagerImpl::ErasePartition(void)
{
- assert(CHIP_KVS_AVAILABLE);
- auto status = mKvsPartition.Erase();
- switch (status.code())
+ // Iterate over all the Matter Kvs nvm3 records and delete each one...
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ for (uint32_t nvm3Key = EFR32Config::kMinConfigKey_MatterKvs; nvm3Key < EFR32Config::kMaxConfigKey_MatterKvs; nvm3Key++)
{
- case pw::OkStatus().code():
- return CHIP_NO_ERROR;
- case pw::Status::DeadlineExceeded().code():
- return CHIP_ERROR_TIMEOUT;
- case pw::Status::PermissionDenied().code():
- return CHIP_ERROR_ACCESS_DENIED;
- default:
- break;
+ err = EFR32Config::ClearConfigValue(nvm3Key);
+
+ if (err != CHIP_NO_ERROR)
+ {
+ break;
+ }
}
- return CHIP_ERROR_INTERNAL; // Unexpected KVS status.
+
+ memset(mKvsStoredKeyString, 0, sizeof(mKvsStoredKeyString));
+ return err;
}
-#endif // defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE
} // namespace PersistedStorage
} // namespace DeviceLayer
diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.h b/src/platform/EFR32/KeyValueStoreManagerImpl.h
index 32650db28215b7..daf5ff8ce32c42 100644
--- a/src/platform/EFR32/KeyValueStoreManagerImpl.h
+++ b/src/platform/EFR32/KeyValueStoreManagerImpl.h
@@ -23,35 +23,14 @@
*/
#pragma once
-
-#include "em_msc.h"
-
-/* ignore GCC Wconversion warnings for pigweed */
-#if defined(__GNUC__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-#endif
-
-#include
-#include
-#include
-
-#if defined(__GNUC__)
-#pragma GCC diagnostic pop
-#endif
-
-// KVS is only available for EFR32 when these macros are defined.
-#if defined(CHIP_KVS_SECTOR_COUNT) && defined(CHIP_KVS_BASE_SECTOR_INDEX)
-#define CHIP_KVS_AVAILABLE 1
-#else // defined(CHIP_KVS_SECTOR_COUNT) && defined(CHIP_KVS_BASE_ADDRESS)
-#define CHIP_KVS_AVAILABLE 0
-#endif // defined(CHIP_KVS_SECTOR_COUNT) && defined(CHIP_KVS_BASE_ADDRESS)
+#include
+#include
+#include
namespace chip {
namespace DeviceLayer {
namespace PersistedStorage {
-#if defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE
class KeyValueStoreManagerImpl final : public KeyValueStoreManager
{
// Allow the KeyValueStoreManager interface class to delegate method calls to
@@ -59,136 +38,27 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager
friend class KeyValueStoreManager;
public:
- void Init() { mKvs.Init(); }
-
+ CHIP_ERROR Init(void);
+ CHIP_ERROR _Put(const char * key, const void * value, size_t value_size);
CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0) const;
-
CHIP_ERROR _Delete(const char * key);
+ CHIP_ERROR ErasePartition(void);
- /**
- * @brief
- * Erases all data in the KVS partition, KVS needs to be initialized after
- * this operation.
- *
- * @return CHIP_NO_ERROR the partiton was erased.
- * CHIP_ERROR_TIMEOUT timed out while doing erase.
- * CHIP_ERROR_ACCESS_DENIED flash locked, erase failed.
- */
- CHIP_ERROR ErasePartition();
-
- CHIP_ERROR _Put(const char * key, const void * value, size_t value_size);
-
-private:
- // KVS flash interface
- class Efr32FlashMemory : public pw::kvs::FlashMemory
- {
- public:
- Efr32FlashMemory() : pw::kvs::FlashMemory(FLASH_PAGE_SIZE, FLASH_SIZE / FLASH_PAGE_SIZE, sizeof(uint32_t), FLASH_BASE) {}
-
- // Enabling flash handled by platform
- pw::Status Enable() override { return pw::OkStatus(); }
- pw::Status Disable() override { return pw::OkStatus(); }
- bool IsEnabled() const override { return true; }
-
- pw::Status Erase(Address flash_address, size_t num_sectors) override
- {
- assert((flash_address % sizeof(uint32_t)) == 0);
- for (size_t i = 0; i < num_sectors; i++)
- {
- auto status =
- MscStatusToPwStatus(MSC_ErasePage(reinterpret_cast(flash_address + i * sector_size_bytes())));
- if (!status.ok())
- {
- return status;
- }
- }
- return pw::OkStatus();
- }
-
- pw::StatusWithSize Read(Address address, std::span output) override
- {
- memcpy(output.data(), reinterpret_cast(address), output.size());
- return pw::StatusWithSize(output.size());
- }
-
- pw::StatusWithSize Write(Address destination_flash_address, std::span data) override
- {
- assert((destination_flash_address % sizeof(uint32_t)) == 0);
- return pw::StatusWithSize(MscStatusToPwStatus(MSC_WriteWord(reinterpret_cast(destination_flash_address),
- data.data(), data.size())),
- data.size());
- }
-
- private:
- static pw::Status MscStatusToPwStatus(MSC_Status_TypeDef msc_status)
- {
- switch (msc_status)
- {
- case mscReturnOk:
- return pw::OkStatus();
- case mscReturnUnaligned:
- case mscReturnInvalidAddr:
- return pw::Status::InvalidArgument();
- case mscReturnLocked:
- return pw::Status::PermissionDenied();
- case mscReturnTimeOut:
- return pw::Status::DeadlineExceeded();
- default:
- break;
- }
- return pw::Status::Internal();
- }
- };
-
- static constexpr size_t kMaxEntries = 50;
- pw::kvs::ChecksumCrc16 mKvsChecksum;
- const pw::kvs::EntryFormat kEntryFormat{ .magic = 0x64d51134, .checksum = &mKvsChecksum };
-
- Efr32FlashMemory mFlash;
- pw::kvs::FlashPartition mKvsPartition{ &mFlash, CHIP_KVS_BASE_SECTOR_INDEX, CHIP_KVS_SECTOR_COUNT };
- pw::kvs::KeyValueStoreBuffer mKvs{ &mKvsPartition, kEntryFormat };
-
- // ===== Members for internal use by the following friends.
-
- friend KeyValueStoreManager & KeyValueStoreMgr();
- friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl();
-
- static KeyValueStoreManagerImpl sInstance;
-};
-
-#else // defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE
-
-// Empty implementation which just asserts if used
-class KeyValueStoreManagerImpl final : public KeyValueStoreManager
-{
-public:
- CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0) const
- {
- assert(CHIP_KVS_AVAILABLE);
- return CHIP_ERROR_NOT_IMPLEMENTED;
- }
- CHIP_ERROR _Delete(const char * key)
- {
- assert(CHIP_KVS_AVAILABLE);
- return CHIP_ERROR_NOT_IMPLEMENTED;
- }
- CHIP_ERROR _Put(const char * key, const void * value, size_t value_size)
- {
- assert(CHIP_KVS_AVAILABLE);
- return CHIP_ERROR_NOT_IMPLEMENTED;
- }
+ static constexpr size_t kMaxEntries = KVS_MAX_ENTRIES;
private:
- // ===== Members for internal use by the following friends.
+ static void OnScheduledKeyMapSave(System::Layer * systemLayer, void * appState);
+ void ScheduleKeyMapSave(void);
+ bool IsValidKvsNvm3Key(const uint32_t nvm3Key) const;
+ CHIP_ERROR MapKvsKeyToNvm3(const char * key, uint32_t & nvm3Key, bool isSlotNeeded = false) const;
+ // ===== Members for internal use by the following friends.
friend KeyValueStoreManager & KeyValueStoreMgr();
friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl();
static KeyValueStoreManagerImpl sInstance;
};
-#endif // defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE
-
/**
* Returns the public interface of the KeyValueStoreManager singleton object.
*
diff --git a/src/platform/EFR32/PlatformManagerImpl.cpp b/src/platform/EFR32/PlatformManagerImpl.cpp
index 5acf098528605b..391e2becf4e48f 100644
--- a/src/platform/EFR32/PlatformManagerImpl.cpp
+++ b/src/platform/EFR32/PlatformManagerImpl.cpp
@@ -26,6 +26,7 @@
#include
#include
+#include
#include
#include
@@ -44,8 +45,9 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
CHIP_ERROR err;
// Initialize the configuration system.
- err = Internal::EFR32Config::Init();
+ err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
SuccessOrExit(err);
+
SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance());
SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance());
diff --git a/src/test_driver/efr32/src/main.cpp b/src/test_driver/efr32/src/main.cpp
index a99e39e10879fa..c3d6028ab136b5 100644
--- a/src/test_driver/efr32/src/main.cpp
+++ b/src/test_driver/efr32/src/main.cpp
@@ -186,7 +186,6 @@ int main(void)
mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree);
chip::Platform::MemoryInit();
- chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
chip::DeviceLayer::PlatformMgr().InitChipStack();
diff --git a/third_party/efr32_sdk/efr32_sdk.gni b/third_party/efr32_sdk/efr32_sdk.gni
index 5af0f01991c1da..846733d07e4e7a 100644
--- a/third_party/efr32_sdk/efr32_sdk.gni
+++ b/third_party/efr32_sdk/efr32_sdk.gni
@@ -24,6 +24,7 @@ declare_args() {
# Location of the efr32 SDK.
efr32_sdk_root = "${chip_root}/third_party/efr32_sdk/repo"
enable_openthread_cli = true
+ kvs_max_entries = 75
}
assert(efr32_sdk_root != "", "efr32_sdk_root must be specified")
@@ -130,6 +131,8 @@ template("efr32_sdk") {
"CORTEXM3_EFM32_MICRO",
"EFR32_LOG_ENABLED=1",
"NVM3_DEFAULT_NVM_SIZE=40960",
+ "NVM3_DEFAULT_MAX_OBJECT_SIZE=4092",
+ "KVS_MAX_ENTRIES=${kvs_max_entries}",
"EFR32_OPENTHREAD_API",
"PHY=EMBER_PHY_RAIL",
"CORTEXM3",
@@ -138,7 +141,6 @@ template("efr32_sdk") {
"${efr32_mcu}=1",
"${efr32_board}=1",
"SL_SUPRESS_DEPRECATION_WARNINGS_SDK_3_1",
- "CHIP_KVS_BASE_SECTOR_INDEX=((FLASH_SIZE/FLASH_PAGE_SIZE)-(CHIP_KVS_SECTOR_COUNT))",
"__HEAP_SIZE=0",
"SL_CATALOG_FREERTOS_KERNEL_PRESENT=1",
"MBEDTLS_THREADING_C=1",
@@ -218,10 +220,7 @@ template("efr32_sdk") {
"${efr32_sdk_root}/platform/emdrv/nvm3/lib/libnvm3_CM4_gcc.a",
]
- defines += [
- "EFR32MG12",
- "CHIP_KVS_SECTOR_COUNT=6",
- ]
+ defines += [ "EFR32MG12" ]
} else if (efr32_family == "efr32mg21") {
_include_dirs += [
"${efr32_sdk_root}/hardware/kit/EFR32MG21_${efr32_board}/config",
@@ -242,7 +241,6 @@ template("efr32_sdk") {
defines += [
"EFR32MG21",
"EFR32_SERIES2_CONFIG1_MICRO",
- "CHIP_KVS_SECTOR_COUNT=4",
]
} else if (efr32_family == "efr32mg24") {
_include_dirs += [
@@ -264,7 +262,6 @@ template("efr32_sdk") {
defines += [
"EFR32MG24",
"EFR32_SERIES2_CONFIG4_MICRO",
- "CHIP_KVS_SECTOR_COUNT=4",
]
}
if (use_wf200) {