diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp index f5b14b9eb2a7e3..8d120eb6c5abaa 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -97,8 +97,6 @@ static OTAImageProcessorImpl gImageProcessor; constexpr uint16_t requestedOtaBlockSize = 1024; #endif -extern bool shouldReset; - CHIP_ERROR AppTask::StartAppTask() { CHIP_ERROR err = CHIP_NO_ERROR; diff --git a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c index 8b94397ae7a39d..5bdb70c6ee21fc 100644 --- a/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c +++ b/examples/platform/nxp/k32w/k32w0/app/support/FreeRtosHooks.c @@ -27,6 +27,7 @@ #include #include +#include "PDM.h" #include "PWR_Interface.h" #include "TimersManager.h" #include "board.h" @@ -52,6 +53,8 @@ #define APP_DBG_LOG(...) #endif +#define PDM_MAX_WRITES_INFINITE 0xFF + static inline void mutex_init(mbedtls_threading_mutex_t * p_mutex) { assert(p_mutex != NULL); @@ -229,10 +232,11 @@ static void BOARD_ActionOnIdle(void) #endif } -extern void OTAIdleActivities(); +extern void OTAIdleActivities(void); void vApplicationIdleHook(void) { + PDM_vIdleTask(PDM_MAX_WRITES_INFINITE); OTAIdleActivities(); BOARD_ActionOnIdle(); } diff --git a/src/platform/nxp/k32w/k32w0/BUILD.gn b/src/platform/nxp/k32w/k32w0/BUILD.gn index e813d8253c48bd..dddeef7374b20a 100644 --- a/src/platform/nxp/k32w/k32w0/BUILD.gn +++ b/src/platform/nxp/k32w/k32w0/BUILD.gn @@ -47,6 +47,8 @@ static_library("k32w0") { "NFCManagerImpl.h", "PlatformManagerImpl.cpp", "PlatformManagerImpl.h", + "RamStorage.cpp", + "RamStorage.h", "ble_function_mux.c", ] diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp b/src/platform/nxp/k32w/k32w0/K32W0Config.cpp index 6c8e4f9c1f2ad7..bab9d1eb2e618b 100644 --- a/src/platform/nxp/k32w/k32w0/K32W0Config.cpp +++ b/src/platform/nxp/k32w/k32w0/K32W0Config.cpp @@ -36,15 +36,26 @@ namespace chip { namespace DeviceLayer { namespace Internal { +static ramBufferDescriptor * ramDescr; + +constexpr uint16_t kNvmIdChipConfigData = 0x5000; +constexpr uint16_t kRamBufferInitialSize = 3072; + CHIP_ERROR K32WConfig::Init() { - CHIP_ERROR err; + CHIP_ERROR err = CHIP_NO_ERROR; int pdmStatus; /* Initialise the Persistent Data Manager */ pdmStatus = PDM_Init(); SuccessOrExit(err = MapPdmInitStatus(pdmStatus)); + ramDescr = getRamBuffer(kNvmIdChipConfigData, kRamBufferInitialSize); + if (!ramDescr) + { + err = CHIP_ERROR_NO_MEMORY; + } + exit: return err; } @@ -53,12 +64,12 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, bool & val) { CHIP_ERROR err; bool tempVal; - uint16_t bytesRead; - PDM_teStatus pdmStatus; + rsError status; + uint16_t sizeToRead = sizeof(tempVal); VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(bool), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); + status = ramStorageGet(ramDescr, key, 0, (uint8_t *) &tempVal, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); val = tempVal; exit: @@ -69,22 +80,13 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint32_t & val) { CHIP_ERROR err; uint32_t tempVal; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; + rsError status; + uint16_t sizeToRead = sizeof(tempVal); VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint32_t), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - val = tempVal; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } + status = ramStorageGet(ramDescr, key, 0, (uint8_t *) &tempVal, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); + val = tempVal; exit: return err; @@ -93,24 +95,14 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint32_t & val) CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint64_t & val) { CHIP_ERROR err; - uint64_t tempVal; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; + uint32_t tempVal; + rsError status; + uint16_t sizeToRead = sizeof(tempVal); VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint64_t), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - val = tempVal; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } + status = ramStorageGet(ramDescr, key, 0, (uint8_t *) &tempVal, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); + val = tempVal; exit: return err; @@ -119,130 +111,44 @@ CHIP_ERROR K32WConfig::ReadConfigValue(Key key, uint64_t & val) CHIP_ERROR K32WConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { CHIP_ERROR err; - const uint8_t * strEnd; - char * pData = NULL; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - - outLen = 0; + rsError status; + uint16_t sizeToRead = bufSize; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pData = (char *) pvPortMalloc(recordSize); - VerifyOrExit((pData != NULL), err = CHIP_ERROR_NO_MEMORY); - - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, pData, recordSize, &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - - strEnd = (const uint8_t *) memchr(pData, 0, bytesRead); - VerifyOrExit(strEnd != NULL, err = CHIP_ERROR_INVALID_ARGUMENT); - - outLen = strEnd - (const uint8_t *) pData; - - // NOTE: the caller is allowed to pass NULL for buf to query the length of the stored value. - - if (buf != NULL) - { - VerifyOrExit(bufSize > outLen, err = CHIP_ERROR_BUFFER_TOO_SMALL); - - memcpy(buf, pData, outLen + 1); - } - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } + // We can call ramStorageGet with null pointer to only retrieve the size + status = ramStorageGet(ramDescr, key, 0, (uint8_t *) buf, &sizeToRead); + SuccessOrExit(err = MapRamStorageStatus(status)); + outLen = sizeToRead; exit: - if (pData != NULL) - { - vPortFree((void *) pData); - } return err; } CHIP_ERROR K32WConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { - CHIP_ERROR err; - uint8_t * pData = NULL; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - - outLen = 0; - - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pData = (uint8_t *) pvPortMalloc(recordSize); - VerifyOrExit((pData != NULL), err = CHIP_ERROR_NO_MEMORY); - - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, pData, recordSize, &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - - if (buf != NULL) - { - VerifyOrExit((bufSize >= bytesRead), err = CHIP_ERROR_BUFFER_TOO_SMALL); - memcpy(buf, pData, bytesRead); - } - outLen = bytesRead; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } - -exit: - if (pData != NULL) - { - vPortFree((void *) pData); - } - - return err; + return ReadConfigValueStr(key, (char *) buf, bufSize, outLen); } CHIP_ERROR K32WConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val) { - CHIP_ERROR err; - uint32_t tempVal; - uint16_t bytesRead; - uint16_t recordSize; - PDM_teStatus pdmStatus; - Key key = kMinConfigKey_ChipCounter + counterIdx; - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if (PDM_bDoesDataExist((uint16_t) key, &recordSize)) - { - pdmStatus = PDM_eReadDataFromRecord((uint16_t) key, &tempVal, sizeof(uint32_t), &bytesRead); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - val = tempVal; - } - else - { - err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - goto exit; - } - -exit: - return err; + return ReadConfigValue(key, val); } CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val) { CHIP_ERROR err; + rsError status; PDM_teStatus pdmStatus; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(bool)); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); + status = ramStorageSet(&ramDescr, key, (uint8_t *) &val, sizeof(bool)); + SuccessOrExit(err = MapRamStorageStatus(status)); + pdmStatus = + PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize); + SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: return err; } @@ -250,10 +156,15 @@ CHIP_ERROR K32WConfig::WriteConfigValue(Key key, bool val) CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val) { CHIP_ERROR err; + rsError status; PDM_teStatus pdmStatus; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint32_t)); + status = ramStorageSet(&ramDescr, key, (uint8_t *) &val, sizeof(uint32_t)); + SuccessOrExit(err = MapRamStorageStatus(status)); + + pdmStatus = + PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize); SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: @@ -263,10 +174,15 @@ CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint32_t val) CHIP_ERROR K32WConfig::WriteConfigValue(Key key, uint64_t val) { CHIP_ERROR err; + rsError status; PDM_teStatus pdmStatus; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint64_t)); + status = ramStorageSet(&ramDescr, key, (uint8_t *) &val, sizeof(uint64_t)); + SuccessOrExit(err = MapRamStorageStatus(status)); + + pdmStatus = + PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize); SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: @@ -282,25 +198,18 @@ CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t str { CHIP_ERROR err; PDM_teStatus pdmStatus; + rsError status; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. if (str != NULL) { - uint8_t * pData = (uint8_t *) pvPortMalloc(strLen + 1); - - if (pData != NULL) - { - memcpy(pData, str, strLen); - pData[strLen] = '\0'; - pdmStatus = PDM_eSaveRecordData((uint16_t) key, (void *) pData, strLen + 1); - vPortFree((void *) pData); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - } - else - { - err = CHIP_ERROR_NO_MEMORY; - } + status = ramStorageSet(&ramDescr, key, (uint8_t *) str, strLen); + SuccessOrExit(err = MapRamStorageStatus(status)); + + pdmStatus = + PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize); + SuccessOrExit(err = MapPdmStatus(pdmStatus)); } else { @@ -314,48 +223,28 @@ CHIP_ERROR K32WConfig::WriteConfigValueStr(Key key, const char * str, size_t str CHIP_ERROR K32WConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { - CHIP_ERROR err; - PDM_teStatus pdmStatus; - - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - - if ((data != NULL) && (dataLen > 0)) - { - pdmStatus = PDM_eSaveRecordData((uint16_t) key, (void *) data, dataLen); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - } - else - { - err = ClearConfigValue(key); - SuccessOrExit(err); - } - -exit: - return err; + return WriteConfigValueStr(key, (char *) data, dataLen); } CHIP_ERROR K32WConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val) { - CHIP_ERROR err; - PDM_teStatus pdmStatus; - Key key = kMinConfigKey_ChipCounter + counterIdx; - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - pdmStatus = PDM_eSaveRecordData((uint16_t) key, &val, sizeof(uint32_t)); - SuccessOrExit(err = MapPdmStatus(pdmStatus)); - -exit: - return err; + return WriteConfigValue(key, val); } CHIP_ERROR K32WConfig::ClearConfigValue(Key key) { CHIP_ERROR err = CHIP_NO_ERROR; + rsError status; + PDM_teStatus pdmStatus; VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - PDM_vDeleteDataRecord((uint16_t) key); + status = ramStorageDelete(ramDescr, key, 0); + SuccessOrExit(err = MapRamStorageStatus(status)); - SuccessOrExit(err); + pdmStatus = + PDM_eSaveRecordDataInIdleTask((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize); + SuccessOrExit(err = MapPdmStatus(pdmStatus)); exit: return err; @@ -363,66 +252,73 @@ CHIP_ERROR K32WConfig::ClearConfigValue(Key key) bool K32WConfig::ConfigValueExists(Key key) { - CHIP_ERROR err; - uint16_t size = 0; - - VerifyOrExit(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. - VerifyOrExit(PDM_bDoesDataExist((uint16_t) key, &size), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); + rsError status; + uint16_t sizeToRead; + bool found = false; -exit: - // Return true if the record was found. - return (err == CHIP_NO_ERROR); + if (ValidConfigKey(key)) + { + status = ramStorageGet(ramDescr, key, 0, NULL, &sizeToRead); + found = (status == RS_ERROR_NONE && sizeToRead != 0); + } + return found; } CHIP_ERROR K32WConfig::FactoryResetConfig(void) { - CHIP_ERROR err; + CHIP_ERROR err = CHIP_NO_ERROR; + PDM_teStatus pdmStatus; - err = FactoryResetConfigInternal(kMinConfigKey_ChipConfig, kMaxConfigKey_ChipConfig); + FactoryResetConfigInternal(kMinConfigKey_ChipConfig, kMaxConfigKey_ChipConfig); + FactoryResetConfigInternal(kMinConfigKey_KVSKey, kMaxConfigKey_KVSKey); + FactoryResetConfigInternal(kMinConfigKey_KVSValue, kMaxConfigKey_KVSValue); - if (err == CHIP_NO_ERROR) - { - err = FactoryResetConfigInternal(kMinConfigKey_KVS, kMaxConfigKey_KVS); - } + pdmStatus = PDM_eSaveRecordData((uint16_t) kNvmIdChipConfigData, ramDescr, ramDescr->ramBufferLen + kRamDescHeaderSize); + SuccessOrExit(err = MapPdmStatus(pdmStatus)); +exit: return err; } -CHIP_ERROR K32WConfig::FactoryResetConfigInternal(Key firstKey, Key lastKey) +void K32WConfig::FactoryResetConfigInternal(Key firstKey, Key lastKey) { - CHIP_ERROR err; - - // Iterate over all the CHIP Config PDM ID records and delete each one - err = ForEachRecord(firstKey, lastKey, false, [](const Key & pdmKey, const size_t & length) -> CHIP_ERROR { - CHIP_ERROR err2; - - err2 = ClearConfigValue(pdmKey); - SuccessOrExit(err2); + for (Key key = firstKey; key <= lastKey; key++) + { + ramStorageDelete(ramDescr, key, 0); + } +} - exit: - return err2; - }); +CHIP_ERROR K32WConfig::MapPdmStatus(PDM_teStatus pdmStatus) +{ + CHIP_ERROR err; - // Return success at end of iterations. - if (err == CHIP_END_OF_INPUT) + switch (pdmStatus) { + case PDM_E_STATUS_OK: err = CHIP_NO_ERROR; + break; + default: + err = CHIP_ERROR(ChipError::Range::kPlatform, pdmStatus); + break; } return err; } -CHIP_ERROR K32WConfig::MapPdmStatus(PDM_teStatus pdmStatus) +CHIP_ERROR K32WConfig::MapRamStorageStatus(rsError rsStatus) { CHIP_ERROR err; - switch (pdmStatus) + switch (rsStatus) { - case PDM_E_STATUS_OK: + case RS_ERROR_NONE: err = CHIP_NO_ERROR; break; + case RS_ERROR_NOT_FOUND: + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + break; default: - err = CHIP_ERROR(ChipError::Range::kPlatform, pdmStatus); + err = CHIP_ERROR_BUFFER_TOO_SMALL; break; } @@ -437,8 +333,7 @@ CHIP_ERROR K32WConfig::MapPdmInitStatus(int pdmStatus) bool K32WConfig::ValidConfigKey(Key key) { // Returns true if the key is in the valid CHIP Config PDM key range. - - if ((key >= kMinConfigKey_ChipFactory) && (key <= kMaxConfigKey_KVS)) + if ((key >= kMinConfigKey_ChipFactory) && (key <= kMaxConfigKey_KVSValue)) { return true; } @@ -446,40 +341,6 @@ bool K32WConfig::ValidConfigKey(Key key) return false; } -CHIP_ERROR K32WConfig::ForEachRecord(Key firstKey, Key lastKey, bool addNewRecord, ForEachRecordFunct funct) -{ - CHIP_ERROR err = CHIP_NO_ERROR; - - for (Key pdmKey = firstKey; pdmKey <= lastKey; pdmKey++) - { - uint16_t dataLen; - - if (PDM_bDoesDataExist((uint16_t) pdmKey, &dataLen)) - { - if (!addNewRecord) - { - // Invoke the caller's function - // (for retrieve,store,delete,enumerate GroupKey operations). - err = funct(pdmKey, dataLen); - } - } - else - { - if (addNewRecord) - { - // Invoke caller's function - // (for add GroupKey operation). - err = funct(pdmKey, dataLen); - } - } - - SuccessOrExit(err); - } - -exit: - return err; -} - void K32WConfig::RunConfigUnitTest() {} } // namespace Internal diff --git a/src/platform/nxp/k32w/k32w0/K32W0Config.h b/src/platform/nxp/k32w/k32w0/K32W0Config.h index bae56b39845996..803149947a7a71 100644 --- a/src/platform/nxp/k32w/k32w0/K32W0Config.h +++ b/src/platform/nxp/k32w/k32w0/K32W0Config.h @@ -29,6 +29,7 @@ #include #include "PDM.h" +#include "RamStorage.h" namespace chip { namespace DeviceLayer { @@ -59,7 +60,9 @@ class K32WConfig * Cleared during factory reset. */ static constexpr uint8_t kPDMId_ChipCounter = 0x03; /**< PDM id for settings containing dynamic counter values set at runtime. * Retained during factory reset. */ - static constexpr uint8_t kPDMId_KVS = 0x04; /**< PDM id for settings containing KVS set at runtime. + static constexpr uint8_t kPDMId_KVSKey = 0x04; /**< PDM id for settings containing KVS keys set at runtime. + * Cleared during factory reset. */ + static constexpr uint8_t kPDMId_KVSValue = 0x05; /**< PDM id for settings containing KVS values set at runtime. * Cleared during factory reset. */ using Key = uint32_t; @@ -104,8 +107,10 @@ class K32WConfig static constexpr Key kMaxConfigKey_ChipConfig = K32WConfigKey(kPDMId_ChipConfig, 0xFF); static constexpr Key kMinConfigKey_ChipCounter = K32WConfigKey(kPDMId_ChipCounter, 0x00); static constexpr Key kMaxConfigKey_ChipCounter = K32WConfigKey(kPDMId_ChipCounter, 0xFF); // Allows 32 Counters to be created. - static constexpr Key kMinConfigKey_KVS = K32WConfigKey(kPDMId_KVS, 0x00); - static constexpr Key kMaxConfigKey_KVS = K32WConfigKey(kPDMId_KVS, 0xFF); + static constexpr Key kMinConfigKey_KVSKey = K32WConfigKey(kPDMId_KVSKey, 0x00); + static constexpr Key kMaxConfigKey_KVSKey = K32WConfigKey(kPDMId_KVSKey, 0xFF); + static constexpr Key kMinConfigKey_KVSValue = K32WConfigKey(kPDMId_KVSValue, 0x00); + static constexpr Key kMaxConfigKey_KVSValue = K32WConfigKey(kPDMId_KVSValue, 0xFF); static CHIP_ERROR Init(void); @@ -131,15 +136,14 @@ class K32WConfig static void RunConfigUnitTest(void); protected: - using ForEachRecordFunct = std::function; - static CHIP_ERROR ForEachRecord(Key firstKey, Key lastKey, bool addNewRecord, ForEachRecordFunct funct); static constexpr uint8_t GetPDMId(uint32_t key); static constexpr uint8_t GetRecordKey(uint32_t key); private: static CHIP_ERROR MapPdmStatus(PDM_teStatus pdmStatus); + static CHIP_ERROR MapRamStorageStatus(rsError rsStatus); static CHIP_ERROR MapPdmInitStatus(int pdmStatus); - static CHIP_ERROR FactoryResetConfigInternal(Key firstKey, Key lastKey); + static void FactoryResetConfigInternal(Key firstKey, Key lastKey); }; /** diff --git a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp index cf30ee9a4c6eb1..3d2dd7374f0d90 100644 --- a/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.cpp @@ -38,105 +38,65 @@ namespace DeviceLayer { namespace PersistedStorage { /* TODO: adjust these values */ -constexpr size_t kMaxNumberOfKeys = 125; +constexpr size_t kMaxNumberOfKeys = 150; constexpr size_t kMaxKeyValueBytes = 255; KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; -/* hashmap having: - * - the matter key string as key; - * - internal PDM identifier as value; - */ -std::unordered_map g_kvs_map; - -/* set containing used PDM identifiers */ -std::set g_key_ids_set; - -/* used to check if we need to restore values from flash (e.g.: reset) */ -static bool g_restored_from_flash = false; - -CHIP_ERROR RestoreFromFlash() +uint16_t GetStringKeyId(const char * key, uint16_t * freeId) { - CHIP_ERROR err = CHIP_NO_ERROR; - uint8_t key_id = 0; - char key_string_id[kMaxKeyValueBytes] = { 0 }; - size_t key_string_id_size = 0; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - uint16_t pdm_internal_id = 0; - - if (g_restored_from_flash) - { - /* already restored from flash, nothing to do */ - return err; - } - - for (key_id = 0; key_id < kMaxNumberOfKeys; key_id++) + CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + uint8_t keyId = 0; + uint8_t pdmIdKvsKey = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVSKey; + bool bFreeIdxFound = false; + char keyString[kMaxKeyValueBytes] = { 0 }; + size_t keyStringSize = 0; + uint16_t pdmInternalId; + + for (keyId = 0; keyId < kMaxNumberOfKeys; keyId++) { - /* key was saved as string in flash (key_string_id) using (key_id + kMaxNumberOfKeys) as PDM key - * value corresponding to key_string_id was saved in flash using key_id as PDM key - */ - - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id + kMaxNumberOfKeys); - err = chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueStr(pdm_internal_id, key_string_id, kMaxKeyValueBytes, - key_string_id_size); - - if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) - { - err = CHIP_NO_ERROR; - continue; - } - else if (err != CHIP_NO_ERROR) - { - ChipLogProgress(DeviceLayer, "KVS, Error while restoring Matter key [%s] from flash with PDM id: %i", key_string_id, - pdm_internal_id); - return err; - } + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvsKey, keyId); + err = + chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueStr(pdmInternalId, keyString, kMaxKeyValueBytes, keyStringSize); - if (key_string_id_size) + if (err == CHIP_NO_ERROR) { - g_key_ids_set.insert(key_id); - key_string_id_size = 0; - if (!g_kvs_map.insert(std::make_pair(std::string(key_string_id), key_id)).second) + if (strcmp(key, keyString) == 0) { - /* key collision is not expected when restoring from flash */ - ChipLogProgress(DeviceLayer, "KVS, Unexpected collision while restoring Matter key [%s] from flash with PDM id: %i", - key_string_id, pdm_internal_id); - } - else - { - ChipLogProgress(DeviceLayer, "KVS, restored Matter key [%s] from flash with PDM id: %i", key_string_id, - pdm_internal_id); + // found the entry we are looking for + break; } } + else if ((NULL != freeId) && (false == bFreeIdxFound)) + { + bFreeIdxFound = true; + *freeId = keyId; + } } - - g_restored_from_flash = true; - - return err; + return keyId; } CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset_bytes) { - CHIP_ERROR err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - std::unordered_map::const_iterator it; - size_t read_bytes = 0; - uint8_t key_id = 0; - uint16_t pdm_internal_id = 0; + CHIP_ERROR err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + uint8_t pdmIdKvsValue = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVSValue; + size_t read_bytes = 0; + uint8_t keyId = 0; + uint16_t pdmInternalId = 0; - VerifyOrExit((key != NULL) && (value != NULL) && (RestoreFromFlash() == CHIP_NO_ERROR), err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit((key != NULL) && (value != NULL), err = CHIP_ERROR_INVALID_ARGUMENT); - if ((it = g_kvs_map.find(key)) != g_kvs_map.end()) - { - key_id = it->second; - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id); + keyId = GetStringKeyId(key, NULL); - err = - chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueBin(pdm_internal_id, (uint8_t *) value, value_size, read_bytes); + if (keyId < kMaxNumberOfKeys) + { + // This is the ID of the actual data + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvsValue, keyId); + err = chip::DeviceLayer::Internal::K32WConfig::ReadConfigValueBin(pdmInternalId, (uint8_t *) value, value_size, read_bytes); *read_bytes_size = read_bytes; - ChipLogProgress(DeviceLayer, "KVS, get Matter key [%s] with PDM id: %i", key, pdm_internal_id); + ChipLogProgress(DeviceLayer, "KVS, get Matter key [%s] with PDM id: %i", key, pdmInternalId); } exit: @@ -145,69 +105,57 @@ 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) { - CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - uint8_t key_id; - bool_t put_key = false; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - std::unordered_map::const_iterator it; - uint16_t pdm_internal_id = 0; - - VerifyOrExit((key != NULL) && (value != NULL) && (RestoreFromFlash() == CHIP_NO_ERROR), err = CHIP_ERROR_INVALID_ARGUMENT); - - if ((it = g_kvs_map.find(key)) == g_kvs_map.end()) /* new key */ - { - for (key_id = 0; key_id < kMaxNumberOfKeys; key_id++) - { - std::set::iterator iter = std::find(g_key_ids_set.begin(), g_key_ids_set.end(), key_id); + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + bool_t putKey = false; + uint8_t pdmIdKvsKey = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVSKey; + uint8_t pdmIdKvsValue = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVSValue; + uint16_t pdmInternalId = 0; + uint16_t freeKeyId; + uint8_t keyId; - if (iter == g_key_ids_set.end()) - { - if (g_key_ids_set.size() >= kMaxNumberOfKeys) - { - return CHIP_ERROR_NO_MEMORY; - } + VerifyOrExit((key != NULL) && (value != NULL), err = CHIP_ERROR_INVALID_ARGUMENT); - g_key_ids_set.insert(key_id); + keyId = GetStringKeyId(key, &freeKeyId); - put_key = true; - break; - } - } + // Key already exists + if (keyId < kMaxNumberOfKeys) + { + // Update just the value in this case + putKey = false; } - else /* overwrite key */ + else { - put_key = true; - key_id = it->second; + // Need to write both the value and the string key + putKey = true; + keyId = freeKeyId; } - if (put_key) - { - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id); - ChipLogProgress(DeviceLayer, "KVS, save in flash the value of the Matter key [%s] with PDM id: %i", key, pdm_internal_id); + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvsValue, keyId); + ChipLogProgress(DeviceLayer, "KVS, save in flash the value of the Matter key [%s] with PDM id: %i", key, pdmInternalId); - g_kvs_map.insert(std::make_pair(std::string(key), key_id)); - err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueBin(pdm_internal_id, (uint8_t *) value, value_size); + err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueBin(pdmInternalId, (uint8_t *) value, value_size); - /* save the 'key' in flash such that it can be retrieved later on */ - if (err == CHIP_NO_ERROR) + /* save the 'key' in flash such that it can be retrieved later on */ + if (err == CHIP_NO_ERROR) + { + if (true == putKey) { - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id + kMaxNumberOfKeys); - ChipLogProgress(DeviceLayer, "KVS, save in flash the Matter key [%s] with PDM id: %i", key, pdm_internal_id); + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvsKey, keyId); + ChipLogProgress(DeviceLayer, "KVS, save in flash the Matter key [%s] with PDM id: %i", key, pdmInternalId); - /* TODO (MATTER-132): do we need to make sure that "key" is NULL-terminated? */ - err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueStr(pdm_internal_id, key, strlen(key) + 1); + err = chip::DeviceLayer::Internal::K32WConfig::WriteConfigValueStr(pdmInternalId, key, strlen(key) + 1); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "KVS, Error while saving in flash the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); } } - else - { - ChipLogProgress(DeviceLayer, "KVS, Error while saving in flash the value of the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); - } + } + else + { + ChipLogProgress(DeviceLayer, "KVS, Error while saving in flash the value of the Matter key [%s] with PDM id: %i", key, + pdmInternalId); } exit: @@ -216,48 +164,46 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { - CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; - std::unordered_map::const_iterator it; - uint8_t pdm_id_kvs = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVS; - uint8_t key_id = 0; - uint16_t pdm_internal_id = 0; + CHIP_ERROR err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + uint8_t pdmIdKvsKey = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVSKey; + uint8_t pdmIdKvsValue = chip::DeviceLayer::Internal::K32WConfig::kPDMId_KVSValue; + uint8_t keyId = 0; + uint16_t pdmInternalId = 0; - VerifyOrExit((key != NULL) && (RestoreFromFlash() == CHIP_NO_ERROR), err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit((key != NULL), err = CHIP_ERROR_INVALID_ARGUMENT); - if ((it = g_kvs_map.find(key)) != g_kvs_map.end()) - { - key_id = it->second; - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id); + keyId = GetStringKeyId(key, NULL); - g_key_ids_set.erase(key_id); - g_kvs_map.erase(it); + if (keyId < kMaxNumberOfKeys) + { + // entry exists so we can remove it + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvsKey, keyId); - ChipLogProgress(DeviceLayer, "KVS, delete from flash the Matter key [%s] with PDM id: %i", key, pdm_internal_id); - err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdm_internal_id); + ChipLogProgress(DeviceLayer, "KVS, delete from flash the Matter key [%s] with PDM id: %i", key, pdmInternalId); + err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdmInternalId); /* also delete the 'key string' from flash */ if (err == CHIP_NO_ERROR) { - pdm_internal_id = chip::DeviceLayer::Internal::K32WConfigKey(pdm_id_kvs, key_id + kMaxNumberOfKeys); + pdmInternalId = chip::DeviceLayer::Internal::K32WConfigKey(pdmIdKvsValue, keyId); ChipLogProgress(DeviceLayer, "KVS, delete from flash the value of the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); - err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdm_internal_id); + err = chip::DeviceLayer::Internal::K32WConfig::ClearConfigValue(pdmInternalId); if (err != CHIP_NO_ERROR) { ChipLogProgress(DeviceLayer, "KVS, Error while deleting from flash the value of the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); } } else { ChipLogProgress(DeviceLayer, "KVS, Error while deleting from flash the Matter key [%s] with PDM id: %i", key, - pdm_internal_id); + pdmInternalId); } } - exit: return err; } diff --git a/src/platform/nxp/k32w/k32w0/RamStorage.cpp b/src/platform/nxp/k32w/k32w0/RamStorage.cpp new file mode 100644 index 00000000000000..4d23aa7024ad64 --- /dev/null +++ b/src/platform/nxp/k32w/k32w0/RamStorage.cpp @@ -0,0 +1,283 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * NVM Writes are time-consuming so instead of blocking the main tasks (e.g.: Matter) + * buffer the writes in a RAM buffer that gets to be written in the Idle Task + */ +#include +#include +#include + +#include "FunctionLib.h" +#include "RamStorage.h" + +#ifndef RAM_STORAGE_LOG +#define RAM_STORAGE_LOG 0 +#endif + +#include + +#if RAM_STORAGE_LOG +#include "fsl_debug_console.h" +#define RAM_STORAGE_PRINTF(...) \ + PRINTF("[%s] ", __FUNCTION__); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n\r"); +#else +#define RAM_STORAGE_PRINTF(...) +#endif + +/* increment size for dynamic memory re-allocation in case the + * initial RAM buffer size gets insufficient + */ +constexpr size_t kRamBufferReallocSize = 512; +constexpr size_t kRamBufferMaxAllocSize = 10240; + +ramBufferDescriptor * getRamBuffer(uint16_t nvmId, uint16_t initialSize) +{ + ramBufferDescriptor * ramDescr = NULL; + bool bLoadDataFromNvm = false; + uint16_t bytesRead = 0; + uint16_t recordSize = 0; + uint16_t allocSize = initialSize; + + /* Check if dataset is present and get its size */ + if (PDM_bDoesDataExist(nvmId, &recordSize)) + { + bLoadDataFromNvm = true; + while (recordSize > allocSize) + { + // increase size until NVM data fits + allocSize += kRamBufferReallocSize; + } + } + + if (allocSize <= kRamBufferMaxAllocSize) + { + ramDescr = (ramBufferDescriptor *) malloc(allocSize); + if (ramDescr) + { + ramDescr->ramBufferLen = 0; + ramDescr->ramBufferMaxLen = allocSize - kRamDescHeaderSize; + + if (bLoadDataFromNvm) + { + /* Try to load the dataset in RAM */ + if (PDM_E_STATUS_OK != PDM_eReadDataFromRecord(nvmId, ramDescr, recordSize, &bytesRead)) + { + memset(ramDescr, 0, allocSize); + } + } + } + } + + return ramDescr; +} + +static rsError ramStorageAdd(ramBufferDescriptor * pBuffer, uint16_t aKey, const uint8_t * aValue, uint16_t aValueLength) +{ + rsError error = RS_ERROR_NONE; + struct settingsBlock currentBlock = { 0 }; + const uint16_t newBlockLength = sizeof(settingsBlock) + aValueLength; + + if (pBuffer->ramBufferLen + newBlockLength <= pBuffer->ramBufferMaxLen) + { + currentBlock.key = aKey; + currentBlock.length = aValueLength; + + memcpy(&pBuffer->pRamBuffer[pBuffer->ramBufferLen], ¤tBlock, sizeof(settingsBlock)); + memcpy(&pBuffer->pRamBuffer[pBuffer->ramBufferLen + sizeof(settingsBlock)], aValue, aValueLength); + pBuffer->ramBufferLen += newBlockLength; + + error = RS_ERROR_NONE; + } + else + { + error = RS_ERROR_NO_BUFS; + } + + RAM_STORAGE_PRINTF("key = %d lengthWriten = %d err = %d", aKey, aValueLength, error); + + return error; +} + +rsError ramStorageGet(const ramBufferDescriptor * pBuffer, uint16_t aKey, int aIndex, uint8_t * aValue, uint16_t * aValueLength) +{ + uint16_t i = 0; + uint16_t valueLength = 0; + uint16_t readLength = 0; + int currentIndex = 0; + struct settingsBlock currentBlock = { 0 }; + rsError error = RS_ERROR_NOT_FOUND; + + while (i < pBuffer->ramBufferLen) + { + memcpy(¤tBlock, &pBuffer->pRamBuffer[i], sizeof(settingsBlock)); + + if (aKey == currentBlock.key) + { + if (currentIndex == aIndex) + { + readLength = currentBlock.length; + + // Perform read only if an input buffer was passed in + if (aValue != NULL && aValueLength != NULL) + { + // Adjust read length if input buffer size is smaller + if (readLength > *aValueLength) + { + readLength = *aValueLength; + } + + memcpy(aValue, &pBuffer->pRamBuffer[i + sizeof(settingsBlock)], readLength); + } + + valueLength = currentBlock.length; + error = RS_ERROR_NONE; + break; + } + + currentIndex++; + } + + i += sizeof(settingsBlock) + currentBlock.length; + } + + if (aValueLength != NULL) + { + *aValueLength = valueLength; + } + + RAM_STORAGE_PRINTF("key = %d err = %d", aKey, error); + + return error; +} + +static rsError ramStorageSetInternal(ramBufferDescriptor * pBuffer, uint16_t aKey, const uint8_t * aValue, uint16_t aValueLength) +{ + uint16_t i = 0; + uint16_t currentBlockLength = 0; + uint16_t nextBlockStart = 0; + struct settingsBlock currentBlock = { 0 }; + + // Delete all entries of aKey + while (i < pBuffer->ramBufferLen) + { + memcpy(¤tBlock, &pBuffer->pRamBuffer[i], sizeof(settingsBlock)); + currentBlockLength = sizeof(settingsBlock) + currentBlock.length; + + if (aKey == currentBlock.key) + { + nextBlockStart = i + currentBlockLength; + + if (nextBlockStart < pBuffer->ramBufferLen) + { + memmove(&pBuffer->pRamBuffer[i], &pBuffer->pRamBuffer[nextBlockStart], pBuffer->ramBufferLen - nextBlockStart); + } + + VerifyOrDie(pBuffer->ramBufferLen >= currentBlockLength); + pBuffer->ramBufferLen -= currentBlockLength; + } + else + { + i += currentBlockLength; + } + } + + return ramStorageAdd(pBuffer, aKey, aValue, aValueLength); +} + +rsError ramStorageSet(ramBufferDescriptor ** pBuffer, uint16_t aKey, const uint8_t * aValue, uint16_t aValueLength) +{ + rsError err = RS_ERROR_NONE; + uint16_t allocSize = (*pBuffer)->ramBufferMaxLen; + ramBufferDescriptor * ptr = NULL; + + if (allocSize <= (*pBuffer)->ramBufferLen + aValueLength) + { + while ((allocSize < (*pBuffer)->ramBufferLen + aValueLength)) + { + /* Need to realocate the memory buffer, increase size by kRamBufferReallocSize until NVM data fits */ + allocSize += kRamBufferReallocSize; + } + + allocSize += kRamDescHeaderSize; + + if (kRamBufferMaxAllocSize <= kRamBufferMaxAllocSize) + { + ptr = (ramBufferDescriptor *) realloc((void *) (*pBuffer), allocSize); + VerifyOrExit((NULL != ptr), err = RS_ERROR_NO_BUFS); + *pBuffer = ptr; + (*pBuffer)->ramBufferMaxLen = allocSize; + } + else + { + err = RS_ERROR_NO_BUFS; + } + } + + err = ramStorageSetInternal(*pBuffer, aKey, aValue, aValueLength); + +exit: + return err; +} + +rsError ramStorageDelete(ramBufferDescriptor * pBuffer, uint16_t aKey, int aIndex) +{ + uint16_t i = 0; + int currentIndex = 0; + uint16_t nextBlockStart = 0; + uint16_t currentBlockLength = 0; + struct settingsBlock currentBlock = { 0 }; + rsError error = RS_ERROR_NOT_FOUND; + + while (i < pBuffer->ramBufferLen) + { + memcpy(¤tBlock, &pBuffer->pRamBuffer[i], sizeof(settingsBlock)); + currentBlockLength = sizeof(settingsBlock) + currentBlock.length; + + if (aKey == currentBlock.key) + { + if (currentIndex == aIndex) + { + nextBlockStart = i + currentBlockLength; + + if (nextBlockStart < pBuffer->ramBufferLen) + { + memmove(&pBuffer->pRamBuffer[i], &pBuffer->pRamBuffer[nextBlockStart], pBuffer->ramBufferLen - nextBlockStart); + } + + VerifyOrDie(pBuffer->ramBufferLen >= currentBlockLength); + pBuffer->ramBufferLen -= currentBlockLength; + + error = RS_ERROR_NONE; + break; + } + else + { + currentIndex++; + } + } + + i += currentBlockLength; + } + RAM_STORAGE_PRINTF("key = %d err = %d", aKey, error); + return error; +} diff --git a/src/platform/nxp/k32w/k32w0/RamStorage.h b/src/platform/nxp/k32w/k32w0/RamStorage.h new file mode 100644 index 00000000000000..b1bc0ea3ad2ad6 --- /dev/null +++ b/src/platform/nxp/k32w/k32w0/RamStorage.h @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +typedef enum +{ + RS_ERROR_NONE, + RS_ERROR_NOT_FOUND, + RS_ERROR_NO_BUFS +} rsError; + +/* the structure used for keeping the records has the same structure both in RAM and in NVM: + * ramBufferLen | ramBufferMaxLen | settingsBlock | .... | settingsBlock + * + * ramBufferLen shows how much of the RAM buffer is currently occupied with settingsBlock structures + * ramBufferMaxLen shows the total malloc'ed size. Dynamic re-allocation is possible + */ +typedef struct +{ + uint16_t ramBufferLen; + uint16_t ramBufferMaxLen; + uint8_t pRamBuffer[1]; +} ramBufferDescriptor; + +struct settingsBlock +{ + uint16_t key; + uint16_t length; +} __attribute__((packed)); + +#define member_size(type, member) sizeof(((type *) 0)->member) + +constexpr size_t kRamDescHeaderSize = + member_size(ramBufferDescriptor, ramBufferLen) + member_size(ramBufferDescriptor, ramBufferMaxLen); + +/* Return a RAM buffer with initialSize and populated with the contents of NVM ID - if found in flash */ +ramBufferDescriptor * getRamBuffer(uint16_t nvmId, uint16_t initialSize); + +/* search pBuffer for aKey and return its value in aValue. aValueLength will contain the length of aValueLength */ +rsError ramStorageGet(const ramBufferDescriptor * pBuffer, uint16_t aKey, int aIndex, uint8_t * aValue, uint16_t * aValueLength); + +/* search pBuffer for aKey and set its value to aValue (having aValueLength length) */ +rsError ramStorageSet(ramBufferDescriptor ** pBuffer, uint16_t aKey, const uint8_t * aValue, uint16_t aValueLength); + +/* search pBuffer for aKey and delete it */ +rsError ramStorageDelete(ramBufferDescriptor * pBuffer, uint16_t aKey, int aIndex); diff --git a/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh b/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh index 324199c6db7f5a..6566feb72700bc 100755 --- a/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh +++ b/third_party/nxp/k32w0_sdk/sdk_fixes/patch_k32w_sdk.sh @@ -40,6 +40,9 @@ patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/Flash convert_to_dos "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/MemManager/Interface/MemManager.h patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/middleware/wireless/framework/MemManager/Interface -p1 <"$SOURCE_DIR/MemManager_h.patch" +#internal: THREADIP-3660 +patch -N --binary -d ./third_party/openthread/ot-nxp/src/k32w0/platform -p1 <"$SOURCE_DIR/settings_k32w_c.patch" + SIGN_FILE_PATH="$NXP_K32W061_SDK_ROOT"/tools/imagetool/sign_images.sh convert_to_dos "$SIGN_FILE_PATH" patch -N --binary -d "$NXP_K32W061_SDK_ROOT"/tools/imagetool/ -p1 <"$SOURCE_DIR/sign_images_sh.patch" diff --git a/third_party/nxp/k32w0_sdk/sdk_fixes/settings_k32w_c.patch b/third_party/nxp/k32w0_sdk/sdk_fixes/settings_k32w_c.patch new file mode 100644 index 00000000000000..08571a4d66b795 --- /dev/null +++ b/third_party/nxp/k32w0_sdk/sdk_fixes/settings_k32w_c.patch @@ -0,0 +1,11 @@ +--- a/settings_k32w.c ++++ b/settings_k32w.c +@@ -52,7 +52,7 @@ + #define NVM_START_ID 0x4F00 + + /* WARNING - the defines below must be in sync with OT NVM datasets from Settings.hpp */ +-#define NVM_MAX_ID 7 ++#define NVM_MAX_ID 20 + + static uint8_t sPdmBuffer[pdmBufferSize] __attribute__((aligned(4))) = {0}; +