Skip to content

Commit ade93ac

Browse files
[Silabs]Bring nvm init and Migration sooner. Use memory allocation and cleanu… (#41155)
* Bring nvm init and Migration sooner. Use memory allocation and cleanup code * Apply suggestions from code review Co-authored-by: Copilot <[email protected]> * address comments * fixup copy paste mistake --------- Co-authored-by: Copilot <[email protected]>
1 parent 546f646 commit ade93ac

File tree

8 files changed

+61
-26
lines changed

8 files changed

+61
-26
lines changed

examples/platform/silabs/MatterConfig.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,14 @@ void ApplicationStart(void * unused)
205205

206206
void SilabsMatterConfig::AppInit()
207207
{
208+
#ifdef SL_WIFI
209+
// Init Chip memory management before the stack for Wi-Fi platforms
210+
// Because OpenThread needs to use memory allocation during its Key operations, we initialize the memory management for thread
211+
// and set the allocation functions inside sl_ot_create_instance, which is called earlier by sl_system_init.
212+
mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree);
213+
VerifyOrDie(chip::Platform::MemoryInit() == CHIP_NO_ERROR);
214+
#endif // SL_WIFI
215+
208216
GetPlatform().Init();
209217
sMainTaskHandle = osThreadNew(ApplicationStart, nullptr, &kMainTaskAttr);
210218
ChipLogProgress(DeviceLayer, "Starting scheduler");
@@ -243,12 +251,10 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName)
243251
ChipLogProgress(DeviceLayer, "Init CHIP Stack");
244252

245253
#ifdef SL_WIFI
246-
// Init Chip memory management before the stack
247-
// Because OpenThread needs to use memory allocation during its Key operations, we initialize the memory management for thread
248-
// and set the allocation functions inside sl_ot_create_instance, which is called earlier by sl_system_init.
249-
mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree);
250-
ReturnErrorOnFailure(chip::Platform::MemoryInit());
251254
ReturnErrorOnFailure(WifiInterface::GetInstance().InitWiFiStack());
255+
// Needs to be done post InitWifiStack for 917.
256+
// TODO move it in InitWiFiStack
257+
GetPlatform().NvmInit();
252258

253259
#if CHIP_CONFIG_ENABLE_ICD_SERVER
254260
ReturnErrorOnFailure(WifiSleepManager::GetInstance().Init(&WifiInterface::GetInstance(), &WifiInterface::GetInstance()));

src/platform/silabs/KeyValueStoreManagerImpl.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "MigrationManager.h"
2525
#include <cmsis_os2.h>
2626
#include <crypto/CHIPCryptoPAL.h>
27+
#include <lib/support/ScopedBuffer.h>
2728
#include <platform/CHIPDeviceLayer.h>
2829
#include <platform/KeyValueStoreManager.h>
2930
#include <platform/silabs/SilabsConfig.h>
@@ -51,10 +52,6 @@ KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance;
5152

5253
CHIP_ERROR KeyValueStoreManagerImpl::Init(void)
5354
{
54-
ReturnErrorOnFailure(SilabsConfig::Init());
55-
56-
Silabs::MigrationManager::GetMigrationInstance().applyMigrations();
57-
5855
memset(mKvsKeyMap, 0, sizeof(mKvsKeyMap));
5956
size_t outLen = 0;
6057
CHIP_ERROR error = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_KvsStringKeyMap,
@@ -275,33 +272,42 @@ void KeyValueStoreManagerImpl::ErasePartition(void)
275272

276273
void KeyValueStoreManagerImpl::KvsMapMigration(void)
277274
{
278-
size_t readlen = 0;
279-
constexpr uint8_t oldMaxEntires = 120;
280-
char mKvsStoredKeyString[oldMaxEntires][PersistentStorageDelegate::kKeyLengthMax + 1] = { 0 };
281-
CHIP_ERROR err =
282-
SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_KvsStringKeyMap, reinterpret_cast<uint8_t *>(mKvsStoredKeyString),
283-
sizeof(mKvsStoredKeyString), readlen);
275+
// this migration precedes Series 3, we don't need to run it in that case
276+
#ifndef _SILICON_LABS_32B_SERIES_3
277+
size_t readlen = 0;
278+
constexpr size_t oldMaxEntries = 120;
279+
constexpr uint32_t maxStringLen = 33; // value of PersistentStorageDelegate::kKeyLengthMax + 1 when migration was added
280+
Platform::ScopedMemoryBuffer<char> mKvsStoredKeyString;
281+
mKvsStoredKeyString.Alloc(oldMaxEntries * maxStringLen);
282+
283+
VerifyOrReturn(mKvsStoredKeyString.Get() != nullptr);
284+
285+
CHIP_ERROR err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_KvsStringKeyMap,
286+
reinterpret_cast<uint8_t *>(mKvsStoredKeyString.Get()),
287+
oldMaxEntries * maxStringLen, readlen);
284288

285289
if (err == CHIP_NO_ERROR)
286290
{
287-
for (uint8_t i = 0; i < oldMaxEntires; i++)
291+
// Migrate the old String Based KvsKeyMap to the Hash based KvsKeyMap
292+
for (size_t i = 0; i < std::min(oldMaxEntries, KeyValueStoreManagerImpl::kMaxEntries); i++)
288293
{
289-
if (mKvsStoredKeyString[i][0] != 0)
294+
char * keyString = mKvsStoredKeyString.Get() + (i * maxStringLen);
295+
if (keyString[0] != 0)
290296
{
291297
size_t dataLen = 0;
292298
uint32_t nvm3Key = CONVERT_KEYMAP_INDEX_TO_NVM3KEY(i);
293299

294300
if (SilabsConfig::ConfigValueExists(nvm3Key, dataLen))
295301
{
296302
// Read old data and prefix it with the string Key for the collision prevention mechanism.
297-
size_t keyStringLen = strlen(mKvsStoredKeyString[i]);
303+
size_t keyStringLen = strlen(keyString);
298304
uint8_t * prefixedData = static_cast<uint8_t *>(Platform::MemoryAlloc(keyStringLen + dataLen));
299305
VerifyOrDie(prefixedData != nullptr);
300-
memcpy(prefixedData, mKvsStoredKeyString[i], keyStringLen);
306+
memcpy(prefixedData, keyString, keyStringLen);
301307

302308
SilabsConfig::ReadConfigValueBin(nvm3Key, prefixedData + keyStringLen, dataLen, readlen);
303309
SilabsConfig::WriteConfigValueBin(nvm3Key, prefixedData, keyStringLen + dataLen);
304-
mKvsKeyMap[i] = KeyValueStoreMgrImpl().hashKvsKeyString(mKvsStoredKeyString[i]);
310+
mKvsKeyMap[i] = KeyValueStoreMgrImpl().hashKvsKeyString(keyString);
305311
Platform::MemoryFree(prefixedData);
306312
}
307313
}
@@ -315,6 +321,7 @@ void KeyValueStoreManagerImpl::KvsMapMigration(void)
315321
// start with a fresh kvs section.
316322
KeyValueStoreMgrImpl().ErasePartition();
317323
}
324+
#endif
318325
}
319326

320327
void KeyValueStoreManagerImpl::KvsKeyMapCleanup(void * argument)

src/platform/silabs/MigrationManager.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@
1616
*/
1717

1818
#include "MigrationManager.h"
19+
#include "sl_component_catalog.h"
20+
#include "sl_core.h"
21+
#include <headers/ProvisionManager.h>
22+
#include <headers/ProvisionStorage.h>
23+
#include <lib/support/CodeUtils.h>
24+
#include <lib/support/ScopedBuffer.h>
25+
#include <lib/support/Span.h>
1926
#include <platform/CHIPDeviceLayer.h>
2027
#include <platform/silabs/SilabsConfig.h>
2128
#include <stdio.h>
@@ -35,7 +42,6 @@ typedef struct
3542
func_ptr migrationFunc;
3643
} migrationData_t;
3744

38-
#define COUNT_OF(A) (sizeof(A) / sizeof((A)[0]))
3945
static migrationData_t migrationTable[] = {
4046
{ .migrationGroup = 1, .migrationFunc = MigrateKvsMap },
4147
{ .migrationGroup = 2, .migrationFunc = MigrateDacProvider },
@@ -47,13 +53,13 @@ static migrationData_t migrationTable[] = {
4753

4854
} // namespace
4955

50-
void MigrationManager::applyMigrations()
56+
void MigrationManager::ApplyMigrations()
5157
{
5258
uint32_t lastMigationGroupDone = 0;
5359
SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_MigrationCounter, lastMigationGroupDone);
5460

5561
uint32_t completedMigrationGroup = lastMigationGroupDone;
56-
for (uint32_t i = 0; i < COUNT_OF(migrationTable); i++)
62+
for (uint32_t i = 0; i < MATTER_ARRAY_SIZE(migrationTable); i++)
5763
{
5864
if (lastMigationGroupDone < migrationTable[i].migrationGroup)
5965
{
@@ -67,7 +73,7 @@ void MigrationManager::applyMigrations()
6773
void MigrationManager::MigrateUint16(uint32_t old_key, uint32_t new_key)
6874
{
6975
uint16_t value = 0;
70-
if (SilabsConfig::ConfigValueExists(old_key) && (CHIP_NO_ERROR == SilabsConfig::ReadConfigValue(old_key, value)))
76+
if (CHIP_NO_ERROR == SilabsConfig::ReadConfigValue(old_key, value))
7177
{
7278
if (CHIP_NO_ERROR == SilabsConfig::WriteConfigValue(new_key, value))
7379
{
@@ -80,7 +86,7 @@ void MigrationManager::MigrateUint16(uint32_t old_key, uint32_t new_key)
8086
void MigrationManager::MigrateUint32(uint32_t old_key, uint32_t new_key)
8187
{
8288
uint32_t value = 0;
83-
if (SilabsConfig::ConfigValueExists(old_key) && (CHIP_NO_ERROR == SilabsConfig::ReadConfigValue(old_key, value)))
89+
if (CHIP_NO_ERROR == SilabsConfig::ReadConfigValue(old_key, value))
8490
{
8591
if (CHIP_NO_ERROR == SilabsConfig::WriteConfigValue(new_key, value))
8692
{

src/platform/silabs/MigrationManager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class MigrationManager
3030
* User should get the object from this getter.
3131
*/
3232
static MigrationManager & GetMigrationInstance();
33-
static void applyMigrations();
33+
static void ApplyMigrations();
3434
static void MigrateUint16(uint32_t old_key, uint32_t new_key);
3535
static void MigrateUint32(uint32_t old_key, uint32_t new_key);
3636

src/platform/silabs/platformAbstraction/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ source_set("common") {
2323
"${chip_root}/src/platform/silabs/platformAbstraction/SilabsPlatform.h",
2424
"${chip_root}/src/platform/silabs/platformAbstraction/SilabsPlatformBase.h",
2525
]
26+
27+
include_dirs = [ "${chip_root}/src/platform/silabs" ]
2628
public_deps = [
2729
"${chip_root}/src/app/icd/server:icd-server-config",
2830
"${chip_root}/src/lib/core",

src/platform/silabs/platformAbstraction/GsdkSpam.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ SilabsPlatform::SilabsButtonCb SilabsPlatform::mButtonCallback = nullptr;
9696

9797
CHIP_ERROR SilabsPlatform::Init(void)
9898
{
99+
NvmInit();
99100
#ifdef _SILICON_LABS_32B_SERIES_2
100101
// Read the cause of last reset.
101102
mRebootCause = RMU_ResetCauseGet();

src/platform/silabs/platformAbstraction/SilabsPlatform.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <lib/support/CodeUtils.h>
2121
#include <platform/DiagnosticDataProvider.h>
22+
#include <platform/silabs/MigrationManager.h>
2223
#include <platform/silabs/SilabsConfig.h>
2324
#include <platform/silabs/platformAbstraction/SilabsPlatform.h>
2425

@@ -41,6 +42,13 @@ CHIP_ERROR SilabsPlatform::VerifyIfUpdated()
4142
return CHIP_NO_ERROR;
4243
}
4344

45+
CHIP_ERROR SilabsPlatform::NvmInit()
46+
{
47+
ReturnErrorOnFailure(Internal::SilabsConfig::Init());
48+
Silabs::MigrationManager::GetMigrationInstance().ApplyMigrations();
49+
return CHIP_NO_ERROR;
50+
}
51+
4452
} // namespace Silabs
4553
} // namespace DeviceLayer
4654
} // namespace chip

src/platform/silabs/platformAbstraction/SilabsPlatform.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ class SilabsPlatform : virtual public SilabsPlatformAbstractionBase
8080
*/
8181
CHIP_ERROR VerifyIfUpdated();
8282

83+
/**
84+
* @brief Initialize the nvm driver (e.g., NVM3), and execute any needed migrations.
85+
*/
86+
CHIP_ERROR NvmInit();
87+
8388
private:
8489
friend SilabsPlatform & GetPlatform(void);
8590

0 commit comments

Comments
 (0)