Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SL-UP] Add OTA Support for series3 #94

Merged
merged 4 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions src/platform/silabs/CHIPDevicePlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,7 @@
#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE

#ifndef CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE
#if defined(EFR32MG21)
#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE (2 * 1024)
#else
#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE (8 * 1024)
#endif
#endif // CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE

#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY 0
Expand Down
2 changes: 2 additions & 0 deletions src/platform/silabs/OTAImageProcessorImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
static void HandleApply(intptr_t context);
static void HandleAbort(intptr_t context);
static void HandleProcessBlock(intptr_t context);
static void LockRadioProcessing();
static void UnlockRadioProcessing();
CHIP_ERROR ProcessHeader(ByteSpan & block);

/**
Expand Down
69 changes: 59 additions & 10 deletions src/platform/silabs/efr32/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ extern "C" {

#include <platform/silabs/SilabsConfig.h>

#ifdef _SILICON_LABS_32B_SERIES_2
// Series 2 bootloader_ api calls must be called from a critical section context for thread safeness
#define WRAP_BL_DFU_CALL(code) \
{ \
CORE_CRITICAL_SECTION(code;) \
}
#else
// series 3 bootloader_ calls use rtos mutex for thread safeness. Cannot be callsed withing a critical sectionß
#define WRAP_BL_DFU_CALL(code) \
{ \
code; \
}
#endif

/// No error, operation OK
#define SL_BOOTLOADER_OK 0L

Expand Down Expand Up @@ -144,7 +158,15 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)

ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload: started");

CORE_CRITICAL_SECTION(bootloader_init();)
#ifdef _SILICON_LABS_32B_SERIES_2
// TODO sl-temp: bootloader_init is called previously sl_platform_init(). Recalling it for series3 causes a crash.
WRAP_BL_DFU_CALL(err = bootloader_init())
if (err != SL_BOOTLOADER_OK)
{
ChipLogProgress(SoftwareUpdate, "bootloader_init Failed error: %ld", err);
}
#endif

mSlotId = 0; // Single slot until we support multiple images
writeBufOffset = 0;
mWriteOffset = 0;
Expand Down Expand Up @@ -186,7 +208,8 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
return;
}
#endif // SL_BTLCTRL_MUX
CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);)
WRAP_BL_DFU_CALL(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes))

#if SL_BTLCTRL_MUX
err = sl_wfx_host_post_bootloader_spi_transfer();
if (err != SL_STATUS_OK)
Expand All @@ -208,11 +231,27 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully");
}

// TODO SE access is not thread safe. Assert if Other task acess it during bootloader_verifyImage or bootloader_setImageToBootload
// steps - MATTER-4155 - PLATFORM_HYD-3235
void OTAImageProcessorImpl::LockRadioProcessing()
{
#if !SL_WIFI
DeviceLayer::ThreadStackMgr().LockThreadStack();
#endif // SL_WIFI
}

void OTAImageProcessorImpl::UnlockRadioProcessing()
{
#if !SL_WIFI
DeviceLayer::ThreadStackMgr().UnlockThreadStack();
#endif // SL_WIFI
}

void OTAImageProcessorImpl::HandleApply(intptr_t context)
{
uint32_t err = SL_BOOTLOADER_OK;

ChipLogProgress(SoftwareUpdate, "HandleApply: started");
ChipLogProgress(SoftwareUpdate, "HandleApply: verifying image");

// Force KVS to store pending keys such as data from StoreCurrentUpdateInfo()
chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().ForceKeyMapSave();
Expand All @@ -224,7 +263,11 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
return;
}
#endif // SL_BTLCTRL_MUX
CORE_CRITICAL_SECTION(err = bootloader_verifyImage(mSlotId, NULL);)

osDelay(100); // sl-temp: delay for uart print before verifyImage
LockRadioProcessing();
WRAP_BL_DFU_CALL(err = bootloader_verifyImage(mSlotId, NULL))
UnlockRadioProcessing();
if (err != SL_BOOTLOADER_OK)
{
ChipLogError(SoftwareUpdate, "bootloader_verifyImage() error: %ld", err);
Expand All @@ -235,13 +278,14 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
if (err != SL_STATUS_OK)
{
ChipLogError(SoftwareUpdate, "sl_wfx_host_post_bootloader_spi_transfer() error: %ld", err);
return;
}
#endif // SL_BTLCTRL_MUX
return;
}

CORE_CRITICAL_SECTION(err = bootloader_setImageToBootload(mSlotId);)
ChipLogError(SoftwareUpdate, "Image verified, Set image to bootloader");
LockRadioProcessing();
WRAP_BL_DFU_CALL(err = bootloader_setImageToBootload(mSlotId))
UnlockRadioProcessing();
if (err != SL_BOOTLOADER_OK)
{
ChipLogError(SoftwareUpdate, "bootloader_setImageToBootload() error: %ld", err);
Expand All @@ -252,7 +296,6 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
if (err != SL_STATUS_OK)
{
ChipLogError(SoftwareUpdate, "sl_wfx_host_post_bootloader_spi_transfer() error: %ld", err);
return;
}
#endif // SL_BTLCTRL_MUX
return;
Expand All @@ -266,8 +309,13 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
return;
}
#endif // SL_BTLCTRL_MUX

ChipLogError(SoftwareUpdate, "Reboot and install new image...");
osDelay(100); // sl-temp: delay for uart print before reboot
LockRadioProcessing();
// This reboots the device
CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();)
WRAP_BL_DFU_CALL(bootloader_rebootAndInstall())
UnlockRadioProcessing(); // Unneccessay but for good measure
}

void OTAImageProcessorImpl::HandleAbort(intptr_t context)
Expand Down Expand Up @@ -326,7 +374,8 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
return;
}
#endif // SL_BTLCTRL_MUX
CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);)
WRAP_BL_DFU_CALL(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes))

#if SL_BTLCTRL_MUX
err = sl_wfx_host_post_bootloader_spi_transfer();
if (err != SL_STATUS_OK)
Expand Down
Loading