Skip to content

Commit

Permalink
Added OTA support for 917 SoC platform
Browse files Browse the repository at this point in the history
  • Loading branch information
bhmanda-silabs committed Nov 8, 2023
1 parent 155917e commit 8a88399
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 61 deletions.
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
4 changes: 2 additions & 2 deletions src/platform/silabs/SiWx917/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ static_library("SiWx917") {
# TODO: OTA on CCP platform
if (chip_enable_ota_requestor) {
sources += [
#"OTAImageProcessorImpl.cpp",
#"${silabs_platform_dir}/OTAImageProcessorImpl.h",
"OTAImageProcessorImpl.cpp",
"${silabs_platform_dir}/OTAImageProcessorImpl.h",
]
}

Expand Down
143 changes: 89 additions & 54 deletions src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,29 @@
#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_t)0x10003)
uint8_t flag = RPS_HEADER;
uint8_t last = 0;
uint8_t length = 0;
uint32_t total_size = 0;
uint32_t count = 0;
namespace chip {

// Define static memebers
Expand Down Expand Up @@ -129,7 +142,6 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)

ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload");

CORE_CRITICAL_SECTION(bootloader_init();)
mSlotId = 0; // Single slot until we support multiple images
writeBufOffset = 0;
mWriteOffset = 0;
Expand All @@ -139,42 +151,54 @@ 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;
}

if(last == 1)
{
ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleFinalize");
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;

while (writeBufOffset != kAlignmentBytes)
{
writeBuffer[writeBufOffset] = 0;
writeBufOffset++;
// Send RPS header which is received as first chunk
count = count + writeBufOffset;
if(count >= total_size) {
writeBufOffset = writeBufOffset - (count - total_size);
last=1;
}

CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);)
if (err)
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize bootloader_eraseWriteStorage() error %ld", err);
status = sl_si91x_fwup_load(writeBuffer, writeBufOffset);
ChipLogProgress(SoftwareUpdate, "status: 0x%lX", status);

if (status != 0) {
if (status == SL_STATUS_FW_UPDATE_DONE) {
ChipLogProgress(SoftwareUpdate,"M4 Firmware update complete");
osDelay(5000);
// send system reset request to reset the MCU and upgrade the m4 image
ChipLogProgress(SoftwareUpdate,"SoC Soft Reset initiated!");
sl_si91x_soc_soft_reset();
} 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");
ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleFinalize");
}

void OTAImageProcessorImpl::HandleApply(intptr_t context)
Expand All @@ -186,28 +210,7 @@ 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();

return;
}

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

return;
}

// This reboots the device
CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();)
ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleApply");
}

void OTAImageProcessorImpl::HandleAbort(intptr_t context)
Expand All @@ -225,6 +228,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 All @@ -250,6 +255,7 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
// Copy data into the word-aligned writeBuffer, once it fills write its contents to the bootloader storage
// Final data block is handled in HandleFinalize().
uint32_t blockReadOffset = 0;

while (blockReadOffset < block.size())
{
writeBuffer[writeBufOffset] = *((block.data()) + blockReadOffset);
Expand All @@ -258,20 +264,49 @@ 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);
total_size = imageProcessor->mParams.totalFileBytes;
count = count + kAlignmentBytes;
flag = RPS_DATA;
}
mWriteOffset += kAlignmentBytes;
imageProcessor->mParams.downloadedBytes += kAlignmentBytes;
}
}

imageProcessor->mDownloader->FetchNextData();
else if(flag == RPS_DATA)
{
// Send RPS content
count = count + kAlignmentBytes;
if(count >= total_size)
{
length = kAlignmentBytes - (count - total_size);
last = 1;
}
else
{
length = kAlignmentBytes;
}
status = sl_si91x_fwup_load(writeBuffer, length);
if (status != 0) {
ChipLogProgress(SoftwareUpdate, "status: 0x%lX", status);
if (status == SL_STATUS_FW_UPDATE_DONE) {
ChipLogProgress(SoftwareUpdate, "M4 Firmware update complete");
// send system reset request to reset the MCU and upgrade the m4 image
osDelay(5000);
sl_si91x_soc_soft_reset();
}
else
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock for middle chunk sl_si91x_fwup_load() error %ld", status);
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
}
}
}
imageProcessor->mParams.downloadedBytes += kAlignmentBytes;
}
}
imageProcessor->mDownloader->FetchNextData();
}

CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block)
Expand Down
11 changes: 11 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,12 @@ 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/hal/src/sl_si91x_hal_soc_soft_reset.c",
"${wifi_sdk_root}/components/siwx917_soc/drivers/systemlevel/src/rsi_wwdt.c",
]

# nvm3 ans startup
Expand Down

0 comments on commit 8a88399

Please sign in to comment.