Skip to content

Commit 94e8197

Browse files
selissiakowsisoundhar12carol-applebzbarsky-appleDamian-Nordic
authored
[EFR32] OTA: Use word-aligned buffer in bootloader storage APIs (#17281)
* Test added march 8 (#15957) * Added new manual scripts * Added Auto generated File * [OTA] Fix OTARequestorDriverImpl inclusion (#15981) * Regen to fix CI failures (#15990) * [ota] Store Default OTA Providers in flash (#15970) * [ota] Store Default OTA Providers in flash Store Default OTA Providers in flash each time the attribute is modified and load it back on the application startup. * Restyled by clang-format * Fix build and reduce flash usage Co-authored-by: Restyled.io <commits@restyled.io> * Use an intermediate buffer for writing the image to the booloader storage * Use critical section in the bootloader API call * Cleanup log messages, move variables into a class * Remove merge artifacts * Update EFR32 documentation * Fix typo * Restyled by whitespace * Restyled by clang-format * Restyled by prettier-markdown * Rename array size parameter, add aligned attribute * Trivial change to restart the CI (restyle job need to be kicked) * Restyled by clang-format * Update comments Co-authored-by: kowsisoundhar12 <57476670+kowsisoundhar12@users.noreply.github.com> Co-authored-by: Carol Yang <clyang@apple.com> Co-authored-by: Boris Zbarsky <bzbarsky@apple.com> Co-authored-by: Damian Królik <66667989+Damian-Nordic@users.noreply.github.com> Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 184bda1 commit 94e8197

File tree

3 files changed

+74
-20
lines changed

3 files changed

+74
-20
lines changed

docs/guides/silabs_efr32_software_update.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,12 @@ all of the EFR32 example applications.
1818
scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/debug chip_config_network_layer_ble=false
1919

2020
- Build or download the Gecko Bootloader binary. Bootloader should be built
21-
with the Gecko SDK version 3.2.1 or earlier, type "external SPI" configured
22-
with a single slot of at least 1000 KB. Pre-built binaries should be
21+
with the Gecko SDK version 3.2.1 or earlier. For the bootloader using the
22+
external flash select the "external SPI" bootloader type configured with a
23+
single slot of at least 1000 KB. For the bootloader using the internal flash
24+
(supported on MG24 boards only) select the "internal storage" bootloader
25+
type. Follow the instructions in "UG266: Silicon Labs Gecko Bootloader
26+
User’s Guide". Pre-built binaries for some configurations should be
2327
available in
2428

2529
third_party/efr32_sdk/repo/platform/bootloader/sample-apps/bootloader-storage-spiflash-single

src/platform/EFR32/OTAImageProcessorImpl.cpp

+59-17
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
extern "C" {
2323
#include "platform/bootloader/api/btl_interface.h"
24+
#include "platform/emlib/inc/em_bus.h" // For CORE_CRITICAL_SECTION
2425
}
2526

2627
/// No error, operation OK
@@ -29,8 +30,10 @@ extern "C" {
2930
namespace chip {
3031

3132
// Define static memebers
32-
uint8_t OTAImageProcessorImpl::mSlotId;
33-
uint32_t OTAImageProcessorImpl::mWriteOffset;
33+
uint8_t OTAImageProcessorImpl::mSlotId = 0;
34+
uint32_t OTAImageProcessorImpl::mWriteOffset = 0;
35+
uint16_t OTAImageProcessorImpl::writeBufOffset = 0;
36+
uint8_t OTAImageProcessorImpl::writeBuffer[kAlignmentBytes] __attribute__((aligned(4))) = { 0 };
3437

3538
CHIP_ERROR OTAImageProcessorImpl::PrepareDownload()
3639
{
@@ -89,9 +92,13 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)
8992
return;
9093
}
9194

92-
bootloader_init();
93-
mSlotId = 0; // Single slot until we support multiple images
94-
mWriteOffset = 0;
95+
ChipLogProgress(SoftwareUpdate, "HandlePrepareDownload");
96+
97+
CORE_CRITICAL_SECTION(bootloader_init();)
98+
mSlotId = 0; // Single slot until we support multiple images
99+
writeBufOffset = 0;
100+
mWriteOffset = 0;
101+
imageProcessor->mParams.downloadedBytes = 0;
95102

96103
imageProcessor->mHeaderParser.Init();
97104

@@ -102,12 +109,34 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)
102109

103110
void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
104111
{
112+
uint32_t err = SL_BOOTLOADER_OK;
105113
auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
106114
if (imageProcessor == nullptr)
107115
{
108116
return;
109117
}
110118

119+
// Pad the remainder of the write buffer with zeros and write it to bootloader storage
120+
if (writeBufOffset != 0)
121+
{
122+
// Account for last bytes of the image not yet written to storage
123+
imageProcessor->mParams.downloadedBytes += writeBufOffset;
124+
125+
while (writeBufOffset != kAlignmentBytes)
126+
{
127+
writeBuffer[writeBufOffset] = 0;
128+
writeBufOffset++;
129+
}
130+
131+
CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);)
132+
if (err)
133+
{
134+
ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize bootloader_eraseWriteStorage() error %ld", err);
135+
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
136+
return;
137+
}
138+
}
139+
111140
imageProcessor->ReleaseBlock();
112141

113142
ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully");
@@ -119,22 +148,23 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context)
119148

120149
ChipLogProgress(SoftwareUpdate, "OTAImageProcessorImpl::HandleApply()");
121150

122-
err = bootloader_verifyImage(mSlotId, NULL);
151+
CORE_CRITICAL_SECTION(err = bootloader_verifyImage(mSlotId, NULL);)
152+
123153
if (err != SL_BOOTLOADER_OK)
124154
{
125155
ChipLogError(SoftwareUpdate, "ERROR: bootloader_verifyImage() error %ld", err);
126156
return;
127157
}
128158

129-
err = bootloader_setImageToBootload(mSlotId);
159+
CORE_CRITICAL_SECTION(err = bootloader_setImageToBootload(mSlotId);)
130160
if (err != SL_BOOTLOADER_OK)
131161
{
132162
ChipLogError(SoftwareUpdate, "ERROR: bootloader_setImageToBootload() error %ld", err);
133163
return;
134164
}
135165

136166
// This reboots the device
137-
bootloader_rebootAndInstall();
167+
CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();)
138168
}
139169

140170
void OTAImageProcessorImpl::HandleAbort(intptr_t context)
@@ -174,18 +204,30 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
174204
return;
175205
}
176206

177-
err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, (uint8_t *) (block.data()), block.size());
178-
179-
if (err)
207+
// Copy data into the word-aligned writeBuffer, once it fills write its contents to the bootloader storage
208+
// Final data block is handled in HandleFinalize().
209+
uint32_t blockReadOffset = 0;
210+
while (blockReadOffset < block.size())
180211
{
181-
ChipLogError(SoftwareUpdate, "ERROR (possible wrong bootloader version): bootloader_eraseWriteStorage() error %ld", err);
182-
183-
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
184-
return;
212+
writeBuffer[writeBufOffset] = *((block.data()) + blockReadOffset);
213+
writeBufOffset++;
214+
blockReadOffset++;
215+
if (writeBufOffset == kAlignmentBytes)
216+
{
217+
writeBufOffset = 0;
218+
219+
CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);)
220+
if (err)
221+
{
222+
ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock bootloader_eraseWriteStorage() error %ld", err);
223+
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
224+
return;
225+
}
226+
mWriteOffset += kAlignmentBytes;
227+
imageProcessor->mParams.downloadedBytes += kAlignmentBytes;
228+
}
185229
}
186230

187-
mWriteOffset += block.size(); // Keep our own track of how far we've written
188-
imageProcessor->mParams.downloadedBytes += block.size();
189231
imageProcessor->mDownloader->FetchNextData();
190232
}
191233

src/platform/EFR32/OTAImageProcessorImpl.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,20 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
6161
*/
6262
CHIP_ERROR ReleaseBlock();
6363

64+
// EFR32 platform creates a single instance of OTAImageProcessorImpl class.
65+
// If that changes then the use of static members and functions must be revisited
6466
static uint32_t mWriteOffset; // End of last written block
6567
static uint8_t mSlotId; // Bootloader storage slot
6668
MutableByteSpan mBlock;
6769
OTADownloader * mDownloader;
6870
OTAImageHeaderParser mHeaderParser;
69-
const char * mImageFile = nullptr;
71+
const char * mImageFile = nullptr;
72+
static constexpr size_t kAlignmentBytes = 64;
73+
// Intermediate, word-aligned buffer for writing to the bootloader storage.
74+
// Bootloader storage API requires the buffer size to be a multiple of 4.
75+
static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4)));
76+
// Offset indicates how far the write buffer has been filled
77+
static uint16_t writeBufOffset;
7078
};
7179

7280
} // namespace chip

0 commit comments

Comments
 (0)