From 30739fb8c8956cb0d5d4bfac41fa2e9f11de75a5 Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Mon, 21 Mar 2022 09:38:18 -0400 Subject: [PATCH 01/10] Merge chip_nvm3 section into silabs default nvm3 section. Rework the efr32Config nvm3 driver, tweaks to linkerfile for the nvm3 section --- .../platform/efr32/ldscripts/efr32mg12.ld | 51 ++-- src/platform/EFR32/CHIPDevicePlatformConfig.h | 45 --- src/platform/EFR32/EFR32Config.cpp | 288 +++++------------- src/platform/EFR32/EFR32Config.h | 12 +- third_party/efr32_sdk/efr32_sdk.gni | 2 +- third_party/pigweed/repo | 2 +- third_party/zap/repo | 2 +- 7 files changed, 110 insertions(+), 292 deletions(-) diff --git a/examples/platform/efr32/ldscripts/efr32mg12.ld b/examples/platform/efr32/ldscripts/efr32mg12.ld index f55f03521bc1e4..f741d3d76e3c20 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) { @@ -255,6 +225,7 @@ SECTIONS __bss_end__ = .; } > RAM + /* .heap (COPY): { __HeapBase = .; @@ -264,6 +235,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 +252,23 @@ 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); + /* + linker_storage_end = linker_nvm_begin; + linker_storage_begin = linker_storage_end - SIZEOF(.internal_storage); + linker_storage_size = SIZEOF(.internal_storage); + */ + __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/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/EFR32Config.cpp b/src/platform/EFR32/EFR32Config.cpp index da1734e34d898f..134aea65d6845c 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. +// 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 #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. - -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); +// Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd +// for an application controlled re-entrance protection +void nvm3_lockBegin(void) +{ + VerifyOrDie(nvm3_Sem != NULL); + xSemaphoreTake(nvm3_Sem, portMAX_DELAY); +} -CHIP_NVM3_DEFINE_SECTION_INIT_DATA(chipNvm3, CHIP_DEVICE_CONFIG_NVM3_MAX_OBJECT_SIZE, CHIP_NVM3_REPACK_HEADROOM); +void nvm3_lockEnd(void) +{ + VerifyOrDie(nvm3_Sem != NULL); + xSemaphoreGive(nvm3_Sem); +} 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,21 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +111,21 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +136,21 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +162,13 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +179,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 +195,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 +203,6 @@ CHIP_ERROR EFR32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, } exit: - OnExit(); return err; } @@ -256,19 +213,14 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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,14 +230,13 @@ 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; exit: - OnExit(); return err; } @@ -295,24 +246,17 @@ CHIP_ERROR EFR32Config::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & va uint32_t tmpVal; Key key = kMinConfigKey_ChipCounter + counterIdx; - 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_open(nvm3_defaultHandle, nvm3_defaultInit)); + // SuccessOrExit(err); // 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 +264,15 @@ 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_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +280,15 @@ 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_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +296,15 @@ 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_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +317,24 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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,33 +342,26 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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; } @@ -461,22 +370,15 @@ 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); - } - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - err = MapNvm3Error(nvm3_open(&handle, &chipNvm3)); - SuccessOrExit(err); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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 +386,27 @@ 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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); + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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); } @@ -537,11 +422,10 @@ CHIP_ERROR EFR32Config::FactoryResetConfig(void) [](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 = MapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, nvm3Key)); SuccessOrExit(err2); exit: - nvm3_close(&handle); return err2; }); @@ -580,11 +464,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 +471,12 @@ 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); + // // Open nvm3 handle for reading on each iteration. + // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); + // 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,8 +503,7 @@ CHIP_ERROR EFR32Config::ForEachRecord(Key firstNvm3Key, Key lastNvm3Key, bool ad SuccessOrExit(err); } -exit: - OnExit(); +exit:; return err; } @@ -652,13 +530,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..d9ace9f4a39630 100644 --- a/src/platform/EFR32/EFR32Config.h +++ b/src/platform/EFR32/EFR32Config.h @@ -46,14 +46,17 @@ 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 @@ -118,6 +121,7 @@ class EFR32Config EFR32ConfigKey(kChipCounter_KeyBase, 0x1F); // Allows 32 Counters to be created. static CHIP_ERROR Init(void); + static void DeInit(void); // Configuration methods used by the GenericConfigurationManagerImpl<> template. static CHIP_ERROR ReadConfigValue(Key key, bool & val); diff --git a/third_party/efr32_sdk/efr32_sdk.gni b/third_party/efr32_sdk/efr32_sdk.gni index 5af0f01991c1da..e1127f3bcab578 100644 --- a/third_party/efr32_sdk/efr32_sdk.gni +++ b/third_party/efr32_sdk/efr32_sdk.gni @@ -138,7 +138,7 @@ 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))", + "CHIP_KVS_BASE_SECTOR_INDEX=((FLASH_SIZE/FLASH_PAGE_SIZE)-(CHIP_KVS_SECTOR_COUNT)-21)", "__HEAP_SIZE=0", "SL_CATALOG_FREERTOS_KERNEL_PRESENT=1", "MBEDTLS_THREADING_C=1", diff --git a/third_party/pigweed/repo b/third_party/pigweed/repo index 67506a1a4487c7..86698c0b9620fe 160000 --- a/third_party/pigweed/repo +++ b/third_party/pigweed/repo @@ -1 +1 @@ -Subproject commit 67506a1a4487c7fb1306bedc391883ec58841522 +Subproject commit 86698c0b9620febe11cc274a44c9457e6127dd62 diff --git a/third_party/zap/repo b/third_party/zap/repo index 9c885cf9391fc0..a1ddd5d56c4bd9 160000 --- a/third_party/zap/repo +++ b/third_party/zap/repo @@ -1 +1 @@ -Subproject commit 9c885cf9391fc09b450e5e8a8e40e381c4bee27d +Subproject commit a1ddd5d56c4bd9b7ba52c63f13665d96a11134ce From 2440e5be048d3192d79102579065bc7ca238a5cd Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Fri, 25 Mar 2022 15:33:35 -0400 Subject: [PATCH 02/10] Refactore efr32 kvs implementation to use silabs nvm3 driver --- examples/persistent-storage/efr32/BUILD.gn | 9 +- examples/persistent-storage/efr32/README.md | 10 +- examples/persistent-storage/efr32/main.cpp | 3 + .../platform/efr32/ldscripts/efr32mg12.ld | 3 +- scripts/examples/gn_efr32_example.sh | 9 +- .../EFR32/ConfigurationManagerImpl.cpp | 2 - src/platform/EFR32/ConfigurationManagerImpl.h | 2 +- src/platform/EFR32/EFR32Config.cpp | 121 ++++++------ src/platform/EFR32/EFR32Config.h | 107 ++++++----- .../EFR32/KeyValueStoreManagerImpl.cpp | 181 ++++++++++-------- src/platform/EFR32/KeyValueStoreManagerImpl.h | 150 +-------------- third_party/efr32_sdk/efr32_sdk.gni | 8 +- 12 files changed, 238 insertions(+), 367 deletions(-) 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..2a86c9d7306950 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; @@ -49,6 +51,7 @@ int main(void) init_efrPlatform(); chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(); + chip::DeviceLayer::Internal::EFR32Config::Init(); EFR32_LOG("=================================================="); EFR32_LOG("chip-efr32-persitent-storage-example starting"); EFR32_LOG("=================================================="); diff --git a/examples/platform/efr32/ldscripts/efr32mg12.ld b/examples/platform/efr32/ldscripts/efr32mg12.ld index f741d3d76e3c20..5f24d3227637d7 100644 --- a/examples/platform/efr32/ldscripts/efr32mg12.ld +++ b/examples/platform/efr32/ldscripts/efr32mg12.ld @@ -225,7 +225,6 @@ SECTIONS __bss_end__ = .; } > RAM - /* .heap (COPY): { __HeapBase = .; @@ -235,7 +234,7 @@ SECTIONS KEEP(*(.heap*)) __HeapLimit = .; } > RAM - */ + __main_flash_end__ = ORIGIN(FLASH) + LENGTH(FLASH); /* .stack_dummy section doesn't contains any symbols. It is only diff --git a/scripts/examples/gn_efr32_example.sh b/scripts/examples/gn_efr32_example.sh index 0ce40ef66d7287..717958c530f255 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 @@ -144,17 +144,18 @@ 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"/ + mv """$BUILD_DIR/compile_commands.json" "$CHIP_ROOT/out/debug/compile_commands.efr32.json" #print stats arm-none-eabi-size -A "$BUILD_DIR"/*.out 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 134aea65d6845c..0499248d8581f6 100644 --- a/src/platform/EFR32/EFR32Config.cpp +++ b/src/platform/EFR32/EFR32Config.cpp @@ -34,21 +34,12 @@ #include "nvm3_default.h" #include "nvm3_hal_flash.h" -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 - +// Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd +// for an application controlled re-entrance protection #define EFR32_SEM_TIMEOUT_ms 5 static SemaphoreHandle_t nvm3_Sem; static StaticSemaphore_t nvm3_SemStruct; -// Substitute the GSDK weak nvm3_lockBegin and nvm3_lockEnd -// for an application controlled re-entrance protection void nvm3_lockBegin(void) { VerifyOrDie(nvm3_Sem != NULL); @@ -60,6 +51,14 @@ void nvm3_lockEnd(void) VerifyOrDie(nvm3_Sem != NULL); xSemaphoreGive(nvm3_Sem); } +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() { @@ -88,9 +87,6 @@ CHIP_ERROR EFR32Config::ReadConfigValue(Key key, bool & val) VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Get nvm3 object info. err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen)); SuccessOrExit(err); @@ -113,9 +109,6 @@ CHIP_ERROR EFR32Config::ReadConfigValue(Key key, uint32_t & val) VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Get nvm3 object info. err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen)); SuccessOrExit(err); @@ -138,9 +131,6 @@ CHIP_ERROR EFR32Config::ReadConfigValue(Key key, uint64_t & val) VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Get nvm3 object info. err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen)); SuccessOrExit(err); @@ -164,9 +154,6 @@ CHIP_ERROR EFR32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Get nvm3 object info. err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen)); SuccessOrExit(err); @@ -213,12 +200,8 @@ CHIP_ERROR EFR32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSiz size_t dataLen; outLen = 0; - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Get nvm3 object info. err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen)); SuccessOrExit(err); @@ -232,10 +215,48 @@ CHIP_ERROR EFR32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSiz err = MapNvm3Error(nvm3_readData(nvm3_defaultHandle, key, buf, dataLen)); SuccessOrExit(err); + + outLen = dataLen; } - outLen = dataLen; +exit: + return err; +} +CHIP_ERROR EFR32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen, size_t offset) +{ + CHIP_ERROR err; + 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 (buf != NULL) + { + // 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 succesful, but we did not read all the data from the object. + err = CHIP_ERROR_BUFFER_TOO_SMALL; + outLen = bufSize; + } + } exit: return err; } @@ -244,13 +265,10 @@ CHIP_ERROR EFR32Config::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & va { CHIP_ERROR err; uint32_t tmpVal; - Key key = kMinConfigKey_ChipCounter + counterIdx; + Key key = kMinConfigKey_MatterCounter + counterIdx; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Read bytes into tmp. err = MapNvm3Error(nvm3_readCounter(nvm3_defaultHandle, key, &tmpVal)); SuccessOrExit(err); @@ -266,9 +284,6 @@ CHIP_ERROR EFR32Config::WriteConfigValue(Key key, bool val) VerifyOrExit(ValidConfigKey(key), err = CHIP_ERROR_INVALID_ARGUMENT); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val))); SuccessOrExit(err); @@ -282,9 +297,6 @@ CHIP_ERROR EFR32Config::WriteConfigValue(Key key, uint32_t val) VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val))); SuccessOrExit(err); @@ -298,9 +310,6 @@ CHIP_ERROR EFR32Config::WriteConfigValue(Key key, uint64_t val) VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - err = MapNvm3Error(nvm3_writeData(nvm3_defaultHandle, key, &val, sizeof(val))); SuccessOrExit(err); @@ -319,9 +328,6 @@ CHIP_ERROR EFR32Config::WriteConfigValueStr(Key key, const char * str, size_t st VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - if (str != NULL) { // Write the string to nvm3 without the terminator char (apart from @@ -344,9 +350,6 @@ CHIP_ERROR EFR32Config::WriteConfigValueBin(Key key, const uint8_t * data, size_ VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - if (data != NULL) { if (dataLen > 0) @@ -368,13 +371,10 @@ CHIP_ERROR EFR32Config::WriteConfigValueBin(Key key, const uint8_t * data, size_ CHIP_ERROR EFR32Config::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val) { CHIP_ERROR err; - Key key = kMinConfigKey_ChipCounter + counterIdx; + Key key = kMinConfigKey_MatterCounter + counterIdx; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - err = MapNvm3Error(nvm3_writeCounter(nvm3_defaultHandle, key, val)); SuccessOrExit(err); @@ -386,9 +386,6 @@ CHIP_ERROR EFR32Config::ClearConfigValue(Key key) { CHIP_ERROR err; - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Delete the nvm3 object with the given key id. err = MapNvm3Error(nvm3_deleteObject(nvm3_defaultHandle, key)); SuccessOrExit(err); @@ -402,9 +399,6 @@ bool EFR32Config::ConfigValueExists(Key key) uint32_t objectType; size_t dataLen; - // err = MapNvm3Error(nvm3_open(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Find object with key id. CHIP_ERROR err = MapNvm3Error(nvm3_getObjectInfo(nvm3_defaultHandle, key, &objectType, &dataLen)); return (err == CHIP_NO_ERROR); @@ -418,11 +412,11 @@ 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(nvm3_defaultHandle, nvm3Key)); + err2 = ClearConfigValue(nvm3Key); SuccessOrExit(err2); exit: @@ -471,10 +465,6 @@ 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(nvm3_defaultHandle, nvm3_defaultInit)); - // SuccessOrExit(err); - // Find nvm3 object with current nvm3 iteration key. nvm3Res = nvm3_getObjectInfo(nvm3_defaultHandle, nvm3Key, &objectType, &dataLen); switch (nvm3Res) @@ -509,9 +499,8 @@ exit:; 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; } diff --git a/src/platform/EFR32/EFR32Config.h b/src/platform/EFR32/EFR32Config.h index d9ace9f4a39630..57b4cf126dd9e1 100644 --- a/src/platform/EFR32/EFR32Config.h +++ b/src/platform/EFR32/EFR32Config.h @@ -61,64 +61,75 @@ constexpr inline uint32_t EFR32ConfigKey(uint8_t keyBaseOffset, uint8_t 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); // 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, 0x1F); static CHIP_ERROR Init(void); static void DeInit(void); @@ -129,6 +140,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); @@ -151,7 +163,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..585d1799fe59cd 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp @@ -21,19 +21,18 @@ * 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 { @@ -41,102 +40,122 @@ namespace PersistedStorage { KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; -#if defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE +void KeyValueStoreManagerImpl::Init(void) +{ + memset(mKvsStoredKeyString, 0, sizeof(mKvsStoredKeyString)); + size_t outLen; + EFR32Config::ReadConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsStoredKeyString), + sizeof(mKvsStoredKeyString), outLen); +} + +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); + return CHIP_NO_ERROR; + } + + if (isSlotNeeded && (firstEmptyKeySlot == kMaxEntries) && (strlen(mKvsStoredKeyString[keyIndex]) == 0)) + { + firstEmptyKeySlot = keyIndex; + } + } + + if (isSlotNeeded) + { + if (firstEmptyKeySlot != kMaxEntries) + { + nvm3Key = CONVERT_KEYMAP_INDEX_TO_NVM3KEY(firstEmptyKeySlot); + err = CHIP_NO_ERROR; + } + else + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + } + else + { + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + return err; +} 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); + 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(); + *read_bytes_size = outLen; } - 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; - } - 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()) + 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); + EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, + reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString)); } - 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()) + 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])); + EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, + reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString)); } - 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..4fb3f253ccc810 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.h +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.h @@ -23,35 +23,12 @@ */ #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 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,127 +36,18 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager friend class KeyValueStoreManager; public: - void Init() { mKvs.Init(); } - + void 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 = 30; + char mKvsStoredKeyString[kMaxEntries][PersistentStorageDelegate::kKeyLengthMax + 1]; private: - // ===== Members for internal use by the following friends. + 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(); @@ -187,8 +55,6 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager static KeyValueStoreManagerImpl sInstance; }; -#endif // defined(CHIP_KVS_AVAILABLE) && CHIP_KVS_AVAILABLE - /** * Returns the public interface of the KeyValueStoreManager singleton object. * diff --git a/third_party/efr32_sdk/efr32_sdk.gni b/third_party/efr32_sdk/efr32_sdk.gni index e1127f3bcab578..996d8661e10234 100644 --- a/third_party/efr32_sdk/efr32_sdk.gni +++ b/third_party/efr32_sdk/efr32_sdk.gni @@ -138,7 +138,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)-21)", "__HEAP_SIZE=0", "SL_CATALOG_FREERTOS_KERNEL_PRESENT=1", "MBEDTLS_THREADING_C=1", @@ -218,10 +217,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 +238,6 @@ template("efr32_sdk") { defines += [ "EFR32MG21", "EFR32_SERIES2_CONFIG1_MICRO", - "CHIP_KVS_SECTOR_COUNT=4", ] } else if (efr32_family == "efr32mg24") { _include_dirs += [ @@ -264,7 +259,6 @@ template("efr32_sdk") { defines += [ "EFR32MG24", "EFR32_SERIES2_CONFIG4_MICRO", - "CHIP_KVS_SECTOR_COUNT=4", ] } if (use_wf200) { From b241f63162d52343b9b9285d6fff5c7202ef3369 Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Fri, 25 Mar 2022 18:15:16 -0400 Subject: [PATCH 03/10] Fix some return codes for KVS --- src/platform/EFR32/EFR32Config.cpp | 1 + src/platform/EFR32/KeyValueStoreManagerImpl.cpp | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/platform/EFR32/EFR32Config.cpp b/src/platform/EFR32/EFR32Config.cpp index 0499248d8581f6..1d7329ee4b2fb0 100644 --- a/src/platform/EFR32/EFR32Config.cpp +++ b/src/platform/EFR32/EFR32Config.cpp @@ -51,6 +51,7 @@ void nvm3_lockEnd(void) VerifyOrDie(nvm3_Sem != NULL); xSemaphoreGive(nvm3_Sem); } + namespace chip { namespace DeviceLayer { namespace Internal { diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp index 585d1799fe59cd..dbdd6cce5591e2 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp @@ -75,12 +75,12 @@ CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t } else { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + err = CHIP_ERROR_PERSISTED_STORAGE_FAILED; } } else { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; } return err; } @@ -88,8 +88,11 @@ CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset_bytes) const { - uint32_t nvm3Key; + 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); @@ -105,6 +108,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) { + 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); @@ -123,6 +129,8 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { + VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + uint32_t nvm3Key; CHIP_ERROR err = MapKvsKeyToNvm3(key, nvm3Key); VerifyOrReturnError(err == CHIP_NO_ERROR, err); From 62a2bcb91a170176b77eda70b673f4e8db3c0660 Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Tue, 29 Mar 2022 16:45:49 -0400 Subject: [PATCH 04/10] Update ldscript for mg24. Add verifications in kvs implementation. Regroup nvm3 and kvs init. Set ble default connection params --- examples/light-switch-app/efr32/src/main.cpp | 1 - examples/lighting-app/efr32/src/main.cpp | 1 - examples/lock-app/efr32/src/main.cpp | 1 - examples/ota-requestor-app/efr32/src/main.cpp | 1 - examples/persistent-storage/efr32/main.cpp | 2 +- .../platform/efr32/ldscripts/efr32mg12.ld | 2 +- .../platform/efr32/ldscripts/efr32mg24.ld | 53 +++++++------------ examples/shell/efr32/src/main.cpp | 1 - examples/window-app/efr32/src/main.cpp | 1 - src/platform/EFR32/BLEManagerImpl.cpp | 20 ++++++- src/platform/EFR32/EFR32Config.cpp | 2 +- src/platform/EFR32/EFR32Config.h | 1 + .../EFR32/KeyValueStoreManagerImpl.cpp | 36 +++++++++++-- src/platform/EFR32/KeyValueStoreManagerImpl.h | 7 +-- src/platform/EFR32/PlatformManagerImpl.cpp | 4 +- src/test_driver/efr32/src/main.cpp | 1 - 16 files changed, 79 insertions(+), 55 deletions(-) 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/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/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/main.cpp b/examples/persistent-storage/efr32/main.cpp index 2a86c9d7306950..92c0fa237ec0b7 100644 --- a/examples/persistent-storage/efr32/main.cpp +++ b/examples/persistent-storage/efr32/main.cpp @@ -50,8 +50,8 @@ int main(void) { init_efrPlatform(); - chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(); chip::DeviceLayer::Internal::EFR32Config::Init(); + chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(); EFR32_LOG("=================================================="); EFR32_LOG("chip-efr32-persitent-storage-example starting"); EFR32_LOG("=================================================="); diff --git a/examples/platform/efr32/ldscripts/efr32mg12.ld b/examples/platform/efr32/ldscripts/efr32mg12.ld index 5f24d3227637d7..d7c4d420d86009 100644 --- a/examples/platform/efr32/ldscripts/efr32mg12.ld +++ b/examples/platform/efr32/ldscripts/efr32mg12.ld @@ -255,7 +255,7 @@ SECTIONS KEEP(*(.simee*)) } > FLASH - linker_nvm_end = __main_flash_end__; + linker_nvm_end = __main_flash_end__ - 2048; linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm); linker_nvm_size = SIZEOF(.nvm); /* diff --git a/examples/platform/efr32/ldscripts/efr32mg24.ld b/examples/platform/efr32/ldscripts/efr32mg24.ld index 8a7835f6cf2fd0..f1881d51e96056 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,22 @@ 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); + /* + linker_storage_end = linker_nvm_begin; + linker_storage_begin = linker_storage_end - SIZEOF(.internal_storage); + linker_storage_size = SIZEOF(.internal_storage); + */ + __nvm3Base = linker_nvm_begin; - /* 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.") + /* 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 !") + } 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/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/src/platform/EFR32/BLEManagerImpl.cpp b/src/platform/EFR32/BLEManagerImpl.cpp index bbbf59105bdba5..435b3fca078d5a 100644 --- a/src/platform/EFR32/BLEManagerImpl.cpp +++ b/src/platform/EFR32/BLEManagerImpl.cpp @@ -249,6 +249,7 @@ 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(16, 100, 0, 200, 0, 0xffff); } break; @@ -257,7 +258,19 @@ 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.c:%d,i:%d,l:%d,t:%d,s:%d,txs:%d", + bluetooth_evt->data.evt_connection_parameters.connection, + bluetooth_evt->data.evt_connection_parameters.interval, + bluetooth_evt->data.evt_connection_parameters.latency, + bluetooth_evt->data.evt_connection_parameters.timeout, + bluetooth_evt->data.evt_connection_parameters.security_mode, + bluetooth_evt->data.evt_connection_parameters.txsize); + + // if (bluetooth_evt->data.evt_connection_parameters.timeout < 80) + // { + // sl_bt_connection_set_parameters(bluetooth_evt->data.evt_connection_parameters.connection, 16, 100, 0, 200, 0, + // 0xffff); + // } } break; case sl_bt_evt_connection_phy_status_id: { @@ -307,6 +320,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/EFR32Config.cpp b/src/platform/EFR32/EFR32Config.cpp index 1d7329ee4b2fb0..bf75f64e566f6f 100644 --- a/src/platform/EFR32/EFR32Config.cpp +++ b/src/platform/EFR32/EFR32Config.cpp @@ -43,7 +43,7 @@ static StaticSemaphore_t nvm3_SemStruct; void nvm3_lockBegin(void) { VerifyOrDie(nvm3_Sem != NULL); - xSemaphoreTake(nvm3_Sem, portMAX_DELAY); + xSemaphoreTake(nvm3_Sem, EFR32_SEM_TIMEOUT_ms); } void nvm3_lockEnd(void) diff --git a/src/platform/EFR32/EFR32Config.h b/src/platform/EFR32/EFR32Config.h index 57b4cf126dd9e1..6c5849989a57c9 100644 --- a/src/platform/EFR32/EFR32Config.h +++ b/src/platform/EFR32/EFR32Config.h @@ -117,6 +117,7 @@ class EFR32Config // 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, 0x1E); // Set key id limits for each group. static constexpr Key kMinConfigKey_MatterFactory = EFR32ConfigKey(kMatterFactory_KeyBase, 0x00); diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp index dbdd6cce5591e2..39cfcdf01f2a23 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp @@ -33,19 +33,40 @@ using namespace ::chip::DeviceLayer::Internal; #define CONVERT_KEYMAP_INDEX_TO_NVM3KEY(index) (EFR32Config::kConfigKey_KvsFirstKeySlot + index) #define CONVERT_NVM3KEY_TO_KEYMAP_INDEX(nvm3Key) (nvm3Key - EFR32Config::kConfigKey_KvsFirstKeySlot) - +uint32_t keyCount = 0; namespace chip { namespace DeviceLayer { namespace PersistedStorage { KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; -void KeyValueStoreManagerImpl::Init(void) +CHIP_ERROR KeyValueStoreManagerImpl::Init(void) { + CHIP_ERROR err; + keyCount = 0; + err = EFR32Config::Init(); + SuccessOrExit(err); + memset(mKvsStoredKeyString, 0, sizeof(mKvsStoredKeyString)); size_t outLen; EFR32Config::ReadConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString), outLen); + + for (uint8_t keyIndex = 0; keyIndex < kMaxEntries; keyIndex++) + { + if (mKvsStoredKeyString[keyIndex][0] != 0) + { + keyCount++; + } + } + +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 @@ -57,6 +78,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t if (strcmp(key, mKvsStoredKeyString[keyIndex]) == 0) { nvm3Key = CONVERT_KEYMAP_INDEX_TO_NVM3KEY(keyIndex); + VerifyOrDie(IsValidKvsNvm3Key(nvm3Key) == true); return CHIP_NO_ERROR; } @@ -71,7 +93,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t if (firstEmptyKeySlot != kMaxEntries) { nvm3Key = CONVERT_KEYMAP_INDEX_TO_NVM3KEY(firstEmptyKeySlot); - err = CHIP_NO_ERROR; + VerifyOrDie(IsValidKvsNvm3Key(nvm3Key) == true); + err = CHIP_NO_ERROR; + keyCount++; } else { @@ -120,8 +144,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, { uint32_t keyIndex = nvm3Key - EFR32Config::kConfigKey_KvsFirstKeySlot; strncpy(mKvsStoredKeyString[keyIndex], key, sizeof(mKvsStoredKeyString[keyIndex]) - 1); - EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, - reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString)); + err == + EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, + reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString)); } return err; @@ -138,6 +163,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) err = EFR32Config::ClearConfigValue(nvm3Key); if (err == CHIP_NO_ERROR) { + keyCount--; uint32_t keyIndex = CONVERT_NVM3KEY_TO_KEYMAP_INDEX(nvm3Key); memset(mKvsStoredKeyString[keyIndex], 0, sizeof(mKvsStoredKeyString[keyIndex])); EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.h b/src/platform/EFR32/KeyValueStoreManagerImpl.h index 4fb3f253ccc810..2b7aa8027c1702 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.h +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.h @@ -36,19 +36,20 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager friend class KeyValueStoreManager; public: - void Init(void); + 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); - static constexpr size_t kMaxEntries = 30; + static constexpr size_t kMaxEntries = 75; char mKvsStoredKeyString[kMaxEntries][PersistentStorageDelegate::kKeyLengthMax + 1]; private: + 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. + // ===== Members for internal use by the following friends. friend KeyValueStoreManager & KeyValueStoreMgr(); friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(); 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(); From 3542076379e97cc279d8ed0fae6293d087e28865 Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Wed, 30 Mar 2022 20:52:35 -0400 Subject: [PATCH 05/10] Delay keymap commit to nvm, Build argument for kvs entry count, Clean up --- examples/persistent-storage/efr32/main.cpp | 1 - .../platform/efr32/ldscripts/efr32mg12.ld | 5 --- .../platform/efr32/ldscripts/efr32mg24.ld | 7 +-- src/platform/EFR32/BLEManagerImpl.cpp | 25 +++++------ src/platform/EFR32/EFR32Config.h | 11 ++++- .../EFR32/KeyValueStoreManagerImpl.cpp | 44 +++++++++++-------- src/platform/EFR32/KeyValueStoreManagerImpl.h | 7 ++- 7 files changed, 52 insertions(+), 48 deletions(-) diff --git a/examples/persistent-storage/efr32/main.cpp b/examples/persistent-storage/efr32/main.cpp index 92c0fa237ec0b7..3d9674369fa153 100644 --- a/examples/persistent-storage/efr32/main.cpp +++ b/examples/persistent-storage/efr32/main.cpp @@ -50,7 +50,6 @@ int main(void) { init_efrPlatform(); - chip::DeviceLayer::Internal::EFR32Config::Init(); chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init(); EFR32_LOG("=================================================="); EFR32_LOG("chip-efr32-persitent-storage-example starting"); diff --git a/examples/platform/efr32/ldscripts/efr32mg12.ld b/examples/platform/efr32/ldscripts/efr32mg12.ld index d7c4d420d86009..9dba3e1ded84e2 100644 --- a/examples/platform/efr32/ldscripts/efr32mg12.ld +++ b/examples/platform/efr32/ldscripts/efr32mg12.ld @@ -258,11 +258,6 @@ SECTIONS linker_nvm_end = __main_flash_end__ - 2048; linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm); linker_nvm_size = SIZEOF(.nvm); - /* - linker_storage_end = linker_nvm_begin; - linker_storage_begin = linker_storage_end - SIZEOF(.internal_storage); - linker_storage_size = SIZEOF(.internal_storage); - */ __nvm3Base = linker_nvm_begin; /* Check if data + heap + stack exceeds RAM limit */ diff --git a/examples/platform/efr32/ldscripts/efr32mg24.ld b/examples/platform/efr32/ldscripts/efr32mg24.ld index f1881d51e96056..06bfc7c1842170 100644 --- a/examples/platform/efr32/ldscripts/efr32mg24.ld +++ b/examples/platform/efr32/ldscripts/efr32mg24.ld @@ -258,15 +258,10 @@ SECTIONS linker_nvm_end = __main_flash_end__; linker_nvm_begin = linker_nvm_end - SIZEOF(.nvm); linker_nvm_size = SIZEOF(.nvm); - /* - linker_storage_end = linker_nvm_begin; - linker_storage_begin = linker_storage_end - SIZEOF(.internal_storage); - linker_storage_size = SIZEOF(.internal_storage); - */ __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 !") - + } diff --git a/src/platform/EFR32/BLEManagerImpl.cpp b/src/platform/EFR32/BLEManagerImpl.cpp index 435b3fca078d5a..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,7 +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(16, 100, 0, 200, 0, 0xffff); + 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; @@ -258,19 +267,7 @@ void BLEManagerImpl::bluetoothStackEventHandler(void * p_arg) } break; case sl_bt_evt_connection_parameters_id: { - ChipLogProgress(DeviceLayer, "Connection parameter ID received.c:%d,i:%d,l:%d,t:%d,s:%d,txs:%d", - bluetooth_evt->data.evt_connection_parameters.connection, - bluetooth_evt->data.evt_connection_parameters.interval, - bluetooth_evt->data.evt_connection_parameters.latency, - bluetooth_evt->data.evt_connection_parameters.timeout, - bluetooth_evt->data.evt_connection_parameters.security_mode, - bluetooth_evt->data.evt_connection_parameters.txsize); - - // if (bluetooth_evt->data.evt_connection_parameters.timeout < 80) - // { - // sl_bt_connection_set_parameters(bluetooth_evt->data.evt_connection_parameters.connection, 16, 100, 0, 200, 0, - // 0xffff); - // } + // ChipLogProgress(DeviceLayer, "Connection parameter ID received"); } break; case sl_bt_evt_connection_phy_status_id: { diff --git a/src/platform/EFR32/EFR32Config.h b/src/platform/EFR32/EFR32Config.h index 6c5849989a57c9..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 { @@ -117,7 +124,7 @@ class EFR32Config // 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, 0x1E); + static constexpr Key kConfigKey_KvsLastKeySlot = EFR32ConfigKey(kMatterKvs_KeyBase, KVS_MAX_ENTRIES); // Set key id limits for each group. static constexpr Key kMinConfigKey_MatterFactory = EFR32ConfigKey(kMatterFactory_KeyBase, 0x00); @@ -130,7 +137,7 @@ class EFR32Config 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, 0x1F); + static constexpr Key kMaxConfigKey_MatterKvs = EFR32ConfigKey(kMatterKvs_KeyBase, 0xFF); static CHIP_ERROR Init(void); static void DeInit(void); diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp index 39cfcdf01f2a23..d46079fcc78163 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp @@ -33,31 +33,28 @@ using namespace ::chip::DeviceLayer::Internal; #define CONVERT_KEYMAP_INDEX_TO_NVM3KEY(index) (EFR32Config::kConfigKey_KvsFirstKeySlot + index) #define CONVERT_NVM3KEY_TO_KEYMAP_INDEX(nvm3Key) (nvm3Key - EFR32Config::kConfigKey_KvsFirstKeySlot) -uint32_t keyCount = 0; + namespace chip { namespace DeviceLayer { namespace PersistedStorage { KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; +char mKvsStoredKeyString[KeyValueStoreManagerImpl::kMaxEntries][PersistentStorageDelegate::kKeyLengthMax + 1]; CHIP_ERROR KeyValueStoreManagerImpl::Init(void) { CHIP_ERROR err; - keyCount = 0; - err = EFR32Config::Init(); + err = EFR32Config::Init(); SuccessOrExit(err); memset(mKvsStoredKeyString, 0, sizeof(mKvsStoredKeyString)); size_t outLen; - EFR32Config::ReadConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsStoredKeyString), - sizeof(mKvsStoredKeyString), outLen); + err = EFR32Config::ReadConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, reinterpret_cast(mKvsStoredKeyString), + sizeof(mKvsStoredKeyString), outLen); - for (uint8_t keyIndex = 0; keyIndex < kMaxEntries; keyIndex++) + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) // Initial boot { - if (mKvsStoredKeyString[keyIndex][0] != 0) - { - keyCount++; - } + err = CHIP_NO_ERROR; } exit: @@ -82,7 +79,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t return CHIP_NO_ERROR; } - if (isSlotNeeded && (firstEmptyKeySlot == kMaxEntries) && (strlen(mKvsStoredKeyString[keyIndex]) == 0)) + if (isSlotNeeded && (firstEmptyKeySlot == kMaxEntries) && (mKvsStoredKeyString[keyIndex][0] == 0)) { firstEmptyKeySlot = keyIndex; } @@ -95,7 +92,6 @@ CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t nvm3Key = CONVERT_KEYMAP_INDEX_TO_NVM3KEY(firstEmptyKeySlot); VerifyOrDie(IsValidKvsNvm3Key(nvm3Key) == true); err = CHIP_NO_ERROR; - keyCount++; } else { @@ -109,6 +105,22 @@ CHIP_ERROR KeyValueStoreManagerImpl::MapKvsKeyToNvm3(const char * key, uint32_t 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 { @@ -144,9 +156,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, { uint32_t keyIndex = nvm3Key - EFR32Config::kConfigKey_KvsFirstKeySlot; strncpy(mKvsStoredKeyString[keyIndex], key, sizeof(mKvsStoredKeyString[keyIndex]) - 1); - err == - EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, - reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString)); + ScheduleKeyMapSave(); } return err; @@ -163,11 +173,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) err = EFR32Config::ClearConfigValue(nvm3Key); if (err == CHIP_NO_ERROR) { - keyCount--; uint32_t keyIndex = CONVERT_NVM3KEY_TO_KEYMAP_INDEX(nvm3Key); memset(mKvsStoredKeyString[keyIndex], 0, sizeof(mKvsStoredKeyString[keyIndex])); - EFR32Config::WriteConfigValueBin(EFR32Config::kConfigKey_KvsStringKeyMap, - reinterpret_cast(mKvsStoredKeyString), sizeof(mKvsStoredKeyString)); + ScheduleKeyMapSave(); } return err; diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.h b/src/platform/EFR32/KeyValueStoreManagerImpl.h index 2b7aa8027c1702..daf5ff8ce32c42 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.h +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.h @@ -24,6 +24,8 @@ #pragma once #include +#include +#include namespace chip { namespace DeviceLayer { @@ -42,10 +44,11 @@ class KeyValueStoreManagerImpl final : public KeyValueStoreManager CHIP_ERROR _Delete(const char * key); CHIP_ERROR ErasePartition(void); - static constexpr size_t kMaxEntries = 75; - char mKvsStoredKeyString[kMaxEntries][PersistentStorageDelegate::kKeyLengthMax + 1]; + static constexpr size_t kMaxEntries = KVS_MAX_ENTRIES; private: + 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; From 65656c877398cd32ea32e4a7c2346e03c4c121cf Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Thu, 31 Mar 2022 09:31:44 -0400 Subject: [PATCH 06/10] Add build option in efr32_sdk.gni and detail in build script --- scripts/examples/gn_efr32_example.sh | 3 +++ third_party/efr32_sdk/efr32_sdk.gni | 3 +++ 2 files changed, 6 insertions(+) diff --git a/scripts/examples/gn_efr32_example.sh b/scripts/examples/gn_efr32_example.sh index 717958c530f255..90b0ca8a7ae774 100755 --- a/scripts/examples/gn_efr32_example.sh +++ b/scripts/examples/gn_efr32_example.sh @@ -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 diff --git a/third_party/efr32_sdk/efr32_sdk.gni b/third_party/efr32_sdk/efr32_sdk.gni index 996d8661e10234..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", From e7acb8b800e723727e0fdcc4dfff8b77807602e4 Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Thu, 31 Mar 2022 10:29:06 -0400 Subject: [PATCH 07/10] add info in read me --- examples/light-switch-app/efr32/README.md | 9 +++++++++ examples/lighting-app/efr32/README.md | 9 +++++++++ examples/lock-app/efr32/README.md | 9 +++++++++ examples/window-app/efr32/README.md | 9 +++++++++ 4 files changed, 36 insertions(+) diff --git a/examples/light-switch-app/efr32/README.md b/examples/light-switch-app/efr32/README.md index a4c9d154c5a6c8..914380e12a8d08 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 maxium entry count + +kvs_max_entries + + Set the maxium 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/README.md b/examples/lighting-app/efr32/README.md index a6fc76292a8d4a..51d272866ac3af 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 maxium entry count + +kvs_max_entries + + Set the maxium 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/README.md b/examples/lock-app/efr32/README.md index 65442b31d84229..1768648779ec63 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 maxium entry count + +kvs_max_entries + + Set the maxium 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/README.md b/examples/window-app/efr32/README.md index 8fac6941c0a8d8..5c715046f50a6d 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 maxium entry count + +kvs_max_entries + + Set the maxium 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 From 6b7151cdd2e41459d91063bf8ed5de45bea9fc89 Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Thu, 31 Mar 2022 10:51:55 -0400 Subject: [PATCH 08/10] Fix typo, add NVM to wordlist --- .github/.wordlist.txt | 1 + examples/light-switch-app/efr32/README.md | 4 ++-- examples/lighting-app/efr32/README.md | 4 ++-- examples/lock-app/efr32/README.md | 4 ++-- examples/window-app/efr32/README.md | 4 ++-- src/platform/EFR32/EFR32Config.cpp | 2 +- 6 files changed, 10 insertions(+), 9 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 914380e12a8d08..831b66406cd7d2 100644 --- a/examples/light-switch-app/efr32/README.md +++ b/examples/light-switch-app/efr32/README.md @@ -407,11 +407,11 @@ show_qr_code $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false" -### KVS maxium entry count +### KVS maximum entry count kvs_max_entries - Set the maxium Kvs entries that can be stored in NVM (Default 75) + 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/README.md b/examples/lighting-app/efr32/README.md index 51d272866ac3af..a4e45a380c07af 100644 --- a/examples/lighting-app/efr32/README.md +++ b/examples/lighting-app/efr32/README.md @@ -357,11 +357,11 @@ show_qr_code $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false" -### KVS maxium entry count +### KVS maximum entry count kvs_max_entries - Set the maxium Kvs entries that can be stored in NVM (Default 75) + 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/README.md b/examples/lock-app/efr32/README.md index 1768648779ec63..61c53124287916 100644 --- a/examples/lock-app/efr32/README.md +++ b/examples/lock-app/efr32/README.md @@ -322,11 +322,11 @@ show_qr_code $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false" -### KVS maxium entry count +### KVS maximum entry count kvs_max_entries - Set the maxium Kvs entries that can be stored in NVM (Default 75) + 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/README.md b/examples/window-app/efr32/README.md index 5c715046f50a6d..8756365f3a7570 100644 --- a/examples/window-app/efr32/README.md +++ b/examples/window-app/efr32/README.md @@ -357,11 +357,11 @@ show_qr_code $ ./scripts/examples/gn_efr32_example.sh ./examples/lighting-app/efr32 ./out/lighting-app BRD4164A "show_qr_code=false" -### KVS maxium entry count +### KVS maximum entry count kvs_max_entries - Set the maxium Kvs entries that can be stored in NVM (Default 75) + 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/src/platform/EFR32/EFR32Config.cpp b/src/platform/EFR32/EFR32Config.cpp index bf75f64e566f6f..f78797c504c6e8 100644 --- a/src/platform/EFR32/EFR32Config.cpp +++ b/src/platform/EFR32/EFR32Config.cpp @@ -253,7 +253,7 @@ CHIP_ERROR EFR32Config::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSiz { err = MapNvm3Error(nvm3_readPartialData(nvm3_defaultHandle, key, buf, offset, bufSize)); SuccessOrExit(err); - // read was succesful, but we did not read all the data from the object. + // read was successful, but we did not read all the data from the object. err = CHIP_ERROR_BUFFER_TOO_SMALL; outLen = bufSize; } From aeff1be3df010207a6620eb01aaea6431e95795d Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Thu, 31 Mar 2022 11:56:20 -0400 Subject: [PATCH 09/10] undo unwanted change to zap and pigweed submodule. --- third_party/pigweed/repo | 2 +- third_party/zap/repo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/pigweed/repo b/third_party/pigweed/repo index 86698c0b9620fe..67506a1a4487c7 160000 --- a/third_party/pigweed/repo +++ b/third_party/pigweed/repo @@ -1 +1 @@ -Subproject commit 86698c0b9620febe11cc274a44c9457e6127dd62 +Subproject commit 67506a1a4487c7fb1306bedc391883ec58841522 diff --git a/third_party/zap/repo b/third_party/zap/repo index a1ddd5d56c4bd9..9c885cf9391fc0 160000 --- a/third_party/zap/repo +++ b/third_party/zap/repo @@ -1 +1 @@ -Subproject commit a1ddd5d56c4bd9b7ba52c63f13665d96a11134ce +Subproject commit 9c885cf9391fc09b450e5e8a8e40e381c4bee27d From b19772d5657c5f6669af339c8264a0fd1ea11368 Mon Sep 17 00:00:00 2001 From: Junior Martinez Date: Thu, 31 Mar 2022 14:10:09 -0400 Subject: [PATCH 10/10] remove mv command --- scripts/examples/gn_efr32_example.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/examples/gn_efr32_example.sh b/scripts/examples/gn_efr32_example.sh index 90b0ca8a7ae774..37346facff934d 100755 --- a/scripts/examples/gn_efr32_example.sh +++ b/scripts/examples/gn_efr32_example.sh @@ -158,7 +158,6 @@ else fi fi ninja -v -C "$BUILD_DIR"/ - mv """$BUILD_DIR/compile_commands.json" "$CHIP_ROOT/out/debug/compile_commands.efr32.json" #print stats arm-none-eabi-size -A "$BUILD_DIR"/*.out