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

[Silabs] - Support for 917 SoC combined OTA upgrade #30335

Merged
Show file tree
Hide file tree
Changes from all 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
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)
selissia marked this conversation as resolved.
Show resolved Hide resolved
// 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
Loading