Skip to content

Commit

Permalink
[Silabs] - Support for 917 SoC combined OTA upgrade (#30335)
Browse files Browse the repository at this point in the history
* Added OTA support for 917 SoC platform

* Added SIWX_917 macro for OTAConfig.cpp

* Addressed review comments

* Remove commented code

* Restyled by whitespace

* Restyled by clang-format

* Restyled by gn

* Added fix for NotifyupdateApplied command and TA alone image upgrade reset issue

* Modified config file as per slc_1.2

* Restyled by whitespace

* Restyled by clang-format

* Removed SLC file Specific changes

---------

Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: kirankha <kishor.rankhamb@silabs.com>
  • Loading branch information
3 people authored and pull[bot] committed Apr 11, 2024
1 parent 682e255 commit fd71add
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 56 deletions.
12 changes: 11 additions & 1 deletion examples/platform/silabs/OTAConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@
*/

#include "OTAConfig.h"
#include <app/server/Server.h>

#ifndef SIWX_917

#include "application_properties.h"
#include <app/server/Server.h>

#if defined(SL_COMPONENT_CATALOG_PRESENT)
#include "sl_component_catalog.h"
#endif

// Only include app properties if the Gecko SDK component that does it automatically isn't present
#if !defined(SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT)
// Header used for building the image GBL file
#define APP_PROPERTIES_VERSION 1
#define APP_PROPERTIES_ID \
Expand Down Expand Up @@ -65,6 +73,8 @@ __attribute__((used)) ApplicationProperties_t sl_app_properties = {
/// Pointer to Long Token Data Section
.longTokenSectionAddress = NULL,
};
#endif // SL_CATALOG_GECKO_BOOTLOADER_INTERFACE_PRESENT
#endif // SIWX_917

// Global OTA objects
chip::DefaultOTARequestor gRequestorCore;
Expand Down
9 changes: 4 additions & 5 deletions examples/platform/silabs/SiWx917/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,9 @@ config("siwx917-common-config") {
defines += [ "QR_CODE_ENABLED" ]
}

# TODO: Renable once ota is supported
# if (chip_enable_ota_requestor) {
# defines += [ "SILABS_OTA_ENABLED" ]
# }
if (chip_enable_ota_requestor) {
defines += [ "SILABS_OTA_ENABLED" ]
}

if (enable_heap_monitoring) {
defines += [ "HEAP_MONITORING" ]
Expand Down Expand Up @@ -229,7 +228,7 @@ source_set("siwx917-common") {
}

if (chip_enable_ota_requestor) {
# TODO: OTA For CCP Platform
sources += [ "${silabs_common_plat_dir}/OTAConfig.cpp" ]
}

if (!disable_lcd) {
Expand Down
10 changes: 10 additions & 0 deletions examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,16 @@ static sl_status_t wfx_rsi_init(void)
return status;
}
#endif

sl_wifi_version_string_t version = { 0 };
status = sl_wifi_get_firmware_version(&version);
if (status != SL_STATUS_OK)
{
SILABS_LOG("Get fw version failed: %s", version.version);
return status;
}
SILABS_LOG("Get current fw version: %s", version.version);

status = sl_wifi_get_mac_address(SL_WIFI_CLIENT_INTERFACE, (sl_mac_address_t *) &wfx_rsi.sta_mac.octet[0]);
if (status != SL_STATUS_OK)
{
Expand Down
1 change: 1 addition & 0 deletions src/platform/silabs/OTAImageProcessorImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4)));
// Offset indicates how far the write buffer has been filled
static uint16_t writeBufOffset;
static bool mReset;
};

} // namespace chip
5 changes: 2 additions & 3 deletions src/platform/silabs/SiWx917/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,10 @@ static_library("SiWx917") {
"PlatformManagerImpl.cpp",
]

# TODO: OTA on CCP platform
if (chip_enable_ota_requestor) {
sources += [
#"OTAImageProcessorImpl.cpp",
#"${silabs_platform_dir}/OTAImageProcessorImpl.h",
"${silabs_platform_dir}/OTAImageProcessorImpl.h",
"OTAImageProcessorImpl.cpp",
]
}

Expand Down
113 changes: 66 additions & 47 deletions src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,30 @@
#include <app/clusters/ota-requestor/OTARequestorInterface.h>
#include <platform/silabs/OTAImageProcessorImpl.h>

#include <platform/silabs/SilabsConfig.h>

#ifdef __cplusplus
extern "C" {
#include "btl_interface.h"
#include "em_bus.h" // For CORE_CRITICAL_SECTION
#endif
#include "sl_si91x_driver.h"
#ifdef RSI_M4_INTERFACE
#include "sl_si91x_hal_soc_soft_reset.h"
#endif
#ifdef __cplusplus
}
#endif

#include <platform/silabs/SilabsConfig.h>

#define RPS_HEADER 1
#define RPS_DATA 2
/// No error, operation OK
#define SL_BOOTLOADER_OK 0L
#define SL_STATUS_FW_UPDATE_DONE SL_STATUS_SI91X_NO_AP_FOUND
uint8_t flag = RPS_HEADER;

namespace chip {

// Define static memebers
bool OTAImageProcessorImpl::mReset = false;
uint8_t OTAImageProcessorImpl::mSlotId = 0;
uint32_t OTAImageProcessorImpl::mWriteOffset = 0;
uint16_t OTAImageProcessorImpl::writeBufOffset = 0;
Expand Down Expand Up @@ -129,7 +140,7 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)

ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload");

CORE_CRITICAL_SECTION(bootloader_init();)
mReset = false;
mSlotId = 0; // Single slot until we support multiple images
writeBufOffset = 0;
mWriteOffset = 0;
Expand All @@ -139,39 +150,39 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)

// Not calling bootloader_eraseStorageSlot(mSlotId) here because we erase during each write

imageProcessor->mDownloader->OnPreparedForDownload(err == SL_BOOTLOADER_OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL);
imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR);
}

void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
{
uint32_t err = SL_BOOTLOADER_OK;
int32_t status = 0;
auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
if (imageProcessor == nullptr)
{
return;
}

// Pad the remainder of the write buffer with zeros and write it to bootloader storage
if (writeBufOffset != 0)
{
// Account for last bytes of the image not yet written to storage
imageProcessor->mParams.downloadedBytes += writeBufOffset;
status = sl_si91x_fwup_load(writeBuffer, writeBufOffset);
ChipLogProgress(SoftwareUpdate, "status: 0x%lX", status);

while (writeBufOffset != kAlignmentBytes)
{
writeBuffer[writeBufOffset] = 0;
writeBufOffset++;
}

CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);)
if (err)
if (status != SL_STATUS_OK)
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize bootloader_eraseWriteStorage() error %ld", err);
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
if (status == SL_STATUS_FW_UPDATE_DONE)
{
mReset = true;
}
else
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status);
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
}
}
}

imageProcessor->ReleaseBlock();

ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully");
Expand All @@ -186,28 +197,16 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
// Force KVS to store pending keys such as data from StoreCurrentUpdateInfo()
chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().ForceKeyMapSave();

CORE_CRITICAL_SECTION(err = bootloader_verifyImage(mSlotId, NULL);)
if (err != SL_BOOTLOADER_OK)
{
ChipLogError(SoftwareUpdate, "ERROR: bootloader_verifyImage() error %ld", err);
// Call the OTARequestor API to reset the state
GetRequestorInstance()->CancelImageUpdate();
ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleApply");

return;
}

CORE_CRITICAL_SECTION(err = bootloader_setImageToBootload(mSlotId);)
if (err != SL_BOOTLOADER_OK)
if (mReset)
{
ChipLogError(SoftwareUpdate, "ERROR: bootloader_setImageToBootload() error %ld", err);
// Call the OTARequestor API to reset the state
GetRequestorInstance()->CancelImageUpdate();

return;
ChipLogProgress(SoftwareUpdate, "M4 Firmware update complete");
// send system reset request to reset the MCU and upgrade the m4 image
ChipLogProgress(SoftwareUpdate, "SoC Soft Reset initiated!");
// Reboots the device
sl_si91x_soc_soft_reset();
}

// This reboots the device
CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();)
}

void OTAImageProcessorImpl::HandleAbort(intptr_t context)
Expand All @@ -225,6 +224,8 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context)
void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
{
uint32_t err = SL_BOOTLOADER_OK;
int32_t status = 0;
int32_t content_block = 0;
auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
if (imageProcessor == nullptr)
{
Expand Down Expand Up @@ -258,19 +259,37 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
if (writeBufOffset == kAlignmentBytes)
{
writeBufOffset = 0;

CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);)
if (err)
if (flag == RPS_HEADER)
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock bootloader_eraseWriteStorage() error %ld", err);
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
// Send RPS header which is received as first chunk
status = sl_si91x_fwup_start(writeBuffer);
status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes);
flag = RPS_DATA;
}
mWriteOffset += kAlignmentBytes;
else if (flag == RPS_DATA)
{
// Send RPS content
status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes);
if (status != SL_STATUS_OK)
{
// If the last chunk of last block-writeBufOffset length is exactly kAlignmentBytes(64) bytes then mReset value
// should be set to true in HandleProcessBlock
if (status == SL_STATUS_FW_UPDATE_DONE)
{
mReset = true;
}
else
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk rsi_fwup() error %ld", status);
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
}
}
}
// ChipLogProgress(SoftwareUpdate, "HandleProcessBlock status: 0x%lX", status);
imageProcessor->mParams.downloadedBytes += kAlignmentBytes;
}
}

imageProcessor->mDownloader->FetchNextData();
}

Expand Down
10 changes: 10 additions & 0 deletions third_party/silabs/SiWx917_sdk.gni
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,11 @@ template("siwx917_sdk") {

"${efr32_sdk_root}/platform/service/iostream/inc",
"${wifi_sdk_root}/components/siwx917_soc/drivers/hardware_drivers/button/inc",

# OTA
"${wifi_sdk_root}/components/si91x/sl_net/protocols/firmware_upgrade",
"${wifi_sdk_root}/components/siwx917_soc/hal/inc",
"${wifi_sdk_root}/components/siwx917_soc/drivers/systemlevel/inc",
]

if (silabs_board == "BRD4338A") {
Expand Down Expand Up @@ -452,6 +457,11 @@ template("siwx917_sdk") {
"${sdk_support_root}/matter/mbedtls/tinycrypt/src/x509write_csr.c",
"${sdk_support_root}/matter/si91x/siwx917/${sdk_support_board}/autogen/sl_si91x_button_instances.c",
"${wifi_sdk_root}/components/siwx917_soc/drivers/hardware_drivers/button/src/sl_si91x_button.c",

# OTA
"${wifi_sdk_root}/components/si91x/sl_net/protocols/firmware_upgrade/firmware_upgradation.c",
"${wifi_sdk_root}/components/siwx917_soc/drivers/systemlevel/src/rsi_wwdt.c",
"${wifi_sdk_root}/components/siwx917_soc/hal/src/sl_si91x_hal_soc_soft_reset.c",
]

# nvm3 ans startup
Expand Down

0 comments on commit fd71add

Please sign in to comment.