ota_mcuboot_basic_psa
Overview
This ota_mcuboot_basic_psa
example demonstrates a basic application that uses MCUBoot as a second stage bootloader and PSA FWU API layer. The Firmware Update API documentation can be obtained from https://arm-software.github.io/psa-api/fwu
Supported Boards
Prepare the Demo
The demo requires MCUBoot booloader to be present in the FLASH memory to function properly. It is recommended to build and program the bootloader first, then go on with the application. Please refer to respective readme of the
mcuboot_opensource
example and follow the steps there before you continue.Connect a USB cable between the PC and the Debug USB port on the target board.
Open a serial terminal on PC for connected board with these settings:
115200 baud rate
8 data bits
No parity
One stop bit
No flow control
Unix line ending using
\n
(LF)
Transfering data to the flash memory
There are multiple ways how to transfer image updates to the flash memory:
This examples implements a simple XMODEM-CRC protocol, that can be used to transfer data to the board at slow speed (~10kB/s). This provides a convenient method for images that have relatively small size (under lower 100’s of kB). In the application shell the XMODEM receiving is initiated by
update
command. Terminal emulators like Tera Term or ExtraPutty can be used as a transmitting side. Both 128B and 1024B packet sizes are supported.An alternative way, more suitable for larger images, is to use the blhost utility (part of NXP’s SPSDK and MCUXpresso Secure Provisioning Tool). Blhost communicates with chip’s ROM and supports all basic flash operations. When used via onboard’s USB the transfer speed is more appropriate for larger files. See board’s user manual for details on ISP mode.
Another option is to use a debug adapter (e.g. JLink, CMSIS DAP…) and flash data using their tools.
Running the demo
To get the application properly executed by the bootloader, it is necessary to put signed application image to the primary application partition. There are multiple options how to achieve that, however in principle the are two main methods (both presuming the bootlaoder is already in place):
a) programing signed application image to the primary application partition using an external tool (direct method) b) jump-starting the application by debugger, performing an image update with the signed image, resetting the board and letting the bootloader to perform the update (indirect method)
The latter method is used in the following step-by-step description:
Open the demo project and build it. Known issue: MDK linker issues warning about unused
boot_hdr
sections. This does not affect the functionality of the example.Prepare signed image of the application from raw binary as described in the readme of
mcuboot_opensource
SDK example.In case of MCUXpresso raw binary may not be generated automatically. Use binary tools after right clicking Binaries/.axf file in the project tree to generate it manually.
Launch the debugger in your IDE to jump-start the application.
In case of MCUXpresso IDE the execution stalls in an endless loop in the bootloader. Pause the debugging and use debugger console and issue command
jump ResetISR
.
When the demo starts successfully, the terminal will display shell prompt as in the following example:
******************************************************* * Basic MCUBoot application example using PSA FWU API * ******************************************************* Built Feb 22 2024 13:09:14 $
Available commands can be printed with
help
commandCurrent image state is printed with
query
command. The output will reflect settings of the used platform and may not be exactly the same as the following output:$ query Component id:0 state: READY Version 0.0.0.0 Image 0; name APP; state None: Slot 0 APP_PRIMARY; address 0x20000; size 0x30000 (196608): <No Image Found> Slot 1 APP_SECONDARY; address 0x50000; size 0x30000 (196608): <No Image Found>
From the shown
query
command output it can be observed that PSA FWU state isREADY
and there are currently no signed images present neither in the primary nor the secondary slot. Since the example was started by a debugger, it is not signed and hence not recognized as a valid signed image in the primary slot.After a reboot the staging area (if needed) is automatically erased by application so PSA FWU state is
READY
Note: This is required forREADY
state by PSA FWU specification. The approach used in the example is universal solution as there are possible scenarios where whole slot needs to be erased before writing an update. Another approach could be always consider staging area asREADY
after a reboot and proceed flash erase operation on-the-fly for written sectors during the update.XMODEM transfer is initiated using
update
command. When executed, it starts waiting for the transmitting side. In this demonstration Tera Term is used to send the update file. The dialogFile->Transfer->XMODEM
is used to select a file to be send. In the same dialog a packet size can be extended to 1kB for faster transmittion.$ update Component id:0 state updated READY -> WRITING Started xmodem download into flash at 0x240000 Initiated XMODEM-CRC transfer. Receiving... (Press 'x' to cancel) CCC Received 31744 bytes SHA256 of received data: 547251A815E1DFB074F9... SHA256 of flashed data: 547251A815E1DFB074F9... Component id:0 state updated WRITING -> CANDIDATE
After image downloaded finished the current image status can be checked with
query
command. The output now shows that there is an MCUBoot image file detected in the secondary slot. The SHA256 digest is different from the digest computed for the data downloaded via XMODEM. This is because XMODEM protocol pads data at the end to make their size multiple of the packet payload size (128/1024 bytes).$ query Component id:0 state: STAGED Version 0.0.0.0 Image 0; name APP; state None: Slot 0 APP_PRIMARY; address 0x20000; size 0x30000 (196608): <No Image Found> Slot 1 APP_SECONDARY; offset 0x240000; size 0x200000 (2097152): <IMAGE: size 34600; version 1.3.1+1001>
To let the bootloader install the new image it must be marked as
ReadyForTest
. This is done usinginstall
command. After running this command the result can be checked by runnig theimage
command again.$ query Component id:0 state: CANDIDATE Version 0.0.0.0 Image 0; name APP; state ReadyForTest: ...
Running
reboot
command or resetting the board manually starts the bootloader and lets it handle the installation of new image. If everything went well the image from the secondary slot was moved to the primary slot and the bootloader started its execution. Thequery
command output should reflect this change:$ query Component id:0 state: READY Version 1.3.1.1001 Flash REMAP_OVERLAY active. Image 0; name APP; state None: Slot 0 APP_PRIMARY; offset 0x40000; size 0x200000 (2097152): <No Image Found> Slot 1 APP_SECONDARY; offset 0x240000; size 0x200000 (2097152): <IMAGE: size 34600; version 1.3.1+1001> log_addr 0x60240000 remaps to 0x60240000 *ACTIVE*
If the bootloader was configured to use the image swapping mode, another image can be now downloaded to test this. The process is exactly the same as in the previous steps. The only difference will be after the image is installed because this time the image state will be set as
Testing
. In this state the newly running image must confirm itself otherwise the booloader will revert back to previous image on the next reboot. The confirmation is done byaccept
command after which the state will be set asUPDATED
. Transition toREADY
state can be done by commandclean
otherwise the staging area is clean after a reboot.