golioth / golioth-firmware-sdk

Firmware SDK enabling any IoT device to connect to Golioth - the Universal Connector for IoT
https://golioth.io
Apache License 2.0
62 stars 11 forks source link

ModusToolbox: Error on boot_set_pending due to flash alignment problem #3

Open ncmiller opened 2 years ago

ncmiller commented 2 years ago

Current Behavior

When running the Golioth example project and testing firmware update, there is an error reported after the image is downloaded:

boot_set_pending failed, error -1

From https://github.com/golioth/golioth-firmware-sdk/blob/main/port/modus_toolbox/fw_update_mcuboot.c#L105.

Digging into MCUboot (v1.8.1-cypress tag), it appears that it's failing to write the image trailer due to a flash alignment problem:

https://github.com/mcu-tools/mcuboot/blob/v1.8.1-cypress/boot/bootutil/src/bootutil_public.c#L348-L355

From what I can tell, this is the same issue as reported here:

https://github.com/mcu-tools/mcuboot/issues/713

The firmware update proceeds normally, despite the error using strategy MCUBOOT_OVERWRITE_ONLY. However, it prevents other desirable strategies such as MCUBOOT_SWAP_USING_SCRATCH from working since the image trailers cannot be written.

Expected Behavior

The error should not happen. MCUboot needs to support the 512-byte alignment restriction of the PSOC6 board so that image trailers can be written.

Steps to Reproduce

Attempt a device firmware update with Golioth, and you will see boot_set_pending failed, error -1 after downloading the image.

Logs, Additional Data

N/A

ddka22 commented 2 years ago

There are three types of swap modes supported in MCUboot - scratch, move, and using a status partition. Only swap mode using status partition can be used with PSoC™ 6 MCU devices because of the hardware restriction of the large minimum flash write/erase size. The MCUboot library is designed with the minimum flash to write/erase size to be 8 bytes or less. This is to ensure that data is not lost when writing to the flash sector status so that it is a single-cycle operation ensuring the robustness of the application.

Because PSoC™ 6 MCU devices have a large minimum flash write/erase size, swap using status partition has been implemented. Using this algorithm, a separate area in the internal flash is used to store swap status values and the image trailer data such as the swap size and info, boot image magic value, and the image ok field.

See https://github.com/Infineon/mtb-example-psoc6-mcuboot-basic for more details.

ncmiller commented 2 years ago

Thanks for the info @ddka22.

I originally tried to use the "swap using status" algorithm (following the Infineon examples), but it didn't work as I expected it to -after a new image was downloaded and flashed, after reboot the bootloader did not detect that a new image was ready. This is a separate issue which I haven't gotten to the bottom of, which prompted me to switch to the MCUBOOT_OVERWRITE_ONLY algorithm, which works (despite the innocuous boot_set_pending failure).

I will leave this issue open for now, until a point when it's either resolved or I switch to the "swap using status" algorithm (assuming I can work through the issues I was seeing).

ddka22 commented 2 years ago

I will try to reproduce the issue from my side. Will keep you posted.